Всем привет! Буквально за 5 минут расскажу, как сделать parallax-эффект, который помог нам наглядно показать стилистические различия между светлой и темной темами на сайте «Дизайн-система НЛМК».

Parallax-эффект позволяет пользователю увидеть изменения темы у компонентов при скролле страницы, причем сами компоненты зафиксированы, а линия смены темы двигается синхронно со скроллом.
Но для начала мне следует представиться. Я - frontend-разработчик “НЛМК - Информационные технологии”, занимаюсь созданием различных решений для упрощения работы промышленных цехов. Один из моих проектов - «Дизайн-система НЛМК», которая является основой для других, более сложных решений в других проектах.
Разработка структуры сайта, который является своеобразной "визитной карточкой" «Дизайн-системы», дала простор для интересных фич по его стилизации.
Какой смысл parallax-эффекта в данном проекте? В “Дизайн-системе” присутствуют различные компоненты с вариациями для темной и светлой тем: от простых всплывающих подсказок до сложных элементов навигации. Как всё это изящно показать пользователям и, возможно, помочь выбрать тему интерфейса? Как раз с помощью parallax-эффекта. Сделать его быстро и просто.

Приступим к реализации. Для этого нам потребуются старые-добрые HTML и CSS, а также препроцессор SCSS. Ну и базовое знание БЭМ также не повредит :)
Создадим блок экрана, содержащий в себе два дочерних элемента, которые будут содержать две картинки с компонентами светлой и темной тем:
<div class="screen">
  <div class="screen__part screen__part--light"></div>
  <div class="screen__part screen__part--dark"></div>
</div>Класс .screen__part объединяет в себе общие стили дочерних элементов, а модификаторы --light и --dark его расширяют.
Начнем написание стилей блоков. Создадим общий класс блока .screen, который содержит в себе элемент .screen__part:
.screen {
  &__part {
    height: 100vh;
  }
}Предполагается, что высота каждого элемента с картинками будет равна высоте экрана (оно же 100vh), чтобы пользователь мог рассмотреть все компоненты. Далее добавим свойства модификаторов .screen__part--light и .screen__part--dark:
&--light {
  background: #EDEEF2 url("../images/screen_white.jpg") no-repeat center/cover fixed;
}
&--dark {
  background: #454C5E url("../images/screen_black.jpg") no-repeat center/cover fixed;
  clip-path: polygon(0 0, 100% 12vh, 100% 100%, 0% 100%);
  position: relative;
  top: -12vh;
}Здесь используются более комплексные стили, поэтому давайте разберемся подробнее. Свойство .background у обоих элементов может заменить десяток аналогичных свойств для стилизации фоновых картинок. Но для наглядности разобьем его на части (возьмем значения из “светлого” блока):
background-color: #EDEEF2;
background-image: url("../images/screen_white.jpg");
background-repeat: no-repeat;
background-position: center;
background-size: cover;
background-attachment: fixed;Первое и второе свойства вполне понятны - они содержат фоновый цвет и путь к фоновой картинке. Третьим свойством мы размещаем изображение один раз и больше его не повторяем. Свойство background-position указывает начальное положение фона, в нашем случае мы располагаем его по центру как по горизонтали, так и по вертикали. Свойством background-size мы указываем размер фонового изображения, причем значением cover мы сохраняем пропорции изображения так, чтобы его высота равнялась высоте элемента. Свойством background-attachment и значением fixed мы фиксируем фоновое изображение и предотвращаем его перемещение (или фиксируем его “на заднем плане”, кому как удобнее)
Теперь рассмотрим свойство clip-path. С его помощью можно создавать блоки в форме разных геометрических фигур. Если в качестве значения использовать функцию polygon, то можно получить блок в форме четырехугольника. В нашем примере мы передаем в функцию четыре пары значений, четыре пары координат углов четырехугольника (левый верхний, правый верхний, правый нижний, левый нижний):
 polygon(0 0, 100% 12vh, 100% 100%, 0% 100%);Но если оставить все как есть, то окажется, что то, что было обрезано при помощи clip-path, оставит под собой пустое пространство или “зазор”. Поэтому при помощи свойств position и top мы поднимаем “темный” блок ровно на столько, сколько по высоте было обрезано, а именно на 12vh (главное помнить, что система координат начинается в левом верхнем углу, и поэтому в свойстве надо поставить знак “минус”, иначе “темный” блок окажется еще ниже).
Ниже представлен демо-результат проделанной работы:
На этом, в принципе, все! Используя несколько несложных свойств css, мы реализовали интересный parallax-эффект, который смог в полной мере раскрыть темизацию используемых компонентов.
Комментарии (9)
 - LDZ10.02.2022 12:08+1- // не рекомендуется использовать отрицательный margin в реальных проектах- Почему? Есть обоснования?  - Carduelis10.02.2022 13:11- Будет горизонтальный скролл страницы на iOs, если не прикрыть - overflow: hidden;, который может обрезать тени, вызвать дополнительные визуальные баги или отсутствие работы- backdropFilter.- А еще проблемы с - width: 100%;или необходимость- calc() - LDZ10.02.2022 13:34+1- Ну так можно сказать почти про любое свойство. Всегда есть несколько НО, которые нужно учитывать. Но это не значит, что их "не рекомендуется использовать в реальных проектах" 
 
  - NikDoomchan Автор10.02.2022 14:18- Конкретно в данном случае отрицательный margin повлечет смещение всех элементов, идущих после элемента с отрицательным margin. 
 Ниже предложена альтернатива - position: relative и отрицательный top.
 
 
           
 
ionicman
Побуду занудой - но вроде как эффект параллакса - это уменьшение скорости движения объектов в зависимости от их удаления от наблюдателя. И для меня параллакс вот, например.
А здесь просто перекрытие в зависимости от положения скролла (во всяком случае, именно так себя ведёт себя демка на мобильном FF) , нет?
NikDoomchan Автор
Фактически параллаксом можно назвать не отдельный эффект, а целую группу эффектов. То есть любую анимацию, завязанную на скролл, можно назвать параллакс-эффектом
fugasio
Побуду ещё большим занудой, но Паралла́кс (греч. παράλλαξις, от παραλλαγή, «смена, чередование») — изменение видимого положения объекта относительно удалённого фона в зависимости от положения наблюдателя.
fugasio
А ещё я не совсем понял технической ценности демо, ок, сейчас это две картинки, а когда это будут настоящие интерфейсы будет ли это работать так же эффективно? Получается, что ради эффекта нужно постоянно держать два идентичных интерфейса в доме и т. д.
NikDoomchan Автор
Для интерфейсов вряд ли потребуется подобный эффект во время прокрутки, а для демо достаточно взять картинки.
Тем более изначально речь шла про сайт-лендинг, который демонстрирует возможные фичи проекта "Дизайн системы", сами стилизованные компоненты в проект лендинга не входят.