В этой статье мы реализуем два типа горизонтальных списков и галерею. Вначале в теоретической части опишем, какое поведение элементов интерфейса хотим получить. В практической части рассмотрим, как воплотить необходимую механику в CSS и JavaScript.
Теория: горизонтальные списки и галерея
Приведённая ниже анимация иллюстрирует горизонтальный список со свободным скроллингом. Структуру можно свободно прокручивать влево и вправо. Список можно слегка оттягивать на крайних элементах. Это даёт подсказку пользователю о границах объекта.
Горизонтальный список со снэппингом – почти то же самое, но текущий элемент списка при тапе заменяется на следующий.
Оба элемента могут применяться я в сочетании, например, список со снэппингом для изображений, относящихся к одному сюжету или пользователю, а список с прокруткой – для быстрого перемещения между такими разделами.
Третий рассматриваемый элемент – галерея. Она похожа на snapping-списки, но каждый элемент занимает всё поле, как в обычном посте Instagram из нескольких фотографий. Под картинками расположен ряд точек – по одной для каждого изображения. Пользователю понятно, что есть другие изображения и какое из них видно в данный момент.
Практическая часть
1. Горизонтальные списки со свободной прокруткой
Для горизонтального списка используем flexbox, которому разрешим горизонтальный скроллинг. Размер элементов списка укажем явно, как и зазор между ними. Поля установим бо́льшими, чем зазор, чтобы видеть, когда мы докрутили до начала или конца списка.
Интерактивное представление и полный код доступны в в сэндбоксе:
Работает, но можно улучшить.
Поведение при прокрутке влево. В некоторых браузерах свайп влево повторяет действие кнопки «Назад». Такое поведение можно предотвратить, установив для overscroll-behavior
значение contain
.
Полосу прокрутки можно скрыть, установив overflow-x
в auto
. Однако при скроллинге полоса вновь появится. Чтобы скрыть полностью, можно установить scrollbar-width
в none
. На момент написания статьи это работало только в Firefox. Для других браузеров придется добавить трюкачества в CSS:
Плавная прокрутка. В iOS не хватает
стандартной плавной прокрутки (momentum scrolling). Потребуется добавить -webkit-overflow-scrolling:
touch;
.
Предотвращение
вертикальной прокрутки. Мы можем прокручивать
страницу по вертикали. Эту возможность лучше
отключить для пользователей мобильных устройств, добавив к списку touch-action:
pan-x
. Однако если список покрывает всю видимую область просмотра, а на странице есть что-то ещё, эти элементы станут недоступны. То есть такой вариант надо использовать с осторожностью.
В результате наших преобразований соответствующая часть CSS теперь будет иметь следующий вид:
А результат выглядит вот так (там же полный код примера):
2. Горизонтальный список со снэппингом
Для описания этого типа списков отталкиваемся от списка со свободной прокруткой. Сначала сообщаем списку, когда нужно останавливаться:
Элементам списка добавляем опцию scroll-snap-align: start
. Чтобы дать подсказку, следующий элемент может немного «выглядывать» из-за края экрана. Для этого достаточно установить отступ прокрутки: scroll-padding-inline-start:
20px
. Если хочется свайпнуть
одним движением несколько элементов,
можно добавить scroll-snap-stop: always
к элементам списка, но не все браузеры пока
такое поддерживают.
Код полностью также выложен на Codesandbox:
3. Галерея в стиле Instagram
Если мы сделаем наш предыдущий список таким же широким, как область прокрутки, и удалим отступы, он будет выглядеть и вести себя примерно так же, как галерея Instagram. За исключением маленьких точек. Без точек будет выглядеть так:
Но как мы поясняли в теоретической части, эти маленькие точки – полезный графический приём. Получается, что нам нужно следить за тем, какой из элементов списка сейчас виден. Наиболее простой способ – использовать IntersectionObserver.
Составим список точек, каждая из которых соответствует одной из картинок. Когда она пролистывается в списке, мы получаем индекс элемента и устанавливаем индикаторную точку с соответствующим индексом в активное положение.
Вот как это будет выглядеть:
Полный результат также доступен в сэндбоксе:
Заключение
Мы разобрали несколько вариаций построения горизонтальных списков изображений. У приведённых решений есть и свои недостатки, и преимущества. Поскольку используется нативная прокрутка, нет возможности настроить способ движения, мы не можем контролировать «липкость» ползунка (в этом случае правильнее было бы использовать решение на JavaScript). Кроме того, в нашем решении мы использовали не самые стандартные подходы в CSS. Однако объём кода невелик, и он работает даже в старых браузерах.
Комментарии