Пользовательские свойства CSS (часто называемые переменными CSS) довольно новые, но мощные. Они, как следует из названия, ведут себя как свойства CSS, а не просто переменные, подобные тем, которые вы знаете по SASS:

  • Препроцессор не требуется.
  • Они наследуют свойства CSS и ведут себя так же.
  • Вы можете получить к ним доступ и управлять ими в JavaScript.

Последний пункт - это то, где становится интересно. Комбинация CSS и JS позволяет нам делать следующее:

header {
  background: var(--color);
}
footer {
  background: var(--color);
}

В JS мы меняем --color на случайное значение. Когда мы применяем свойство к телу, каждое свойство, которое использует --color, изменяется. В реальном времени!

document.documentElement.style.setProperty('--color', randomColor())

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

Поддержка браузера

Три основных браузера уже поддерживают переменные CSS: Chrome, Safari и Firefox. Edge и старым браузерам не повезло. Это проблема? Нет! Параллакс-анимация - прекрасный пример прогрессивного улучшения. Ваш сайт продолжает работать везде, но пользователи с новейшими браузерами получают некоторые специальные эффекты 😎.

Начиная

basicScroll не имеет зависимостей, поддерживает CommonJS и AMD, а также поддерживает мобильные и настольные компьютеры. Он в основном включает в себя все необходимое для создания потрясающих анимаций параллакса. Для начала скачайте basicScroll с GitHub или установите библиотеку с помощью Bower или npm:

npm install basicscroll

HTML и CSS

Чтобы использовать библиотеку, нам сначала понадобятся HTML и CSS. Давайте создадим что-то похожее на сайт Firewatch. Многослойный герой. Композиция иллюстраций, создающая сцену с параллаксом.

Вот HTML ...

<img class="scene" data-modifier="30" src="p0.png">
<img class="scene" data-modifier="18" src="p1.png">
<img class="scene" data-modifier="12" src="p2.png">
<img class="scene" data-modifier="8" src="p3.png">
<img class="scene" data-modifier="6" src="p4.png">
<img class="scene" data-modifier="0" src="p6.png">

… И CSS…

body {
  /* Let the user scroll */
  height: 2000px;
  /* Frontmost scene and background should have the same color */
  background: black;
}
.scene {
  position: absolute;
  width: 100%;
  transform: translateY(var(--translateY));
  will-change: transform;
}

.scene - вот где становится интересно: мы собираемся использовать --translateY, чтобы изменить положение каждого слоя. Свойство will-change CSS предоставляет способ подсказки браузерам о том, какие изменения следует ожидать в элементе. Таким образом, браузер может заранее настроить соответствующие оптимизации. В нашем примере большой выигрыш в производительности, поскольку мы уже знаем, что transform будет меняться при прокрутке пользователем.

JavaScript

Но без JS ничего не произойдет 🤔 Наша переменная в настоящее время пуста и поэтому ничего не будет делать. Браузеры игнорируют свойство и используют значение по умолчанию для transform. Здесь на помощь приходит basicScroll. От basicScroll мы хотим, чтобы ...

  • … Он начинает изменять настраиваемое свойство CSS для каждого слоя, как только пользователь начинает прокрутку.
  • … Он перестает изменять настраиваемое свойство CSS для каждого слоя, как только нижняя часть слоев достигает верха области просмотра.

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

document.querySelectorAll('.scene').forEach((elem) => {
 
  const modifier = elem.getAttribute('data-modifier')
 
  basicScroll.create({
    elem: elem,
    from: 0,
    to: 519,
    props: {
      '--translateY': {
        from: '0',
        to: `${ 10 * modifier }px`,
        direct: true
      }
    }
  }).start()
  
})

0 сообщает библиотеке начать изменение props с 0px. 519, с другой стороны, указывает, что мы не хотим никаких изменений, когда пользователь прокрутил больше, чем 519px. 519px - это высота наших сцен, но вы можете делать все, что захотите.

Объект props содержит свойства CSS, которые должны измениться. В нашем случае переменная --translateY. Слои должны двигаться быстрее, чем больше они находятся на заднем плане иллюстрации. Самый передний слой должен иметь самое медленное преобразование, а самый задний слой должен иметь самое быстрое преобразование. Именно для этого и нужен modifier.

И последнее, но не менее важное: свойство direct, которое указывает basicScroll применять переменную непосредственно к элементу.

Все, что нам нужно сделать сейчас, - это активировать экземпляр, вызвав его функцию start. Вот и все! 🎉 Наслаждайтесь полной демонстрацией на CodePen.

Рисунок моего коллеги @setgraphic: ознакомьтесь с его работой.