CSS расширения для WebKit

Подготовили: Анна Лысак и Татьяна Головко Дата публикации: 09.09.2011

На момент написания этой статьи Safari на iOS была самым сложным браузером. Как уже отмечалось в Главе 7, начиная с версии 2.0, IOS поддерживает большую (и странную) группу CSS-расширений, которые позволяют нам использовать аппаратно-ускоренную анимацию, переходы и даже 3D-эффекты. Некоторые из этих расширений, в зависимости от версии операционной системы, также работают и с Android и webOS браузерами.

WebKit функции

Многие CSS-свойства как параметр воспринимают функции. Эти функции — аппаратно-ускоренные WebKit-расширения.

Перечисленные здесь связанные с градиентом функции в iOS официально не поддерживаются (согласно Safari Reference Library). Тем не менее, они работают с OS 3.0 и более старыми устройствами, где они используют простой фон.

В таблице 9.7 перечислены функции, доступные для iPhone (есть и другие, но они работают только в настольном Safari). Некоторые из этих функций — например, scale и rotate — можно использовать также и в браузерах Android и webOS.

Табл. 9.7. Таблица CSS функций доступных в Safari на iOS
Функция Описание
cubic-beizer(p1x, p1y, p2x, p2y) Определяет кривую Безье для timing function.
matrix(m11, m12, m21, m22, tX, tY) Определяет трансформационную матрицу из шести значений с двумя смещениями.
matrix3d(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m31, m33) Определяют трансформационную 3D матрицу 4×4.
perspective(depth) Карты просмотра куба на пирамиде, основание которой находится далеко от зрителя.
rotate(angle) Определяет 2D вращение вокруг начала координат элемента.
rotate3d(x, y, z, angle) Определяет 3D вращение с [x,y,z] в качестве вектора направления вращения.
rotateX(angle) Указывает вращение по часовой стрелке вокруг оси Х.
rotateY(angle) Указывает вращение по часовой стрелке вокруг оси Y.
rotateZ(angle) Указывает вращение по часовой стрелке вокруг оси Z.
scale(scaleX, [scaleY]) Выполняет операцию 2D масштабирования.
scale3d(scaleX, scaleY, scaleZ) Выполняет операцию 3D масштабирования.
scaleX(value) Масштабирование вдоль оси Х.
scaleY(value) Масштабирование вдоль оси Y.
scaleZ(value) Масштабирование вдоль оси Z.
skewX(angle) Выполнение скошенного преобразования вдоль оси Х.
skewY(angle) Выполнение скошенного преобразования вдоль оси Y.
translate(deltaX, [deltaY]) Указывает вектор 2D смещения.
translate3d(deltaX, deltaY, deltaZ) Указывает вектор 3D смещения.
translateX(value) Выполняет смещение вокруг оси Х.
translateY(value) Выполняет смещение вокруг оси Y.
translateZ(value) Выполняет смещение вокруг оси Z.
from(color) Определяет начальный цвет в последовательности.
to(color) Определяет конечный цвет в последовательности.
color-stop(stop_percentage, color) Указывает промежуточный цвет, который будет использоваться в последовательности в значении stop_percentage.
-webkit-gradient(linear, start_function, end_function, [stop_function, ...]) Определяет линейный градиент, используя стартовую точку, конечную точку и дополнительные промежуточные точки. Может быть использовано вместо любого изображения в CSS. Доступно начиная с iOS 3.0.
-webkit-gradient(radial, inner_center, inner_radius, outer_center, outer_radius, [stop_function, ...]) Определяет радиальный градиент с центральной (внутренней) точкой и другой точкой (внешней) с цветами, которые определяются серией функции color-stop. Доступно начиная с iOS 3.0.

CSS функции — это не новая особенность CSS, они доступны в любом браузере. На самомом деле, ты, наверное, уже знаком с некоторыми стандартными функциями — те же url(url_string) или rgba(red, green, blue, alpha) — для определения цвета.

Градиенты

Начиная с iOS 3.0 Safari поддерживает расширения CSS-градиента в качестве функции для тех ситуаций, где раньше мы использовали изображение (например, для фона). Для фона вместо функции url можно использовать функцию -webkit-gradient, с целью определить использование линейного или радиального градиента в качестве фона. Этот метод позволяет нам, используя минимум кода, делать действительно хорошие фоны для заголовков, контейнеров и ячеек. Для браузера Android применяем точно такой же код.

Некоторые примеры определения градиента:

	/* Эффект солнца из правого верхнего угла */
	body {
	background: -webkit-gradient(radial, 50% −50, 0, 50% 0, 300, from(#676767),
	to(black)) black;
	}
	body {
	background: -webkit-gradient(radial, 100% −10, 50, 70% 0, 200,
	from(yellow), to(white)) #FFC;
	}
	/* Простой линейный градиент */
	li {
	background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#369), to(#3FF))
	#369;
	}
	/* Простой 3D эффект */
	h1 {
	background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#369), to(#369),
	color-stop(0.5, #58B));
	}

Для значений позиций мы можем использовать проценты, абсолютные значения (без пикселей) или константы top, bottom, right и left. Например, в качестве второго параметра функции CSS мы можем использовать top right, а не 0% 0%. На рисунке 9.1 показано, как такие варианты могут выглядеть в браузере.

Используя только CSS можно создать различные эффекты градиента для iPhone, iPod Touch, iPad, и устройств на базе Android Рис. 9.1. Используя только CSS можно создать различные эффекты градиента для iPhone, iPod Touch, iPad, и устройств на базе Android.

Mobile Internet Explorer начиная с версии 6.0 поддерживает фильтры и переходы, используя CSS расширение со стилем filter. Можно применять alpha, chroma, shadow, glow, mask и другие эффекты.

Эффекты отражения

Эффекты отражения или зеркальные эффекты — одни из наиболее часто используемых эффектов в Web 2.0 проектах. Использоваться эти эффекты могут для любого контента, в том числе и для изображений. Но не забывай, что мы разрабатываем для мобильных устройств с их маленькими экранами и здесь не стоит тратить впустую слишком много пространства.

Отражение оригинального элемента не изменяет макет или размер исходного блока контента элемента. Это часть переполнения контейнера.

Чтобы сделать эффект отражения в Safari на iOS, используй свойство -webkit-box-reflect со следующим синтаксисом:

	-webkit-box-reflect: direction offset <mask-box-image>;

direction может быть above, below, left или right; offset — расстояние (в px или %) от исходного элемента, отражение которого должно появиться; дополнительный <mask-box-image> — это, как правило, функция градиента, которая будет работать как маска для отражения изображения. Если изображение маски не указано, то будет использоваться обычное зеркало.

У того типа эффекта отражения, который обычно используется на Web 2.0 сайтах следующие атрибуты:

	-webkit-box-reflect: below 3px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), to(white));

Маски изображений

Начиная с iOS 3.0 у нас есть доступ к типичной дизайнерской функции, которая отсутствовала в веб-разработке в течении многих лет: маски изображений. Маски изображений мы можем использовать, чтобы к исходному изображению применить любую правильную или неправильную обрезку или, если используется альфа-маска (или функция градиента) можно для любого изображения сделать классный визуальный эффект (например, fuzzy border). Свойства маски похожи на свойства фона. Для применения маски у нас в распоряжении есть сокращенное свойство ярлыка, -webkit-mask и специфические свойства для определения каждого параметра.

Синтаксис shortcut версии с дополнительными параметрами:

	-webkit-mask: attachment, clip, origin, image, repeat, composite, box-image;

Конечно, у нас есть отдельный доступ ко всем свойствам (-webkit-mask-attachment, -webkit-mask-clip и т.д.). Возможностей много, но обычно в качестве значения изображения используются изображение (альфа или нет, PNG или SVG) или функция градиента. Пример:

	<img src="london.png" style="-webkit-mask-image:-webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); " />
	<img src="london.png" style="-webkit-mask-image: url(old_picture_mask.png)" />

Переход

Переход (transition) — это автоматическая анимация, которая проявляется при изменении значения CSS свойства. Свойство должно быть определено браузером как способное к анимации (обычно это относится к свойствам позиции и размера). Официального списка свойств, которые могут работать с анимацией нет, но в целом позиция такая: любое свойство с числовыми значениями или значениями цвета может быть анимирован при помощи transition. При этом есть несколько исключений, как, например, дискретное свойство visibility.

Помни, что эти смещения реализуются только силами CSS: для создания анимации мы не используем JavaScript или любой другой подобный метод. Может тебе покажется странным, но это простой и, одновременно, мощный метод.

Фреймворк для работы с transition доступен для браузеров Safari (начиная с iOS 2.0) и Android и, кроме того, на этих устройствах производительность при работе с transition выше.

Для реализации transition мы должны:

  1. Определить свойства transition (продолжительность, задержка, где применяется, функция синхронизации) для элемента (-тов), который(-е) мы хотим анимировать.
  2. Изменить значения свойств элемента (-ов) для анимации с использованием JavaScript или применить классы или вообще удалить их из элемента.
  3. Убедиться, что анимация работает.

Правда, звучит просто? Теперь давай сделаем.

Свойства анимации

Анимацию можно определить при помощи свойства -webkit-transition со следующим синтаксисом:

	-webkit-transition: property duration timing_function delay [, ...];

Мы также можем использовать специфические свойства, указанные в таблице 9.8.

Табл. 9.8. Таблица свойств transition для WebKit
Свойство Описание
-webkit-transition-property Определяет какое свойство или свойства будут использоваться для анимации. Можно использовать список значений, разделенных запятыми или постоянные значения.
-webkit-transition-duration Определяет продолжительность перехода. Значение может быть 0 (нет анимации) или положительное значение в секундах (s используется в качестве единицы). Если для каждого свойства мы хотим задать разное время — можно использовать список разделенных запятыми значений в том же самом порядке, как и значения для свойства -webkit-transition-property.
-webkit-transition-delay Определяет задержку анимации, которая начинается с момента изменения свойства. Определятся может в секундах или милисекундах; значение по умолчанию — 0. Если используется отрицательная величина — анимация запускается сразу, но какой-то фрагмент анимации будет уже как бы проигран и, соответственно, пропущен.
-webkit-transition-timing-function Определяет функцию, которая используется для вычисления промежуточных значений между начальным и конечным значениями свойства. Ты можешь использовать CSS функцию cubic-bezier или любую из следующих констант: ease, linear, ease-in, ease-out, и ease-in-out (чаще всего используется).

При помощи следующего примера кода реализуется анимация появления и исчезновения

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
"http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Fade Sample</title>
	<style>
		#box {
			width: 200px;
			height: 200px;
			background-color: red;
			-webkit-transition: opacity 2s;
		}
		.hide {
			opacity: 0;
		}
	</style>
	<script type="text/javascript">
		function fade() {
		var box = document.getElementById("box");
		box.className = (box.className=="hide") ? "" : "hide";
		box.innerHTML = box.className;
	}
	</script>
</head>
<body>
	<h1>Fading</h1>
	<input type="button" onclick="fade()" value="Hide-Show" />
	<div id="box"></div>
</body>
</html>

Такие же переходы мы можем использовать для изменения размера, перемещения, изменения цвета и даже для 3D-перемещений.

Завершение перехода

Завершение перехода, точно так же, как и любое другое событие DOM можно реализовать при помощи addEventListener из JavaScript. Когда ты убедишься, что анимация действительно закончилась, можно инициировать начало следующего перехода или же еще какое-нибудь другое действие. Для этого нам нужно отловить событие webkitTransitionEnd. Сделать это мы можем при помощи следующего кода:

	box.addEventListener('webkitTransitionEnd', function(event) {
	alert("Finished transition");
	});

Анимации

Переход — это отличная вещь и самый простой способ реализовать анимацию на устройствах iPhone и Android. Если же тебе нужен точный контроль над анимацией на уровне ключевого кадра, можно воспользоваться CSS фреймворком для анимации. Если честно, я думаю, что это уже слишком для обработки только посредством CSS, непроцедурного и «не-разметочного» языка. Но работает это прекрасно.

В WebKit анимация делается при помощи свойства -webkit-animation и синтаксис будет следующим:

	-webkit-animation: name duration timing_function delay iteration_count direction

Как ты уже, наверное, догадался, для каждого возможного значения, перечисленного в таблице 9.9, есть свои специальные свойства.

Табл. 9.9. Таблица анимаций для WebKit
Свойство Описание
-webkit-animation-name Определяет имя анимации, которое будет использоваться ключевыми кадрами.
-webkit-animation-duration Определяет продолжительность анимации (в секундах или милисекундах).
-webkit-animation-timing-function Определяет функцию, которая используется для вычисления промежуточных величин между начальными и конечными значениями определенного свойства. Ты можешь использовать CSS функцию cubic-bezier() или любую из следующих констант: ease, linear, ease-in, ease-out и ease-in-out (используется чаще всего).
-webkit-animation-delay Определяет задержку анимации, которая начинается с момента изменения свойства. Определятся может в секундах или милисекундах; значение по умолчанию — 0. Если используется отрицательная величина — анимация запускается сразу, но какой-то фрагмент анимации будет уже как бы проигран и, соответственно, пропущен.
-webkit-animation-iteration-count Определяет, сколько раз повторится анимация. Значение по умолчанию здесь 1, также в качестве значения может выступать любое целое число, специальная константа infinite или любое действительное число.
-webkit-animation-direction Определяет, в каком направлении будет проигрываться анимация.

Разобравшись с этим перечнем, ты, должно быть, спрашиваешь себя, где именно определяется анимация? Что выступает в качестве объекта анимации? И ответить на эти вопросы помогут расширения WebKit для ключевых кадров.

Если ты перемещаешь или масштабируешь объект и хочешь, к тому же, анимировать его, лучше вместо стандартных свойств CSS использовать -webkit-transform — свойство с улучшенной производительностью.

Директива ключевого кадра

Чтобы определить, как будет работать анимация и что именно будет происходить, нужно определить специальное CSS эт-правило, которое называется @-webkit-keyframes. Это правило сопровождается именем анимации, которое определяется в -webkit-animation-name.

Внутри директивы ключевого кадра следует указать, сколько нам нужно селекторов или групп анимации в качестве ключевых кадров. Селектор определяется значением в процентах и константами from (эквивалент 0%) и to (эквивалент 100%). В каждом селекторе мы определяем все нужные для определенной точки анимации свойства и значения. При помощи -webkit-transition-timing-function мы можем определить синхронизацию для каждой анимационной группы.

По завершению анимации восстанавливаются исходные значения. После остановки анимации элементы не будут сохранять значения последнего ключевого кадра.

Например, при помощи следующего кода мы перемещаем <div> по квадратной траектории:

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
"http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Fade Sample</title>
	<style>
		#box {
			width: 200px;
			height: 200px;
			background-color: red;
			position: absolute;
			top: 0px;
			left: 0px;
		}
		.squareAnimation {
			-webkit-animation-name: squarePath;
			-webkit-animation-duration: 4s;
			-webkit-animation-timing-function: linear;
			-webkit-animation-iteration-count: infinite;
		}
		@-webkit-keyframes squarePath {
			/* В качестве селектора можно использовать 0% или "from" */
			from {
				top: 0px;
				left: 0px;
			}
			25% {
				top: 0px;
				left: 100px;
			}
			50% {
				top: 100px;
				left: 100px;
			}
			75% {
				top: 100px;
				left: 0px;
			}
			/* В качестве селектора можно использовать 100% или "to" */
			100% {
				top: 0px;
				left: 0px;
			}
		}
	</style>
	<script type="text/javascript">
		function start() {
			// Когда мы применяем свойство -webkit-animation, анимация начинается
			document.getElementById("box").className = "squareAnimation";
		}
	</script>
</head>
<body onload="start()">
	<h1>Движение по квадратной траектории</h1>
	<div id="box"></div>
</body>
</html>

Если мы указываем атрибуты -webkit-animation в начале элемента, то анимация начнется при загрузке страницы. Лучше определить анимацию как класс и применять этот класс к элементу, когда нужно запустить анимацию.

Итак, для старта анимации мы применяем класс, а если мы хотим остановить анимацию раньше, чем проиграется последний кадр, мы должны присвоить свойству -webkit-animation-name пустое значение.

Можно использовать несколько вариантов: одну анимацию, которая изменяет сразу несколько свойств или одновременно применять разные анимации (с разными именами), каждая из которых будет изменять только одно свойство.

События анимации

Как и в случае с переходами смещениями, мы можем отследить события webkitAnimationStart, webkitAnimationIteration, и webkitAnimationEnd. При запуске эти события отправляют в качестве параметра объект WebKitAnimationEvent. Но для получения каждого изменения ключевого кадра события нет.

У объекта события есть специальные свойства animationName и elapsedTime, значения которых задаются в секундах.

Трансформации

Последняя группа WebKit CSS расширений, которую мы рассмотрим — функции преобразования (трансформации). Для генерации визуальных эффектов без использования изображений, canvas или SVG, мы можем применить эти функции к любому элементу. Функции преобразования работают в браузерах Safari, Android и webOS.

Работать с этими функциями очень просто: мы используем CSS свойство -webkit-transform, применяя в качестве значения функции CSS, с которыми мы уже встречались ранее в этом разделе, например rotate, scale или translate3d (последняя только Safari).

При помощи свойства -webkit-transform-origin мы можем изменить исходную точку преобразования. По умолчанию указывается середина элемента (значение 50% 50%).

Перспектива

Настроить 3D перспективу можно при помощи функции трансформации perspective или специального CSS свойства -webkit-perspective — это свойство принимает значение в пикселях, которое определяет расстояние от перспективы. Если мы будем использовать последний вариант, то перспектива будет применяться к дочерним элементам родителя, если же мы будем использовать функцию преобразования, то она будет применена непосредственно к элементу.

Стиль трансформации

По отношению к вложенным элементам преобразование может действовать по-разному. При помощи атрибута -webkit-transform-style мы можем контролировать сценарий поведения. У этого атрибута есть два возможных значения: float и preserve-3d. При использовании float вложенные элементы сглаживаются так, если бы они были изображением и перспектива применяется к этому изображению. С применением preserve-3d каждый вложенный элемент получает свою собственную 3D перспективу (рисунок 9.2).

Пример преобразования предоставляемые Apple в Safari Visual Effects Guide на http://developer.apple.com/safari. Рис. 9.2. Пример преобразования предоставляемые Apple в Safari Visual Effects Guide на http://developer.apple.com/safari

Видимость backface

Backface? Что? Какой еще бэкфейс у HTML-элемента? Бэкфейс есть и применяется он в Safari для 3D преобразований с использованием CSS свойства -webkit-backface-visibility. Бэкфейс — это не то что ты мог бы подумать (два «лица» (faces) в одном элементе), но в целом этот эффект может быть легко реализован.

В устройствах Android и webOS 3D преобразования не работают, так что пользоваться ими нужно при разработке только для устройств iPhone, iPod Touch или iPad.

Видимость бэкфейс может определятся свойствами hidden или visible. Если используется hidden, то когда мы указываем поворот вокруг оси Y более чем на 180 градусов — элемент исчезнет и мы сможем сделать видимым другой элемент.

Все преобразования могут быть реализованы при помощи JavaScript, изменением CSS сти