Базовый обзор того, как создать в Интернете интерфейс, аналогичный Instagram Stories.
В этом посте я хочу поделиться мыслями о создании компонента Stories для Интернета, который будет адаптивным, поддерживает навигацию с помощью клавиатуры и работает во всех браузерах.
Если вы предпочитаете практическую демонстрацию создания этого компонента Stories самостоятельно, ознакомьтесь с кодовой лабораторией компонента Stories .
Если вы предпочитаете видео, вот версия этого поста на YouTube:
Обзор
Двумя популярными примерами UX Stories являются Snapchat Stories и Instagram Stories (не говоря уже о автопарках). В общих чертах UX, истории обычно представляют собой ориентированный только на мобильные устройства шаблон для навигации по нескольким подпискам. Например, в Instagram пользователи открывают историю друга и просматривают фотографии в ней. Обычно они делают это со многими друзьями одновременно. Нажав на правую сторону устройства, пользователь переходит к следующей истории этого друга. Проведя пальцем вправо, пользователь переходит к другому другу. Компонент Story очень похож на карусель, но позволяет перемещаться по многомерному массиву, а не по одномерному. Как будто внутри каждой карусели есть карусель. 🤯
![Визуализация многомерного массива с помощью карточек. Слева направо находится стопка карточек с фиолетовыми рамками, а внутри каждой карты находится по одной карточке с голубой рамкой. Список в списке.](https://web.dev/static/articles/building/a-stories-component/image/visualized-multi-dimensio-bca9c1e40444a.png?authuser=2&hl=ru)
2-я "сложенная" карусель историй
👍 Список в списке, он же: многомерный массив
Выбор правильных инструментов для работы
В целом этот компонент показался мне довольно простым в создании благодаря нескольким важным функциям веб-платформы. Давайте прикроем их!
CSS-сетка
Наш макет оказался непростым испытанием для CSS Grid, поскольку он оснащен некоторыми мощными способами управления контентом.
Макет друзей
Наша основная оболочка компонента .stories
— это горизонтальная прокрутка, ориентированная на мобильные устройства:
.stories {
inline-size: 100vw;
block-size: 100vh;
display: grid;
grid: 1fr / auto-flow 100%;
gap: 1ch;
overflow-x: auto;
scroll-snap-type: x mandatory;
overscroll-behavior: contain;
touch-action: pan-x;
}
/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
max-inline-size: 480px;
max-block-size: 848px;
}
Давайте разберем эту grid
:
- Мы явно заполняем область просмотра на мобильных устройствах значениями
100vh
и100vw
и ограничиваем размер на настольном компьютере. -
/
разделяет наши шаблоны строк и столбцов -
auto-flow
переводится какgrid-auto-flow: column
- Шаблон автопотока равен
100%
, что в данном случае соответствует ширине окна прокрутки.
На мобильном телефоне думайте об этом как о том, что размер строки — это высота области просмотра, а каждый столбец — это ширина области просмотра. Продолжая пример с историями Snapchat и Instagram, каждый столбец будет историей друга. Мы хотим, чтобы истории друзей продолжались за пределами области просмотра, чтобы нам было куда прокручивать. Grid создаст столько столбцов, сколько потребуется для разметки HTML-кода для каждой истории друзей, создавая для нас динамический и отзывчивый контейнер прокрутки. Grid позволил нам централизовать весь эффект.
Укладка
Для каждого друга нам нужны истории в готовом к разбиению на страницы состоянии. Готовясь к анимации и другим забавным шаблонам, я выбрал стек. Когда я говорю «стопка», я имею в виду, что вы смотрите на бутерброд сверху, а не сбоку.
С помощью сетки CSS мы можем определить сетку из одной ячейки (т. е. квадрат), где строки и столбцы имеют общий псевдоним ( [story]
), а затем каждому дочернему элементу назначается это псевдонимное пространство из одной ячейки:
.user {
display: grid;
grid: [story] 1fr / [story] 1fr;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.story {
grid-area: story;
background-size: cover;
…
}
Это позволяет нашему HTML контролировать порядок наложения, а также обеспечивает плавность всех элементов. Обратите внимание, что нам не нужно ничего делать с absolute
позиционированием или z-index
, и нам не нужно корректировать бокс с помощью height: 100%
или width: 100%
. Родительская сетка уже определила размер области просмотра изображения истории, поэтому ни одному из этих компонентов истории не нужно было указывать, чтобы она заполнила его!
Точки привязки прокрутки CSS
Спецификация CSS Scroll Snap Points упрощает фиксацию элементов в области просмотра при прокрутке. До того, как появились эти свойства CSS, вам приходилось использовать JavaScript, и это было… сложно, если не сказать больше. Ознакомьтесь с статьей «Введение в точки привязки прокрутки CSS» Сары Драснер, чтобы получить подробное описание того, как их использовать.
scroll-snap-points
и со стилями. Без него пользователи смогут свободно прокручивать страницы как обычно. Благодаря ему браузер мягко опирается на каждый элемент..stories { display: grid; grid: 1fr / auto-flow 100%; gap: 1ch; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior: contain; touch-action: pan-x; }
.user { display: grid; grid: [story] 1fr / [story] 1fr; scroll-snap-align: start; scroll-snap-stop: always; }
Я выбрал точки привязки прокрутки по нескольким причинам:
- Свободный доступ . В спецификации прокрутки точек привязки указано, что нажатие клавиш со стрелкой влево и стрелкой вправо должно по умолчанию перемещаться по точкам привязки.
- Растущая спецификация . Спецификация Scroll Snap Points постоянно получает новые функции и улучшения, а это означает, что мой компонент «Истории», вероятно, с этого момента станет только лучше.
- Простота реализации . Точки привязки прокрутки практически созданы для сенсорно-ориентированного варианта использования горизонтальной пагинации.
- Инерция в стиле свободной платформы . Каждая платформа будет прокручиваться и отдыхать в своем стиле, в отличие от нормализованной инерции, которая может иметь странный стиль прокрутки и отдыха.
Кроссбраузерная совместимость
Мы тестировали на Opera, Firefox, Safari и Chrome, а также на Android и iOS. Ниже приведен краткий обзор веб-функций, в которых мы обнаружили различия в возможностях и поддержке.
Однако мы не применили некоторые CSS, поэтому на некоторых платформах в настоящее время отсутствует оптимизация UX. Мне понравилось отсутствие необходимости управлять этими функциями, и я был уверен, что в конечном итоге они появятся в других браузерах и платформах.
scroll-snap-stop
Карусели были одним из основных вариантов использования UX, который побудил к созданию спецификации CSS Scroll Snap Points. В отличие от историй, карусель не всегда должна останавливаться на каждом изображении после того, как пользователь с ним взаимодействует. Возможно, было бы неплохо или желательно быстро просмотреть карусель. С другой стороны, по историям лучше всего перемещаться по одному, и это именно то, что обеспечивает scroll-snap-stop
.
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
На момент написания этой статьи scroll-snap-stop
поддерживается только в браузерах на базе Chromium. Проверьте совместимость браузера для получения обновлений. Хотя это не блокировщик. Это просто означает, что в неподдерживаемых браузерах пользователи могут случайно пропустить друга. Таким образом, пользователям просто придется быть более осторожными, или нам придется написать JavaScript, чтобы гарантировать, что пропущенный друг не будет помечен как просмотренный.
Если вам интересно, читайте больше в спецификации .
overscroll-behavior
Вы когда-нибудь прокручивали модальное окно и вдруг начинали прокручивать содержимое за модальным окном? overscroll-behavior
позволяет разработчику ловить эту прокрутку и никогда не позволять ей уходить. Это приятно на все случаи жизни. Компонент «Мои истории» использует его, чтобы предотвратить выход дополнительных пролистываний и жестов прокрутки за пределы компонента.
.stories {
overflow-x: auto;
overscroll-behavior: contain;
}
Safari и Opera были двумя браузерами, которые не поддерживали эту функцию, и это совершенно нормально. Эти пользователи получат привычный опыт прокрутки и могут никогда не заметить этого улучшения. Лично я большой поклонник и люблю включать его почти в каждую реализуемую мной функцию прокрутки. Это безобидное дополнение, которое может привести только к улучшению UX.
scrollIntoView({behavior: 'smooth'})
Когда пользователь нажимает или щелкает и достигает конца набора историй друга, пришло время перейти к следующему другу в наборе точек привязки прокрутки. С помощью JavaScript мы смогли сослаться на следующего друга и запросить его прокрутку в поле зрения. Поддержка этих основ великолепна; каждый браузер прокручивал его в поле зрения. Но не каждый браузер сделал это 'smooth'
. Это просто означает, что он прокручивается в поле зрения, а не фиксируется.
element.scrollIntoView({
behavior: 'smooth'
})
Safari был единственным браузером, который не поддерживал behavior: 'smooth'
. Проверьте совместимость браузера для получения обновлений.
Практический
Теперь, когда вы знаете, как я это сделал, как бы вы поступили?! Давайте разнообразим наши подходы и изучим все способы разработки в Интернете. Создайте глюк , напишите мне в Твиттере свою версию, и я добавлю ее в раздел ремиксов сообщества ниже.
Ремиксы сообщества
- @geoffrich_ со Svelte : демо и код
- @GauteMeekOlsen с Vue : демо + код
- @AnaestheticsApp с Lit : демо и код