Що таке паралакс ефект CSSЩо таке паралакс ефект CSS

0 Comment

Как сделать параллакс-эффект на CSS или JavaScript

Если вы хотите, чтобы сайт вызывал «вау-эффект», а ссылками на него делились, используйте параллакс. С ним сайты выглядят объёмно, а элементы могут плавно перемещаться при прокрутке страницы или движении курсора.

В этой статье мы покажем, как сделать параллакс на чистом CSS и JavaScript, поговорим про некоторые JS-библиотеки и посмотрим, как оптимизировать анимацию.

Пример параллакса на CSS. Outer Studio, источник

На чём делать параллакс-эффект: CSS или JavaScript

Параллакс при прокрутке страниц создают с помощью 3D трансформаций: transform-style: preserve-3d, perspective, transform: translateZ и других.

Делать такие эффекты на JavaScript слишком ресурсозатратно, потому что браузеру приходится отслеживать движение по событию scroll , вызывать функцию перерасчёта положения блоков и смещать их. В результате страницы тормозят, а скролл становится прерывистым.

А вот параллакс по движению мыши создаётся на JavaScript. В CSS пока нет подходящих для этого свойств, но с его помощью можно оптимизировать параллакс-эффект.

Как сделать параллакс на чистом CSS

Как задать элементу глубину

Чтобы задать элементу глубину, нужно применить к нему transform: translateZ; и указать значение свойства perspective .

Разработчики позиционируют элементы на странице по двум осям: Х и Y, по вертикали и горизонтали. Но есть и третья ось — Z, которая отражает глубину элемента и его расстояние до пользователя. Если просто сдвинуть элемент по этой оси, задав ему свойство transform: translateZ , то мы не увидим разницы. Элемент пока находится в двухмерной плоскости, ведь экран смартфона или монитор ноутбука не обладают глубиной.

Сделать плоскость трёхмерной можно с помощью CSS-свойства perspective . В качестве значения оно принимает расстояние от элемента до пользователя по оси Z — чем больше это значение, тем дальше элемент от вас находится, и наоборот. Часто для perspective указывают значение в 1px — этого достаточно, чтобы установить глубину перспективы.

Пример параллакс-эффекта на чистом CSS

Сделаем параллакс при прокрутке страницы. Сначала подготовим разметку блока с параллаксом. Добавляем — родитель с классом parallax . Внутри него создаём два элемента-слоя с классами parallax-layer . Первый элемент — с изображением, второй — с текстом. Указываем для дополнительный класс parallax-image , а для — parallax-text .

Задаём -родителю свойство perspective: 1px . Оно создаёт виртуальную 3D-плоскость, указывая, что центр блока parallax — исходная точка построения перспективы. Добавляем overflow-y: auto , чтобы прокручивать элементы-потомки относительно фиксированной точки.

Теперь удаляем внутренние элементы с классом parallax-layer из общего потока и растягиваем на всю площадь родителя.

Остаётся задать смещение по оси Z. Текст будет дальше от пользователя, а фон ближе — за счёт этого мы создадим параллакс-эффект.

.parallax-image < transform: translateZ(0); >.parallax-text

Добавим стили и получим результат:

See the Pen parallax by Mikhail (@smfms) on CodePen.

Если открыть вкладку с CSS, можно заметить, что для блока parallax-text задан scale(3) — то есть элемент увеличен в три раза. Зачем мы это сделали?

Дело в том, что элемент, отдаляясь от нас в 3D-плоскости, визуально уменьшается в размерах. И наоборот, приближаясь — увеличивается. Чтобы компенсировать эти изменения, мы используем scale . А его значение вычисляем по формуле:

1 + (translateZ * −1) / perspective

В нашем случае вычисление будет таким:

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

Пример параллакса с множеством элементов. Автор — Скотт Келлум, CodePen

⭐ Научитесь делать анимации разного уровня сложности — записывайтесь на наш курс. Вы узнаете, как анимировать слайдер, бургер-меню и аккордеон, как создавать карточки товаров с 3D-эффектом, многослойный параллакс и параллакс шапки.

Как сделать параллакс на JavaScript

Теперь создадим параллакс-эффект на JavaScript: сделаем карточку с несколькими элементами, которые будут смещаться при движении курсора — каждый со своей скоростью. Так как элементы смещаются по осям X и Y, это будет 2D-параллакс.

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

 

Здорово быть енотом!

.parallax__inner < position: relative; overflow: hidden; >.parallax__layer

Уже сейчас можно задать характер анимации при смещении элементов, указав свойство transition для элементов параллакса. Для более точной настройки можно использовать кривые Безье. Но не рекомендуем использовать значение ease-in-out : могут появиться «рывки» при быстром движении курсора, ведь функция не обладает достаточной линейностью.

Пример «рывков» при быстром перемещении курсора

Перейдём к JavaScript. Найдём параллакс-родитель и все параллакс-элементы, а затем добавим обработчик на родитель. Будем слушать движение курсора мыши — mousemove .

const wrapper = document.querySelector('.parallax__inner'); const layers = document.querySelectorAll('.parallax__layer'); wrapper.addEventListener('mousemove', initParallax); 

Опишем функцию initParallax , в которой будем вести расчёты. Далее декомпозируем задачу: сначала найдём координаты курсора относительно карточки, а затем вычислим новые координаты для элементов при срабатывании события мыши.

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

Сначала вычислим координаты. В JS нет метода, который возвращал бы координаты курсора относительно нужного блока. Свойство clientX возвращает положение по оси X относительно начала вьюпорта. Чтобы начало блока parallax совпадало с 0 по оси X, надо из положения относительно экрана вычесть левый отступ блока parallax . В этом нам поможет метод getBoundingClientRect() .

Перейдём к вычислениям. Для удобства записываем текущую координату в переменную и следом добавляем переменную parallaxLeftOffset с внешним отступом блока wrapper от границ экрана. Будем вычитать отступ из текущей позиции курсора и записывать это в переменную coordX :

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

const coordX = clientX - parallaxLeftOffset - (0.5 * wrapper.offsetWidth); const coordX = clientY - parallaxTopOffset - (0.5 * wrapper.offsetHeight); 

Чтобы получить ширину, используем свойство offsetWidth . Теперь центр враппера — точка с координатами 0.0. Можно двигаться к самому интересному.

Мы вычислили положение курсора относительно параллакс-блока. Теперь мы можем рассчитать смещение его элементов и задать им его:

Округляем координату с помощью метода toFixed и задаём каждому элементу трансформацию по обеим осям. Вот что получилось:

See the Pen Untitled by Mikhail (@smfms) on CodePen.

Теперь элементы следуют за курсором. Добавляем коэффициент скорости, который будет замедлять трансформацию элементов. Пусть он будет равен 0.5 — слишком большое значение лучше не устанавливать, так как трансформация должна быть плавной.

Будем умножать вычисленную координату на этот коэффициент.

Код работает, но мы забыли о сути параллакса. Параллакс — это смещение элементов с разной скоростью, а сейчас все элементы двигаются с одинаковой.

Изменим это. Коэффициент скорости будем хранить прямо в разметке в data-атрибуте, так как это удобно.

 

Здорово быть енотом!

Значение не должно быть слишком большим, чтобы элементы двигались плавно. Допишем скрипт с поправкой на скорость:

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

See the Pen Untitled by Mikhail (@smfms) on CodePen.

Как оптимизировать параллакс

В начале статьи мы упомянули, что параллакс ресурсозатратен для браузера — на каждое движение мыши вызывается несколько команд по перерасчёту координат. Что можно с этим сделать?

Не смещайте элементы с помощью свойств top, left, right, bottom . Вместо них лучше использовать transform: translateX, translateY — они снижают нагрузку на графический процессор.

В CSS есть свойство will-change. Если задать ему значение transform , то браузер ещё до анимирования выполнит оптимизации. Это снизит нагрузку на графический процессор, и анимация будет работать плавнее, без рывков.

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

Заключение

Мы показали простые способы создания параллакса на CSS и JS, но иногда нужны более сложные эффекты. Для таких случаев есть специальные библиотеки, например, Loco Scroll, parallax JS или rellax. С их помощью можно управлять направлением движения элементов, фиксировать слайды при прокрутке, создавать эффект «спешки» или «задержки» анимации.

Узнать больше

«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

CSS ‘>’ selector; what is it? [duplicate]

I’ve seen the “greater than” ( > ) used in CSS code a few times, but I can’t work out what it does. What does it do?

7 Answers 7

> selects immediate children

For example, if you have nested divs like such:

and you declare a css rule in your stylesheet like such:

your rules will apply only to those divs that have a class of “middle” since those divs are direct descendants (immediate children) of elements with class “outer” (unless, of course, you declare other, more specific rules overriding these rules). See fiddle.

 
div.outer - This is the parent.
div.middle - This is an immediate child of "outer". This will receive the orange border.
div.inner - This is an immediate child of "middle". This will not receive the orange border.
div.middle - This is an immediate child of "outer". This will receive the orange border.
div.inner - This is an immediate child of "middle". This will not receive the orange border.

Without Words

.
.

Side note

If you, instead, had a space between selectors instead of > , your rules would apply to both of the nested divs. The space is much more commonly used and defines a “descendant selector”, which means it looks for any matching element down the tree rather than just immediate children as the > does.

NOTE: The > selector is not supported by IE6. It does work in all other current browsers though, including IE7 and IE8.

If you’re looking into less-well-used CSS selectors, you may also want to look at + , ~ , and [attr] selectors, all of which can be very useful.

This page has a full list of all available selectors, along with details of their support in various browsers (its mainly IE that has problems), and good examples of their usage.