Статьи

Как создать анимацию на всю страницу с помощью CSS

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

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

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

В примерах кода в этом посте используется разметка CSS без префикса, поддерживаемая IE10 Release Preview; другим браузерам могут потребоваться префиксы поставщиков для используемых свойств CSS Animations и CSS Transforms.

Преобразование всего содержимого страницы

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

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

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

 body { transform: rotateZ(45deg); } 

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

Figure 1
Применение rotateZ(45deg) к элементу body документа.

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

 html { perspective: 500px; } 

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

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

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

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

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

Figure 3

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

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

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

Figure 4

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

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

Figure 5

Обратите внимание, что контент фактически не поворачивается внизу окна, а в какой-то момент за пределами области просмотра. Это ожидаемое поведение для CSS-преобразований: <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> нашего документа напрямую (слева) и с использованием шаблона оболочки (справа):

Figure 6

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

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

От трансформации к анимации

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

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

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

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

Figure 7

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

  @keyframes whirlOut {
 к {
     преобразование: шкала (0) rotateZ (1260 градусов);
    }
 } 

С визуальным результатом:

Figure 8

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

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

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

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

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

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

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

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

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

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

Чтобы просто наслаждаться постраничной анимацией, переходите по страницам руководства, используя ссылки «Продолжить…» в правом нижнем углу каждой страницы.

В конце урока мы даем некоторые дополнительные рекомендации и примеры кода о том, как включить эти анимации в ваш собственный веб-контент.

Завершение

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

Если вам понравилось читать этот пост, вы полюбите Learnable ; место, чтобы узнать новые навыки и приемы у мастеров. Участники получают мгновенный доступ ко всем электронным книгам SitePoint и интерактивным онлайн-курсам, таким как Практический CSS .