От автора: вам когда-нибудь хотелось оживить цвет элемента (например, шрифта) при проведении над ним мышью? Можно подумать, что это легко делается с помощью jQuery, но он совсем не поддерживает анимацию цвета, если только не применяется плагин или jQuery UI (пользовательский интерфейс jQuery). Вам нужен быстрый и легкий способ добавлять элементу простую анимацию цвета, и тут в дело вступают переходы CSS. Они являются частью проекта спецификации CSS3 и обеспечивают средство анимации изменений свойств CSS, а не немедленный эффект этих изменений. Благодаря чему мы сможем делать на своих сайтах, плавный переход цвета в CSS.
Это легкий способ, но у него есть один недостаток – плавный переход в CSS поддерживается только современными браузерами. Однако нельзя оставить «за бортом» пользователей старых браузеров, так что вам нужна некая постепенная деградация до тех браузеров, которые не поддерживают переходы CSS3. В этом посте мы увидим, как можно анимировать цвета с помощью переходов CSS3 и метода jQuery .animate() в качестве альтернативы там, где переходы не поддерживаются браузером.
Используем jQuery при плавном переходе в CSS
Вы можете поинтересоваться, почему бы просто не придерживаться jQuery при анимации? Годами веб-дизайнеры полагались на JavaScript при внутристраничной анимации, но он далек от совершенства. Причина того, что мы собираемся использовать переходы CSS3, заключается в том, что, в отличие от обычных переходов JavaScript, переходы CSS3 ускоряются техническими средствами и оттого проходят более гладко. Особенно это может оказаться спасением для мобильных устройств с ограниченной производительностью компьютера.
Согласно W3C, плавные переходы CSS позволяют изменениям свойств в значениях CSS происходить гладко в течение определенного времени. Это сглаживание анимирует изменение значения CSS, когда то запускается щелчком мыши, фокусированием или активным состоянием, или любыми изменениями элемента (включая даже изменение атрибута класса элемента).
Например, вы можете определить переход свойств расположения и фонового цвета, а затем установить оба значения свойства элемента одновременно. Старый цвет и местоположение элемента переходят в новый цвет и местоположение в течение некоторого времени, как показано на этом изображении:
Передача изображения: Apple
Итак, давайте создадим элемент с определенным CSS, а затем для изменения цвета шрифта применим псевдокласс :hover. Для сглаживания этого изменения мы используем переход – эффект, ранее возможный только при использовании JavaScript или Flash, а теперь – при употреблении нескольких простых строк CSS.
Разметка – простая гиперссылка, как здесь:
1 |
<a href="" class="test" >Transition me!</a> |
Далее мы добавим объявление обычного состояния ссылки, за которым следует смена цвета шрифта на синий при проведении над ним мышью:
1 2 |
a.test {color:#AAA;} a.test:hover {color:#F00;} |
Теперь давайте добавим к изменению цвета шрифта переход. Так различие смягчается и анимируется в течение определенного периода времени.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
a.test { color: #AAA; -moz-transition-property: color; /* FF4+ */ -moz-transition-duration: 1s; -webkit-transition-property: color; /* Saf3.2+, Chrome */ -webkit-transition-duration: 1s; -o-transition-property: color; /* Opera 10.5+ */ -o-transition-duration: 1s; -ms-transition-property: color; /* IE10? */ -ms-transition-duration: 1s; transition-property: color; /* Standard */ transition-duration: 1s; } a.test:hover { color: #F00; } |
Теперь давайте скомбинируем все эти значения в стенографическое объявление для его упрощения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* сокращенная запись свойств перехода */ transition: [transition-property] [transition-duration] [transition-timing-function] [transition-delay]; a.test { color: #F00; -moz-transition: color 1s; -webkit-transition: color 1s; -o-transition: color 1s; -ms-transition: color 1s; transition: color 1s; } a.test { color: #AAA; } |
Важно использовать подходящие префиксы, следовательно, с расширением поддержки наши переходы будут работать во все большем количестве браузеров. В объявлении вы заметите две части перехода:
transition-property: Устанавливает имя или имена свойств CSS, к которым должны применяться переходы.
transition-duration: Устанавливает продолжительность, во время которой должны происходить переходы. Вы можете назначить отдельную продолжительность, применяемую ко всем свойствам во время перехода, или увеличить значения для того, чтобы каждое свойство могло делать переходы через различные периоды времени.
В примере мы не использовали еще два свойства:
transition-delay: Задержка перед началом перехода, установленная в секундах, напр. 1s
transition-timing-function: Значение функции тайминга позволяет вам со временем менять скорость перехода путем определения одной из шести возможностей: ease, linear, ease-in, ease-out, ease-in-out и cubic-bezier (что дает вам возможность определять свою собственную временную дугу).
Попробуйте каждое из значений функции тайминга, чтобы посмотреть, чем они различаются. Значение по умолчанию – ease, и оно должно просто отлично работать для коротких переходов. Они – сравнительно недавнее свойство. Прекрасно работает в современных браузерах, а пользователи старых все еще не могут видеть их как анимацию. Переходы CSS3 выполняются на следующих браузерах:
Safari 3.2+ (представлен в 2008г.)
Firefox 4+ (2009г.)
Google Chrome 7+ (представлен в 2010г.)
Opera 10.50+ (представлен в 2010г.)
Было предложено запустить FireFox 3.7 с поддержкой переходов CSS, но по какой-то причине FireFox отменил запуск и объявил, что 3.7 выйдет в производство как версия 4.
Хотя не все браузеры поддерживают переходы CSS, тот факт, что они заявлены отдельно от изменяющих свойств, означает, что эти изменения все еще будут видны в браузерах без поддержки переходов. Браузеры, у которых отсутствует поддержка переходов CSS, будут отлично применять состояние :hover (или другое), кроме того, что все изменения будут происходить мгновенно, а не со временем.
Чтобы гарантировать в более старых браузерах тот же эффект переходов CSS3, мы применим JavaScript для обеспечения поддержки только тех браузеров, у которых нет собственной поддержки, но вместо решения всех кроссбраузерных проблем гладкой анимации своими силами, можно воспользоваться средствами jQuery .animate() для обеспечения того же эффекта анимации, если он не может быть выполнен в текущем браузере с помощью CSS3.
Вот наша функция jQuery:
1 2 3 4 5 6 7 |
$(document).ready(function(){ $(".test").hover(function () { $(this).stop().animate({ color: "#F00" },700) }, function() { $(this).stop().animate({ color: "#AAA" },700)} ); }); |
Как я уже сказал ранее, jQuery не поддерживает анимированную смену цвета, так что для добавления этой функциональности мы применим jQuery UI, но нам не нужен весь код, что окажется излишними +200kb. Можно взять только необходимый, так что если нам будет нужно анимировать цвет, все, что придется включить – это следующий код. Я взял его из последнего jQuery UI (в настоящее время 1.8.14).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
// замена анимации на стили цвета $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], function(i, attr) { $.fx.step[attr] = function(fx) { if (!fx.colorInit) { fx.start = getColor(fx.elem, attr); fx.end = getRGB(fx.end); fx.colorInit = true; } fx.elem.style[attr] = 'rgb(' + Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' + Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' + Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')'; }; }); // функции цветовой конверсии из highlightFade // от Blair Mitchelmore // //jquery.offput.ca/highlightFade/ // Разбираем строки, ищем фрагменты цвета [255,255,255] function getRGB(color) { var result; // Проверяем, не имеем ли мы уже дело с массивом цветов if ( color && color.constructor == Array && color.length == 3 ) return color; // Ищем rgb(num,num,num) if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; // Ищем rgb(num%,num%,num%) if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; // Ищем #a0b1c2 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; // Ищем #fff if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; // Ищем rgba(0, 0, 0, 0) == transparent в Safari 3 if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) return colors['transparent']; // иным образом, мы, скорее всего, имеем дело с названным цветом return colors[$.trim(color).toLowerCase()]; } function getColor(elem, attr) { var color; do { color = $.curCSS(elem, attr); // Продолжайте, пока не найдем элемент, содержащий цвет, или не наткнемся на body if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) break; attr = "backgroundColor"; } while ( elem = elem.parentNode ); return getRGB(color); }; |
После сжатия с помощью YUI остается всего 1.43kb:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", "borderTopColor","borderColor","color","outlineColor"],function(b,a){$.fx.step[a]=function(c) {if(!c.colorInit)c.start=getColor(c.elem,a);c.end=getRGB(c.end);c.colorInit=true} c.elem.style[a]="rgb("+Math.max(Math.min(parseInt((c.pos*(c.end[0]-c.start[0]))+c.start[0],10),255),0)+","+Math.max(Math.min(parseInt((c.pos*(c.end[1]-c.start[1]))+c.start[1],10),255),0)+","+Math.max(Math.min(parseInt((c.pos*(c.end[2]-c.start[2]))+c.start[2],10),255),0)+")"}});function getRGB(b){var a;if (b&&b.constructor==Array&&b.length==3) {return b}if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b)){return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)]}if (a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s* ([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b)){return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55]}if(a=/#([a-fA-F0-9]{2}) ([a-fA-F0-9]{2}) ([a-fA-F0-9]{2})/.exec(b)){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}if(a=/#( [a-fA-F0-9]) ([a-fA-F0-9])([a-fA-F0-9])/.exec(b)){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}if(a=/rgba\(0, 0, 0, 0\)/.exec(b)) {return colors.transparent}return colors[$.trim(b).toLowerCase()]}function getColor(c,a){var b;do{b=$.curCSS(c,a);if(b!=""&&b!="transparent"||$.nodeName(c,"body")){break}a="backgroundColor"}while(c=c.parentNode);return getRGB(b)}; |
Далее применяем библиотеку JavaScript с открытым исходным кодом под названием Modernizr, она дает нам возможность протестировать отдельные свойства HTML5 и CSS3 в браузерах наших пользователей. Вместо тестирования только отдельного браузера и попытки принимать решения на этом основании, Modernizr дает возможность задавать отдельные вопросы типа: «Поддерживает ли этот браузер переходы CSS3?» и получать четкие ответы «да» или «нет».
И снова нам не нужна вся библиотека, к счастью, в Modernizr2 имеется новая возможность модификации вашей закачки JavaScript’а в соответствии с запросами пользователя. Так что теперь, если вам не нужна отдельная характеристика (например, Drag and Drop), вы можете выключить и не заставлять Modernizr ее проверять. Прочтите все об этом здесь.
Вот код, нужный нам из библиотеки Modernizr. Здесь всего 1kb (Modernizr 2.0.6 — Custom Build)
1 2 3 4 5 6 7 8 9 10 |
;window.Modernizr=function(a,b,c){function z(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1), d=(a+" "+m.join(c+" ")+c).split(" ");return y(d,b)}function y(a,b){for(var d in a)if(j[a[d]]!==c) return b=="pfx"?a[d]:!0;return!1}function x(a,b){return!!~(""+a).indexOf(b)}function w(a,b) {return typeof a===b}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function u(a) {j.cssText=a}var d="2.0.6",e={},f=b.documentElement,g=b.head||b.getElementsByTagName("head")[0],h="modernizr",i=b.createElement(h),j=i.style,k,l=Object.prototype.toString, m="Webkit Moz O ms Khtml".split(" "),n={},o={},p={},q=[],r,s={}.hasOwnProperty,t;!w (s,c)&&!w(s.call,c)?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype<strong></strong>,c)}, n.csstransitions=function(){return z("transitionProperty") };for(var A in n)t(n,A)&&(r=A.toLowerCase(),e[r]=n[A](),q.push((e[r]?"":"no-")+r));u(""),i=k=null,e._version=d,e._domPrefixes=m,e.testProp=function(a){return y([a]) },e.testAllProps=z;return e}(this,this.document); |
Теперь мы можем прибегнуть к следующему коду и обеспечить мощную анимацию jQuery тем браузерам, которые не поддерживают переходы CSS3:
1 2 3 4 5 6 7 8 9 |
if (!Modernizr.csstransitions) { $(document).ready(function(){ $(".test").hover(function () { $(this).stop().animate({ color: "#F00" },700) }, function() { $(this).stop().animate({ color: "#AAA" },700)} ); }); } |
Заключение по плавным переходам в CSS
Как любыми новенькими инструментами, пользуйтесь плавными переходами в CSS с вниманием и осторожностью. Можно легко впасть в излишество, добавляя цветовые переходы к множеству элементов страницы, в результате чего получится некий раздражающий, пульсирующий монстр. Необходимо применять переходы CSS там, где это имеет смысл, улучшая впечатление пользователя – и пропускать в остальных случаях. К тому же, очень нужно убедиться, что скорость перехода не замедляет мгновенное в прочих отношениях действие со стороны пользователя. Уместное использование переходов насущно важно.
Автор: Faraz Karimian
Источник: //www.onextrapixel.com
Редакция: Команда webformyself.
Комментарии (2)