Преобразования CSS

В новых версий браузеров была реализована поддержка двухмерных преобразований CSS3 и добавлена поддержка трехмерных преобразований CSS3 и анимации CSS3.

В предыдущих записях блога мы рассматривали трехмерные преобразования CSS3, а также анимации и переходы CSS3. В этой записи мы представляем менее привычный вариант использования этих технологий, разрабатывая концепцию «полно-страничные анимации», которые могут использоваться во время навигации для добавления плавности и непрерывности при просмотре веб-страниц. Целью является оптимизация просмотра веб-страниц в том плане, чтобы контент плавно появлялся, когда пользователь посещает страницу, и исчезал, когда пользователь щелкает ссылку или выполняет соответствующее действие.

Преобразования и анимации CSS3

Демо

Эти эффекты могут быть реализованы путем преобразования элемента HTML <body> с использованием анимации CSS3. Однако такой вариант использования требует учета некоторых аспектов, которые полезно обсудить. К ним относятся эффект изменения положения и размера преобразуемого элемента <body>, а также правильное распределение времени переходов между страницами, чтобы они хорошо сочетались с анимацией.

В примерах кода в этой записи блога используется разметка CSS3 без префикса, поскольку она поддерживается в Internet Explorer 10. В других браузерах для используемых свойств анимации и преобразований CSS3 могут потребоваться префиксы.

к меню ↑

Преобразование всего контента страницы

Преобразования CSS3 определяются для стилистических свойств элементов HTML DOM. Например, разметка для поворота элемента на 45 градусов вокруг оси Z может выглядеть следующим образом:

#element {
transform: rotateZ(45deg);
}

Присоединение преобразования к элементу <body> документа HTML работает аналогичным образом. Поэтому, чтобы добавить такой же эффект к <body> вашего документа, нужно сделать следующее:

body {
transform: rotateZ(45deg);
}

Давайте посмотрим на снимок страницы до и после применения преобразования к элементу body:

Снимок экрана, на котором показано применение преобразования rotateZ(45deg) к элементу документа body

Применение преобразования rotateZ(45deg) к элементу документа body

Для трехмерных преобразований в спецификации преобразований CSS3 определяется свойство perspective, которое можно задать для родительского элемента, по отношению к преобразуемому элементу. При преобразовании контента элемент <body> следует применять к элементу <html>, расположенному выше в иерархии DOM. Это выполняется просто:

html {
perspective: 500px;
}

В сочетании с преобразованием элемента <body> свойство rotateY(45deg) даст следующий результат:

Снимок экрана, на котором показано применение преобразования rotateY(45deg) к элементу <body><с perspective: 500px для <html>

Применение преобразования rotate(45deg) к элементу body с свойством perspective: 500px для <html>

Мы можем управлять свойством transform-origin для элемента body что бы получить интересный результат. Рассмотрим пару примеров:

body {
transform-origin: 50% 100%;
transform: rotateX(45deg);
}

Приведенная выше разметка задаёт поворот вокруг оси X для элемента body и сдвиг оси вращения в нижнюю часть этого элемента с использованием transform-origin. В результате такого поворота контента документ будет выглядеть так:

Снимок экрана, на котором показано применение преобразования: rotateX(45deg) и transform-origin: 50% 100% для <body>
Применение преобразования: rotateX(45deg) и transform-origin: 50% 100% для <body>

Мы также можем управлять свойством perspective-origin корневого элемента нашего документа, чтобы добиться эффекта не осевой проекции. Изменение стиля для html:

html {
perspective: 500px;
perspective-origin: 90% 50%;
}

Наша страница теперь выглядит так:

Снимок экрана, на котором показано применение perspective: 500px и perspective-origin: 90% 50% к элементу <html>
Применение perspective: 500px и perspective-origin: 90% 50% к элементу <html>

Используя преобразования CSS3, мы можем легко управлять внешним видом всего контента нашей страницы. Поскольку обычные правила разметки и размер по-прежнему применяется, некоторые преобразования элемента body (особенно те, в которых используются проценты или свойство transform-origin могут приводить к различным визуальным эффектам в зависимости от контента страницы. Вспомним наш предыдущий пример rotateX(45deg), где для свойство transform-origin установлено со значением 50% 100%.

Ниже вы можете увидеть результаты до и после применения преобразования.

Снимок экрана, на котором показана разница между полосами прокрутки до и после применения преобразования с проекцией перспективы

Разница между полосами прокрутки до и после применения преобразования с проекцией перспективы

Обратите внимание на то, что контент поворачивается не вокруг нижней стороны окна, а вокруг некоторой оси, находящейся вне поля зрения. Это ожидаемое поведение для преобразований CSS3: <body> расположен стандартно, затем он поворачивается вокруг нижнего края, находящегося вне экрана. Вы также заметите, что фактическая площадь, занимаемая контентом, увеличилась (посмотрите на полосы прокрутки на картинке «после»), чтобы вместить преобразованный контент (тот факт, что мы используем центральную проекцию, делает этот эффект еще более выраженным).

Как мы работаем с контентом произвольного размера, когда применяем преобразования к элементу body? Настройка всего контента происходит так, чтобы размер элемента body не превышал некоторой определенной величины, это может быть нереальной задачей. Вместо этого мы можем использовать простой шаблон HTML/CSS3, позволяющий зафиксировать размер элемента body в соответствии с размером окна браузера и добавить контент внутри блока <div>. Следующая разметка дает именно такой результат:

html, body {
width: 100%;
height: 100%;
min-width: 100%;
max-width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}

#Wrapper {
position: absolute;
width: 100%;
height: 100%;
overflow: scroll;
}

На приведенной ниже иллюстрации показано, что происходит, когда страница прокручивается вертикально и мы применяем преобразование rotateY(45deg) к элементу <body> нашего документа напрямую (слева) и с использованием шаблона окружения (справа):

Снимок экрана, на котором показано, что происходит при вертикальной прокрутке страницы и применении преобразования rotateY(45deg) к элементу <body> с проекцией перспективы с использованием и без использования шаблона CSS3/HTML

Применение преобразования rotateY(45deg) к элементу <body> с проекцией перспективы с использованием и без использования шаблона CSS3/HTML

Непосредственное применение преобразования приводит к искаженному визуальному результату вследствие не осевой проекции (поскольку мы больше не смотрим на «центр» элемента body). Использование шаблона окружения гарантирует, что для элемента <html> свойство perspective-origin (по умолчанию 50% 50%) всегда будет правильно центрироваться по отношению к элементу <body>, создавая приятный визуальный эффект.

Используя вышеописанный шаблон и задав для преобразований CSS3 значения в процентах, где это возможно, мы можем согласованно влиять на наш элемент <body> независимо от размера его контента.

к меню ↑

От преобразований к анимациям

Разобравшись с хитростями применения преобразований CSS3 к элементу <body>, перейдём к анимации CSS3. Следуя принципам описанных выше, мы можем создавать анимации, перенося веб-контент в поле зрения (или уводящие его из поля зрения) интересным способом.

Рассмотрим это простое правило @keyframes:

@keyframes rotateInLeft {
from {
transform-origin: 0% 0%;
transform: rotateY(180deg);
}
to { 
transform-origin: 0% 0%; 
transform: rotateY(0deg);
}
}

Когда анимация применяется к элементу, он поворачивается вокруг своей левой стороны. Если её применить к элементу <body>, использующему шаблон окружения, получается более интересный визуальный эффект. Документ фактически поворачивается и переходит извне видимой области окна браузера в полно-экранное представление:

Три снимка экрана, последовательно показывающие эффект применения анимации
Три снимка экрана, последовательно показывающие эффект применения анимации

Аналогичным образом мы можем создавать анимации, плавно удаляющий веб-контент из поля зрения. Например, если бы мы хотели, чтобы наша страница исчезала, удаляясь и вращаясь, мы могли бы использовать следующий код:

@keyframes whirlOut {
to {
transform: scale(0)rotateZ(1260deg);
}
}

Результат был бы таким:

Три снимка экрана, последовательно показывающие эффект применения анимации
Три снимка экрана, последовательно показывающие эффект применения анимации

Если использовать все возможности анимации CSS3 для влияния на веб-контент, мы обладаем большой гибкостью при создании таких эффектов для страниц (и безусловно, не ограничиваемся применением только преобразований CSS3). Когда эффекты, которые мы хотим применять к своему контенту, созданы, как запустить их во время навигации по веб-страницам?

к меню ↑

Подключение анимации к <body>

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

Первым интуитивно понятным местом добавления анимации к элементу body могло бы быть событие JavaScript onload. Однако оказалось, что добавлять анимацию, когда запускается onload, слишком поздно. Это событие генерируется, когда завершилась загрузка всей совокупности контента нашей страницы (включая все изображения и другие ресурсы, интенсивно использующие пропускную способность). Присоединение анимации к onload на странице, интенсивно использующей пропускную способность, привело бы к «стандартному» отображению нашего контента, за которым последовал бы запуск анимации и повторный перевод контента в поле зрения. Это не совсем то, чего мы добиваемся.

Оптимальным местом для настройки анимации, перемещающий контент нашей страницы в поле зрения, является верхняя часть элемента <body>. Это гарантирует, что анимация запустится именно при от рисовки контента (и что начальное положение контента будет соответствовать опорному кадру from нашей выбранной анимации). Приятным побочным эффектом этого подхода является то, что анимация может фактически скрыть любую последовательную от рисовку, перекомпоновку или загрузку ресурсов для сложного контента.

Настройка анимации, уводящая контент из поля зрения, также представляет собой интересную задачу. Казалось бы, можно присоединить обработчик события onclick ко всем нужным элементам нашего контента (например, ко всем тегам <a>) и просто задать соответствующие свойства анимации (animation-name, animation-duration и т. д.) в функции обратного вызова. Однако если мы фактически не задержим навигацию, мы не увидим ожидаемого плавного перехода.

Это удобная возможность использовать событие анимации, описанные в спецификации анимации CSS3. В частности, мы можем использовать событие animationend, чтобы обнаружить завершение анимации, а затем запустить навигацию (задав, например, window.location.href). Таким образом, наше событие onclick запустит анимацию remove-from-view и зарегистрирует обработчик события animationend для <body>, который обеспечит выполнение этого события навигации.

к меню ↑

Заключение

Преобразования и анимации CSS3 — два мощных набора компонентов, позволяющих создавать более насыщенные и иммерсионные эффекты при просмотре веб-страниц. В этой записи блога были рассмотрены основные аспекты использования преобразований и анимации CSS3 для добавления динамики ко всей совокупности вашего веб-контента. Прилагая совсем немного усилий, вы можете создавать веб-страницы (даже статичные), обеспечивающие плавную навигацию.