Share via


Полностраничные анимации с использованием CSS

В Internet Explorer 9 была впервые реализована поддержка двухмерных преобразований CSS. В Internet Explorer 10 Developer Preview была добавлена поддержка трехмерных преобразований CSS и анимаций CSS. Используя возможности графического процессора и выполняясь в асинхронном режиме из обычного JavaScript, эти компоненты Internet Explorer 10 обеспечивают более эффективную и гибкую альтернативу традиционным анимациям на основе скриптов, используемым в веб-контенте.

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

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

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

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

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

#element {

transform: rotateZ(45deg);

}

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

body {

transform: rotateZ(45deg);

}

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

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

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

html {

perspective: 500px;

}

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

Снимок экрана, на котором показано применение преобразования 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>

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

html {

perspective: 500px;

perspective-origin: 90% 50%;

}

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

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

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

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

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

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

Как мы работаем с контентом произвольного размера, когда применяем преобразования к элементу body? Настройка всего контента так, чтобы размер элемента body не превышал некоторой определенной величины, может быть нереалистичной задачей. Вместо этого мы можем использовать простой шаблон HTML/CSS, позволяющий зафиксировать размер элемента 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> с проекцией перспективы с использованием и без использования шаблона CSS/HTML

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

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

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

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

Рассмотрим это простое правило @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);

}

}

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

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

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

Присоединение анимаций к <body>

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

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

Вместо этого мы могли бы использовать событие DOMContentLoaded, которое генерируется, когда браузер закончил анализ структуры DOM нашего контента (но потенциально до окончания загрузки ресурсов). DOMContentLoaded Демонстрация на сайте тестирования Internet Explorer иллюстрирует разницу между этими двумя событиями. Однако в случаях сложного веб-контента современный браузер может использовать поэтапную отрисовку, отображая страницу до того, как была загружена вся совокупность дерева DOM. В этих случаях визуальный результат будет аналогичным сценарию onload.

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

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

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

Доступна интерактивная демонстрация

Мы создали демонстрацию и руководство на английском языке по добавлению динамики для страниц с помощью преобразований и анимаций CSS, содержащее подробное описание возможностей и примеры, не вошедшие в данную статью. В этом руководстве используются полностраничные анимации во время навигации по страницам, работающие в Internet Explorer 10 в Windows 8, а также в новейших версиях Chrome и Firefox.

Чтобы по достоинству оценить анимации при переходе от одной страницы к другой, "пролистайте" страницы этого руководства, используя ссылки "Continue to ..." (Перейти к ...) в правом нижнем углу каждой страницы.

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

Заключение

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

— Харилаос "Харрис" Пападопулос (Charilaos "Harris" Papadopoulos), стажер руководителя программы, графика в Internet Explorer