Всем привет! Буквально за 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)
LDZ
10.02.2022 12:08+1// не рекомендуется использовать отрицательный margin в реальных проектах
Почему? Есть обоснования?
Carduelis
10.02.2022 13:11Будет горизонтальный скролл страницы на iOs, если не прикрыть
overflow: hidden;
, который может обрезать тени, вызвать дополнительные визуальные баги или отсутствие работыbackdropFilter
.А еще проблемы с
width: 100%;
или необходимостьcalc()
LDZ
10.02.2022 13:34+1Ну так можно сказать почти про любое свойство. Всегда есть несколько НО, которые нужно учитывать. Но это не значит, что их "не рекомендуется использовать в реальных проектах"
NikDoomchan Автор
10.02.2022 14:18Конкретно в данном случае отрицательный margin повлечет смещение всех элементов, идущих после элемента с отрицательным margin.
Ниже предложена альтернатива - position: relative и отрицательный top.
ionicman
Побуду занудой - но вроде как эффект параллакса - это уменьшение скорости движения объектов в зависимости от их удаления от наблюдателя. И для меня параллакс вот, например.
А здесь просто перекрытие в зависимости от положения скролла (во всяком случае, именно так себя ведёт себя демка на мобильном FF) , нет?
NikDoomchan Автор
Фактически параллаксом можно назвать не отдельный эффект, а целую группу эффектов. То есть любую анимацию, завязанную на скролл, можно назвать параллакс-эффектом
fugasio
Побуду ещё большим занудой, но Паралла́кс (греч. παράλλαξις, от παραλλαγή, «смена, чередование») — изменение видимого положения объекта относительно удалённого фона в зависимости от положения наблюдателя.
fugasio
А ещё я не совсем понял технической ценности демо, ок, сейчас это две картинки, а когда это будут настоящие интерфейсы будет ли это работать так же эффективно? Получается, что ради эффекта нужно постоянно держать два идентичных интерфейса в доме и т. д.
NikDoomchan Автор
Для интерфейсов вряд ли потребуется подобный эффект во время прокрутки, а для демо достаточно взять картинки.
Тем более изначально речь шла про сайт-лендинг, который демонстрирует возможные фичи проекта "Дизайн системы", сами стилизованные компоненты в проект лендинга не входят.