Практика использования спецификации CSS Scroll Snap

Автор оригинала: Ahmad Shadeed

Перевод

Часто ли у вас возникало желание воспользоваться какой-нибудь возможностью CSS, позволяющей, без лишних усилий, создать элемент-контейнер, поддерживающий прокрутку? CSS, что очень хорошо, даёт нам такую возможность. Я, когда только начинал заниматься фронтенд-разработкой, пользовался для создания прокручиваемых элементов JavaScript-плагинами. Но иногда нужно что-то такое, что позволяет создавать подобные элементы просто и быстро, без привлечения JavaScript. Сделать это можно, воспользовавшись спецификацией CSS Scroll Snap.

Практика использования спецификации CSS Scroll Snap

Здесь я хочу раскрыть основы практического использования этой спецификации. Я сам только недавно разобрался с CSS Scroll Snap, поэтому рассказывать всё это буду, так сказать, «по горячим следам».

Зачем использовать CSS Scroll Snap?

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

Практика использования спецификации CSS Scroll Snap
Вертикальная организация содержимого не всегда удобна при работе со страницами на устройствах, оснащённых сенсорными экранами. С содержимым, организованным горизонтально, на таких устройствах работать удобнее.

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

Основы работы с контейнерами, поддерживающими прокрутку

Для того чтобы создать элемент-контейнер, поддерживающий прокрутку, понадобится следующее:

  • Использование свойства из группы свойствoverflowсо значением, отличающимся отvisible.
  • Применение некоего способа вывода элементов в контейнере, позволяющего расположить их рядом друг с другом (inline-элементы).

Рассмотрим пример.

Вот HTML-код:

<div class="section">
  <div class="section__item">Item 1</div>
  <div class="section__item">Item 2</div>
  <div class="section__item">Item 3</div>
  <div class="section__item">Item 4</div>
  <div class="section__item">Item 5</div>
</div>

Вот стили:

.section {
  white-space: nowrap;
  overflow-x: auto;
}

Популярным CSS-решением для размещения элементов в контейнере многие годы было свойствоwhite-space: nowrap. В наши дни без этого, к счастью, можно обойтись, воспользовавшись свойствомdisplay: flex:

.section {
  display: flex;
  overflow-x: auto;
}
Практика использования спецификации CSS Scroll Snap
Контейнер, поддерживающий прокрутку элементов

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

Проблема контейнеров, поддерживающих прокрутку содержимого

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

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

Практика использования спецификации CSS Scroll Snap
Работа с обычным контейнером, поддерживающим прокрутку

Как видите, каждый элемент приходится буквально «вести» на его место, не отрывая палец от экрана. Это — не «свайп» и это очень неудобно с точки зрения пользователя. Но, используя возможности CSS Scroll Snap, мы можем решить эту проблему, просто описав точки привязки (snap point), которые упростят горизонтальную или вертикальную прокрутку содержимого страницы.

Знакомство с CSS Scroll Snap

Для того чтобы воспользоваться возможностями CSS Scroll Snap дочерние элементы должны выводиться внутри контейнера в inline-режиме. Сделать это можно с использованием одного из вышеописанных методов. Я использую для этих целей Flexbox-макет.

Вот HTML-код:

<div class="section">
  <div class="section__item">Item 1</div>
  <div class="section__item">Item 2</div>
  <div class="section__item">Item 3</div>
  <div class="section__item">Item 4</div>
  <div class="section__item">Item 5</div>
</div>

Вот CSS-код:

.section {
  display: flex;
  overflow-x: auto;
}

Теперь нам, чтобы спецификация CSS Scroll Snap заработала бы, нужно воспользоваться ещё парой свойств. Главный вопрос тут заключается в том, куда именно их нужно добавить.

Сначала надо добавить свойствоscroll-snap-typeк контейнеру, поддерживающему прокрутку. В нашем примере это — элемент с классомsection. Затем нужно добавить свойствоscroll-snap-alignк дочерним элементам (классsection__item).

.section {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

.section__item {
  scroll-snap-align: start;
}

Вы, вероятно, видя кучу новых ключевых слов, вродеx mandatoryиstart, чувствуете сейчас некоторую растерянность. Но ничего страшного тут нет — скоро вы с ними разберётесь.

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

Воткак это выглядит.

Практика использования спецификации CSS Scroll Snap
Элементы привязаны к началу контейнера

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

Свойство scroll-snap-type

Свойствоscroll-snap-type, в соответствии со спецификацией, позволяет указать на то, что элемент является snap-контейнером. Его значения позволяют задать то, насколько жёстко осуществляется привязка содержимого этого контейнера при прокрутке, а так же то, прокрутка по каким осям принимается во внимание.

Оси контейнера

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

/* Горизонтальная прокрутка */.section {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x;
}

/* Вертикальная прокрутка */.section {
  height: 250px;
  overflow-y: auto;
  scroll-snap-type: y;
}
Практика использования спецификации CSS Scroll Snap
Горизонтальная прокрутка и вертикальная прокрутка

Настройка жёсткости привязки

Мы, настраивая контейнер, можем задать не только направление прокрутки, но и то, насколько жёстко содержимое должно быть связано с точками привязки. Сделать это можно с помощью значенийmandatoryиproximityсвойстваscroll-snap-type.

Ключевое словоmandatoryозначает, что браузер обязательно должен привязать элемент к точке привязки. Представим, что свойствоscroll-snap-alignустановлено в значениеstart. Это означает, что элементы при прокрутке обязательно должны ориентироваться на начало контейнера.

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

Практика использования спецификации CSS Scroll Snap

Элементы жёстко привязаны к началу контейнера

Вот CSS-код:

.section {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

.section__item {
  scroll-snap-align: start;
}

Здесьможно найти видео к этому примеру.

Практика использования спецификации CSS Scroll Snap
Прокрутка с привязкой

Авот— интерактивный вариант этого примера.

Практика использования спецификации CSS Scroll Snap
Работа с интерактивным вариантом примера

Самое приятное тут то, что при прокрутке элементов, делается ли это на компьютере, с использованием мыши, или на сенсорном экране, можно буквально почувствовать то, как элементы «притягиваются» к началу контейнера.

А вот если тут используется значениеproximity, то элементы будут вести себя уже немного свободнее, привязка работает не так жёстко. Обратите внимание на то, что значениеproximityиспользуется в свойствеscroll-snap-typeпо умолчанию. Я показываю тут последствия его явного применения лишь ради того, чтобы сделать изложение понятнее.

Практика использования спецификации CSS Scroll Snap
Элементы привязаны к началу контейнера менее жёстко
.section {
  display: flex;
  overflow-x: auto;
  /* proximity - это значение, используемое по умолчанию, я описываю его лишь для того чтобы сделать изложение понятнее */  scroll-snap-type: x proximity;
}

Видеодемонстрация.

Практика использования спецификации CSS Scroll Snap
Последствия использования значения proximity

Свойство scroll-snap-align

При настройке дочерних элементов контейнера, поддерживающего прокрутку, нужно указать то, к какому месту контейнера привязываются эти элементы. Делается это путём настройки свойстваscroll-snap-align, которое поддерживает значенияstart(начало),center(центр) иend(конец).

Для того чтобы лучше разобраться в этих значениях — взгляните на следующий рисунок. Представим, что в контейнере имеется магнит, который позволяет нам контролировать точки привязки содержимого контейнера. Рассмотрим действие этого «магнита» на содержимое контейнера, ориентированное по горизонтали.

Практика использования спецификации CSS Scroll Snap
Значения свойства scroll-snap-align и их влияние на содержимое, расположенное в контейнере по горизонтали

Если содержимое в контейнере ориентировано вертикально, это значит, что точки привязки, задаваемые значениямиstart,centerиend, тоже расположены по вертикали.

Практика использования спецификации CSS Scroll Snap
Значения свойства scroll-snap-align и их влияние на содержимое, расположенное в контейнере по вертикали

Ниже приведено несколько видеопримеров.

Привязка содержимого к началу контейнера

При установке свойстваscroll-snap-alignв значениеstartсодержимое контейнера привязывается к его началу.

Практика использования спецификации CSS Scroll Snap
Привязка содержимого к началу контейнера`

Привязка содержимого к центру контейнера

При установке свойстваscroll-snap-alignв значениеcenterсодержимое контейнера привязывается к его центру.

Практика использования спецификации CSS Scroll Snap
Привязка содержимого к центру контейнера

Привязка содержимого к концу контейнера

При установке свойстваscroll-snap-alignв значениеendсодержимое контейнера привязывается к его концу.

Практика использования спецификации CSS Scroll Snap
Привязка содержимого к концу контейнера

Использование свойства scroll-snap-stop

Иногда нужно сделать так, чтобы пользователь, прокручивающий список элементов, не пропустил бы случайно какой-нибудь очень важный элемент. Если список прокручивают слишком быстро, то нечто подобное вполне может случиться. Решить вышеописанную задачу можно, прибегнув к свойствуscroll-snap-stop.

Вот стили:

.section__item {
  scroll-snap-align: start;
  scroll-snap-stop: normal;
}

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

Практика использования спецификации CSS Scroll Snap
При слишком быстрой прокрутке некоторые элементы можно пропустить

По умолчанию свойствоscroll-snap-stopустановлено в значениеnormal. Для принудительной привязки элементов это свойство можно установить в значениеalways. Благодаря этому браузер будет останавливать прокрутку каждый раз, когда очередной элемент достигает точки привязки.

Вот соответствующие стили:

.section__item {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

Вотвидеодемонстрация.

Практика использования спецификации CSS Scroll Snap
Браузер не позволяет пропускать элементы
Практика использования спецификации CSS Scroll Snap
Точки привязки — это, при использовании значения always, то же самое, что и знаки «STOP»

Здесьможно найти интерактивный пример, позволяющий поэкспериментировать со свойствомscroll-snap-stop.

Практика использования спецификации CSS Scroll Snap
Эксперименты со свойством scroll-snap-stop

Внутренние отступы и свойство scroll-padding

Сокращённое свойствоscroll-paddingпозволяет устанавливать внутренние отступы, воздействующие на прокрутку содержимого в контейнере. Оно похоже на обычное свойствоpadding. На следующем рисунке показаны последствия создания внутреннего левого отступа шириной в50px. Благодаря этому дочерние элементы будут привязаны к точке, отстоящей от края контейнера на 50 пикселей.

Вот стили, соответствующие сценарию горизонтальной прокрутки:

.section {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 0 0 50px;
}
Практика использования спецификации CSS Scroll Snap
Использование свойства scroll-padding при реализации горизонтальной прокрутки

Внешние отступы и свойство scroll-margin

Сокращённое свойствоscroll-marginпозволяет настраивать внешние отступы дочерних элементов контейнера, учитываемые при их прокрутке. Например, как показано на следующем рисунке, добавив к элементу.item-2свойствоscroll-margin-left: 20px, мы можем сместить позицию привязки элемента на 20 пикселей.

Практика использования спецификации CSS Scroll Snap
Использование свойства scroll-margin

В результате прокрутка остановится в тот момент, когда до края контейнера будет 20 пикселей. А если пользователь продолжит прокручивать список и дойдёт до элемента.item-3, то край этого элемента будет привязан к началу контейнера, так как для этого элемента свойствоscroll-marginне задано.

Способы использования CSS Scroll Snap

Список изображений

CSS Scroll Snap отлично подходит для создания списка изображений. Благодаря этому работать с таким списком будет гораздо удобнее, чем с использованием обычной прокрутки.

Вот стили:

.images-list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x;
  gap: 1rem;
  -webkit-overflow-scrolling: touch; /* Важно для iOS-устройств */}

.images-list img {
  scroll-snap-align: start;
}

Обратите внимание на то, что в качестве значения свойстваscroll-snap-typeиспользуетсяx. Жёсткость привязки будет, по умолчанию, установлена в значениеproximity.

Пример прокрутки

Popular Images

Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap Практика использования спецификации CSS Scroll Snap

Вотинтерактивный вариант этого примера.

Список друзей

Список друзей — это ещё один отличный способ использования CSS Scroll Snap. Нижеприведённый пример взят с Facebook (то есть — перед нами — реальный пример).

Практика использования спецификации CSS Scroll Snap
Список друзей

Вот CSS-код к этому примеру:

.list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  gap: 1rem;
  scroll-padding: 48px;
  padding-bottom: 32px;
  -webkit-overflow-scrolling: touch;
}

.list-item {
  scroll-snap-align: start;
}

Обратите внимание на то, что при настройке контейнера используется свойствоpadding-bottom: 32px. Сделано это для того чтобы дать дополнительное пространство для вывода тени, задаваемой свойствомbox-shadow.

Практика использования спецификации CSS Scroll Snap
Без использования свойства padding-bottom тень выводится не полностью

Список аватаров

В данном примере нас интересует значениеcenter, задаваемое свойствуscroll-snap-alignдочерних элементов контейнера.

Практика использования спецификации CSS Scroll Snap
Список аватаров

Вот стили:

.list {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.list-item {
  scroll-snap-align: center;
}

Этот подход хорош для тех случаев, когда нужно, чтобы аватар располагался бы по центру контейнера.

Здесьс этим примером можно поэкспериментировать.

Практика использования спецификации CSS Scroll Snap
Эксперименты со списком аватаров

Список разделов, занимающих всю доступную высоту области просмотра страницы

Использование спецификации CSS Scroll Snap может пригодиться и при реализации сценариев вертикальной прокрутки элементов. Например — при организации работы с элементами, занимающими всю высоту области просмотра страницы.

Практика использования спецификации CSS Scroll Snap
Элементы, занимающие всю высоту области просмотра страницы

Вот разметка к этому примеру:

<main>
  <section class="section section-1"></section>
  <section class="section section-2"></section>
  <section class="section section-3"></section>
  <section class="section section-4"></section>
  <section class="section section-5"></section>
</main>

Вот стили:

main {
  height: 100vh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
}

.section {
  height: 100vh;
  scroll-snap-align: start;
}

Здесьможно найти рабочий вариант этого примера.

Практика использования спецификации CSS Scroll Snap
Элементы, занимающие всю доступную высоту области просмотра страницы

Значения inline и block свойства scroll-snap-type

Полагаю, стоит сказать о том, что при настройке свойстваscroll-snap-typeможно использовать логические CSS-значенияinlineиblock. Вот пример:

main {
  scroll-snap-type: inline mandatory;
}

В данном примере значениеinlineпредставляет горизонтальное измерение в горизонтальных режимах вывода данных, например — в английском языке. А для языков вроде японского значениеinlineбудет представлять вертикальное измерение.

Подробнее о логических CSS-свойствах можно почитатьздесь.

Доступность

При применении спецификации CSS Scroll Snap стоит помнить о доступности контента. Вот пример плохого использования этой спецификации. Здесь настройки прокрутки мешают пользователю свободно читать выводимые материалы.

Вот CSS-код:

.wrapper {
  scroll-snap-type: y mandatory;
}

h2 {
  scroll-snap-align: start;
}
Практика использования спецификации CSS Scroll Snap
Прокрутить текст так, как показано справа, при таком подходе нельзя. Дело в том, что при прокрутке осуществляется привязка заголовков к началу контейнера

Можетеиспытатьэто сами.

Практика использования спецификации CSS Scroll Snap
Неудачное использование CSS Scroll Snap

Пожалуйста, постарайтесь так не делать!

Пользуетесь ли вы возможностями CSS Scroll Snap в своих проектах?

Поделится

Добавить комментарий

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять