Это перевод статьи Кит Кларк «Pure CSS Parallax Websites».
В этой статье показано, как с помощью CSS-трансформаций, перспективы и небольших хитростей с масштабированием сделать параллакс-эффект на чистом CSS.
Параллакс чаще всего делается на JavaScript, и почти всегда он реализован плохо: отлавливается событие прокрутка, изменения в DOM вносятся напрямую в обработчике и вызываются лишние перерасчёты и перерисовки. Всё это происходит асинхронно с потоковым рендерингом браузера, в результате чего некоторые кадры пропускаются и эффект выглядит прерывистым. Впрочем, это не так уж страшно — requestAnimationFrame
и отложенное обновление DOM позволяют управлять внешним видом сайтов с параллакс-эффектом. Но что если вы могли бы совсем не зависеть от JavaScript?
Перенос параллакс-эффекта на CSS избавит вас от упомянутых проблем и позволит браузеру положиться на аппаратное ускорение — почти всё будет обрабатываться компоновщиком. В результате вы получите согласованную частоту кадров и гладкую прокрутку страницы. Кроме того, можно сочетать этот эффект с другими CSS-приёмами, такими как медиавыражения и поддержка CSS-свойств. Как насчёт отзывчивого параллакс-эффекта?
Теория
Прежде чем говорить о принципе работы, давайте выполним базовую разметку:
А вот основные стили:
Именно класс .parallax
содержит всю магию параллакс-эффекта. Указав для элемента свойства height
и perspective
, мы привяжем построение перспективы от центра этого элемента, создав тем самым исходный фиксированный 3D вьюпорт. Благодаря свойству overflow-y: auto
контент внутри элемента будет прокручиваться как обычно, но элементы-потомки теперь будут отображаться относительно фиксированной точки. Это ключевой принцип создания параллакс-эффекта.
Далее — класс .parallax__layer
. Как можно понять из названия класса, он определяет слой контента, к которому будет применяться параллакс-эффект; элемент выпадает из основного потока и заполняет собой всё пространство контейнера.
И наконец, у нас есть классы-модификаторы .parallax__layer—base
и .parallax__layer—back
. Они определяют скорость прокрутки параллакс-элемента посредством перемещения его по оси Z (отодвигая его от вьюпорта или приближая к нему). Для краткости я установил только две скорости слоя — позже добавим ещё.
Коррекция глубины
Поскольку параллакс-эффект создаётся при помощи 3D-трансформаций, сдвиг элемента по оси Z имеет побочный эффект: по мере того, как он приближается к вьюпорту или отодвигается от него, его реальный размер меняется. Чтобы компенсировать это, мы должны применить трансформацию scale()
к этому элементу — так он будет отображаться в оригинальном размере:
Коэффициент масштабирования (scale) можно вычислить с помощью формулы: 1 + (translateZ * -1) / perspective
. Например, если свойство perspective
нашего вьюпорта равно 1px
, и мы перемещаем элемент по оси Z на -2px
, то коэффициент масштабирования будет равен 3:
Управление скоростью движения слоя
Скорость движения слоя определяется сочетанием значений перспективы и перемещения по оси Z. Элементы с отрицательным значением translateZ
прокручиваются медленнее, чем с положительным. Чем дальше это значение от 0, тем более выраженным получится параллакс-эффект (то есть при translateZ(-10px)
прокрутка происходит медленнее, чем при translateZ(-1px)
).
Разделы страницы с параллакс-эффектом
Предыдущие примеры демонстрировали основные приёмы, используя очень простой контент, но страницы большинства сайтов состоят из отдельных блоков-разделов, к которым можно применять разные эффекты. Вот как это делается.
Для начала нам понадобится элемент .parallax__group
, чтобы сгруппировать наши слои:
Вот CSS-стили для группового элемента:
В этом примере мне нужно, чтобы каждая группа заполняла вьюпорт, поэтому я указал height: 100vh
, однако при необходимости можно указывать разные значения для каждой группы. Значение transform-style: preserve-3d
не даёт браузеру производить слияние слоёв элементов .parallax__layer
, а position: relative
позволяет расположить дочерние элементы parallax__layer относительно группового элемента.
При группировке элементов важно помнить одно правило: нельзя обрезать содержимое группы. Если применить свойство overflow: hidden
к элементу .parallax__group
, параллакс-эффект не будет работать. Если не обрезать контент, элементы-потомки будут выходить за его границы, поэтому придётся проявить изобретательность и использовать разные значения z-index
для групп, чтобы обеспечить правильное скрытие/отображение контента при прокрутке документа.
Не существует чётких правил для решения проблемы с позиционированием слоёв — в разных проектах может быть разная реализация. Гораздо проще устранить неполадки в слоях, если понимать, как работает параллакс-эффект — чтобы увидеть картину яснее можно применить трансформацию к групповым элементам:
Посмотрите на следующий пример — обратите внимание на опцию debug!
Поддержка браузерами
- Firefox, Safari, Opera и Chrome поддерживают этот эффект.
- В Firefox в данный момент присутствует небольшая проблема с выравниванием, хотя в целом всё работает.
- IE пока не поддерживает свойство
preserve-3d
(скоро будет), так что параллакс-эффект в этом браузере не работает. Но это не страшно, так как ваш дизайн всё равно должен работать и без параллакс-эффекта — сами знаете: прогрессивное улучшение и всё такое!
Ещё из рубрики «Вёрстка»
Что такое CMS и как под них верстать
И что это вообще за системы управления контентом?
Как составить план развития: неочевидные советы
Как расти по плану, а без плана не расти.
Как одновременно работать, учиться и не сойти с ума
«…с тайм-менеджментом я не очень дружу: всё делаю медленно, часто опаздываю». Узнали? Согласны?