Все в перспективе: чистый параллакс CSS и другие эффекты прокрутки

Выполните следующие действия с помощью Codepens:

Базовый параллакс
Параллакс с Фиксированным Объектом

Несмотря на заявления о том, что «параллакс мертв», эффект очень жив и здоров - и очарователен - при правильном применении. К сожалению, в девяти случаях из десяти реализация не выполняется в Javascript. Игра со слушателями событий прокрутки - рискованное дело для производительности, и изменение DOM напрямую вызывает ненужные повторные рендеринг, вызывая прерывистую анимацию и липкие прокрутки. Правильный параллакс можно снять с помощью JS. Вот отличная статья о том, как это сделать:

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

Базовая установка

В качестве первого примера мы создадим страницу с заголовком параллакса и статическим содержимым страницы. Поскольку мы отключаем Javascript, у нас нет доступа к позиции прокрутки окна, и нам это не нужно! Ключом к достижению эффекта является использование перспективы. Мы создадим 2 слоя контента. Контент, который мы хотим прокрутить медленнее, будет размещен «дальше» от пользователя по оси Z. Это заставит браузер сделать всю тяжелую работу за нас.

Вот основная разметка:

  
    

Заголовок      
    

Контент сайта   

Давайте уточним CSS. Нам нужно сказать браузеру использовать преимущество перспективы по оси Z. Мы делаем это, добавляя перспективное свойство в наш класс-оболочку:

перспектива: 1px;

Большее значение перспективы приведет к большей разнице в скоростях прокрутки между слоями.

Затем мы заставляем обертку занимать 100% области просмотра браузера и устанавливаем для overflow-y значение auto. Это позволяет прокручивать содержимое в оболочке как обычно, но скорость прокрутки для потомков теперь будет зависеть от значения перспективы оболочки:

.wrapper {
  высота: 100vh;
  переполнение-х: скрыто;
  переполнение-у: авто;
  перспектива: 1px;
}

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

Ничего особенного не происходит в классе .section, применяемом к заголовку. Он определяет высоту и форматирует контент. Вот CSS:

.раздел {
  высота: 100vh;
  дисплей: гибкий;
  align-items: center;
  justify-content: центр;
  размер шрифта: 48 пикселей;
  цвет белый;
}

Вся прелесть параллакса происходит в псевдоэлементе:

.parallax :: after {
  содержание: "";
  положение: абсолютное;
  верх: 0;
  справа: 0;
  низ: 0;
  слева: 0;
  transform: translateZ (-1px) шкала (2);
  размер фона: 100%;
  z-индекс: -1;
  background-image: url (некоторые ссылки на некоторые изображения);
}

Псевдоэлемент размещается за содержимым заголовка. translateZ (-1px) определяет расстояние слоя от пользователя вдоль оси z.

Поскольку мы перемещаем слой дальше назад, содержимое кажется меньше (подумайте о том, что происходит, когда вы отодвигаете объект от себя). Чтобы учесть это, мы должны масштабировать слой обратно до размера, используя scale (2).

Если для вашей перспективы задано значение 1px, формула для масштабирования слоев до размера по умолчанию: 1 + (translateZ * -1) / перспектива.

В нашем случае для translateZ (-2px) потребуется шкала (3) и так далее…

Добавьте немного статического контента под заголовком, и вы получите прекрасный эффект параллакса без JS!

Вот ссылка на Codepen для этого примера.

Теперь для забавной части: параллакс с фиксированными объектами

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

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

Идея состоит в том, чтобы создать отдельные слои объектов в главном контейнере, каждый из которых имеет свое значение translateZ (читай: скорость прокрутки). Реализуя это, я быстро понял, что при переводе и масштабировании объектов у меня не было возможности отслеживать их положение по осям x и y (они меняются относительно значения объекта translateZ). Чтобы решить эту проблему, я обернул каждый объект в прозрачный контейнер, который помещается на весь экран. Затем я мог бы точно разместить объект внутри оболочки и применить translateZ и масштабировать к оболочке вместо самого объекта.

Для определения размера всех объектов необходим только один класс .wrapper:

.object-wrapper {
  положение: абсолютное;
  верх: 0;
  справа: 0;
  низ: 0;
  слева: 0;
  фон: нет;
  justify-content: центр;
}

Различные скорости могут быть определены и применены к объектным оберткам:

.speed-1 {
  transform: translateZ (-1px) шкала (2);
}
.speed-2 {
  transform: translateZ (-2px) шкала (3);
}
.speed-3 {
  transform: translateZ (-3px) шкала (4);
}

Вот кодекс, демонстрирующий параллакс фиксированных объектов:

Чистый CSS предлагает целый мир возможностей для анимации контента относительно позиции прокрутки - и самое приятное то, что в JS практически невозможно испортить производительность!

Когда дело доходит до выдающегося параллакса, это действительно все о перспективе.