Skip to content
О сайте Блог Обучение Исследовать узоры Case studies
Содержание
  • Обзор
  • Реализация на веб-платформе
    • HTML-код
    • Макеты с прокруткой
    • Анимация
    • Как еще улучшить наш JavaScript
    • Заключение
  • Ремиксы сообщества
  • Home
  • All articles

Создание компонента вкладок

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

Feb 17, 2021
Available in: English, Português, 中文, 日本語 и 한국어
Adam Argyle
Adam Argyle
TwitterGitHubGlitchHomepage
Содержание
  • Обзор
  • Реализация на веб-платформе
    • HTML-код
    • Макеты с прокруткой
    • Анимация
    • Как еще улучшить наш JavaScript
    • Заключение
  • Ремиксы сообщества

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

Демопример

Если вы предпочитаете видео, вот версия этой статьи на YouTube:

Обзор #

Вкладки — стандартный компонент систем дизайна, но они могут быть разных видов и форм. Первыми были вкладки для ПК, построенные на элементе <frame>, теперь же у нас есть красивые мобильные компоненты с анимацией на основе «физических» свойств. Но задача у них всех одна: сэкономить место.

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

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

Реализация на веб-платформе #

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

  • scroll-snap-points — взаимодействие жестами и с помощью клавиатуры, а также правильные позиции остановки прокрутки;
  • ссылки на контент посредством URL-хешей — поддержка встроенной прокрутки в браузере и передачи ссылок;
  • поддержка программ чтения с экрана: разметка элементами <a> и id="#hash";
  • prefers-reduced-motion — плавные переходы и мгновенная прокрутка внутри страницы;
  • предложенная функция @scroll-timeline для динамического подчеркивания и изменения цвета выбранной вкладки.

HTML-код #

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

У нас используются элементы структурного контента: ссылки и :target. Нам нужен список ссылок (для чего отлично подходит <nav>) и список элементов <article> (здесь подходит <section>). Каждому хешу ссылки будет соответствовать section, поэтому браузер сможет делать прокрутку по ссылке.

При нажатии кнопки с ссылкой меняется контент в фокусе

Например, в Chrome 89 при нажатии на ссылку фокус автоматически переключается на article-элемент :target — и не нужно ничего писать на JS. Пользователь может прокрутить содержимое article обычным образом с помощью имеющегося устройства ввода. Это дополнительный контент, как указано в разметке.

Например, в Chrome 89 при нажатии на ссылку фокус автоматически переключается на article-элемент :target — и не нужно ничего писать на JS. Пользователь может прокрутить содержимое article обычным образом с помощью имеющегося устройства ввода. Это дополнительный контент, как указано в разметке.

<snap-tabs>
<header>
<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>
</header>
<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>
</snap-tabs>

Установить связь между элементами <a> и <article> можно с помощью свойств hrefи id следующим образом:

<snap-tabs>
<header>
<nav>
<a href="#responsive"></a>
<a href="#accessible"></a>
<a href="#overscroll"></a>
<a href="#more"></a>
</nav>
</header>
<section>
<article id="responsive"></article>
<article id="accessible"></article>
<article id="overscroll"></article>
<article id="more"></article>
</section>
</snap-tabs>

Затем я заполнил каждый article различным количеством «рыбы», а ссылки — заголовками различной длины с изображениями для заголовков. Контент у нас есть — можно приступать к работе над макетом.

Макеты с прокруткой #

В этом компоненте есть области прокрутки трех типов:

  • Блок навигации (розовый цвет) использует горизонтальную прокрутку.
  • Область контента (синий цвет) также использует горизонтальную прокрутку.
  • Элементы article (зеленый цвет) используют вертикальную прокрутку.
Три цветных прямоугольника со стрелками соответствующего цвета, которые указывают область и направление прокрутки

При прокрутке используются элементы двух типов:

  1. Окно.
    Прямоугольник с заданными размерами и стилем свойства overflow.
  2. Безразмерная поверхность.
    В этом макете это списочные контейнеры: ссылки nav, элементы article в разделах section и содержимое article.

Макет для <snap-tabs> #

В качестве макета верхнего уровня я выбрал flex (адаптируемый блок) с направлением column — чтобы заголовок и section располагались вертикально. Это первое окно прокрутки; оно скрывает всё с помощью overflow: hidden. Заголовок и и section будут использовать прокрутку за границы в виде отдельных зон.

HTML

<snap-tabs>
<header></header>
<section></section>
</snap-tabs>

CSS

snap-tabs {
display: flex;
flex-direction: column;

/* устанавливаем первичный контейнер */
overflow: hidden;
position: relative;

& > section {
/* указываем использовать всё место */
block-size: 100%;
}

& > header {
/* защита от случая, когда <section> требует 100 % */
flex-shrink: 0;
/* учет особенностей различных браузеров */
min-block-size: fit-content;
}
}

Возвращаясь к разноцветной схеме с тремя областями прокрутки:

  • Элемент <header> теперь готов стать розовым контейнером прокрутки.
  • Элемент <section> готов стать синим контейнером прокрутки.

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

Элементы «header» и «section» помечены ярко-розовыми ярлыками и выделены рамкой, ограничивающей место, которое они занимают в компоненте

Макет для <header> #

Следующий макет почти такой же: я создаю вертикальную упорядоченную структуру с помощью flex.

HTML

<snap-tabs>
<header>
<nav></nav>
<span class="snap-indicator"></span>
</header>
<section></section>
</snap-tabs>

CSS

header {
display: flex;
flex-direction: column;
}

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

Элементы «nav» и «span.indicator» помечены ярко-розовыми ярлыками и выделены рамкой, ограничивающей место, которое они занимают в компоненте

Далее — стили прокрутки. Оказывается, один стиль можно использовать в двух областях горизонтальной прокрутки (header и section), поэтому я сделал вспомогательный класс: .scroll-snap-x.

.scroll-snap-x {
/* браузер решает, можно ли прокручивать и отображать полосы по X, Y скрыто */
overflow: auto hidden;
/* не даем создать цепочку прокрутки по X */
overscroll-behavior-x: contain;
/* прокрутка должна привязываться к дочернему элементу по X */
scroll-snap-type: x mandatory;

@media (hover: none) {
scrollbar-width: none;

&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}

В каждом случае нужен overflow по оси x, contain для захвата выхода за границы прокрутки, скрытые полосы прокрутки для сенсорных устройств и, наконец, scroll-snap для фиксации областей показа контента. Удобный порядок вкладок при использовании клавиатуры позволяет переключать фокус естественный образом. У контейнеров scroll-snap красивый «карусельный» стиль взаимодействия при использовании с клавиатуры.

Макет для <nav> в заголовке #

Ссылки nav должны располагаться строкой, без разрывов строк, с центрированием по вертикали, причем каждый элемент ссылки должен привязываться к контейнеру scroll-snap. CSS 2021 отлично с этим справляется!

HTML

<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>

CSS

nav {
display: flex;

& a {
scroll-snap-align: start;

display: inline-flex;
align-items: center;
white-space: nowrap;
}
}

Стили и размеры ссылок задаются автоматически, поэтому в макете nav нужно указать только направление и структуру наполнения — flow. Благодаря различной ширине элементов nav за переходом между вкладками интересно наблюдать: ширина индикатора подстраивается к новой цели. Отображение полосы прокрутки браузером будет зависеть от количества элементов.

Элементы «nav» помечены ярко-розовыми ярлыками, выделены рамкой, указывающей место, которое они занимают в компоненте, и снабжены стрелкой для направления развертывания

Макет для <section> #

Этот раздел представляет собой элемент flex и должен быть основным потребителем места. Ему также необходимо создать столбцы для размещения статей. И CSS 2021 снова отлично справляется с задачей! С помощью block-size: 100% элемент растягивается на весь родительский объект, а затем для собственного макета создает несколько столбцов с шириной, равной 100% родительского объекта. Здесь проценты использовать удобно, поскольку для «родителя» мы указали строгие ограничения.

HTML

<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>

CSS

section {
block-size: 100%;

display: grid;
grid-auto-flow: column;
grid-auto-columns: 100%;
}

Это можно перевести как «расширять по вертикали, насколько это возможно» (вспомните заголовок, для которого мы установили на flex-shrink: 0: это защита от такого принудительного расширения). Так мы устанавливаем высоту строки для столбцов полной высоты. При этом стиль auto-flow указывает сетке всегда располагать дочерние элементы в горизонтальную линию, без переноса (как нам и нужно), что позволяет заполнить родительское окно с выходом за его границы.

Элементы «article» помечены ярко-розовыми ярлыками, выделены рамкой, указывающей место, которое они занимают в компоненте, и снабжены стрелкой для направления развертывания

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

Макет для <article> #

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

HTML

<article>
<h2></h2>
<p></p>
<p></p>
<h2></h2>
<p></p>
<p></p>
...
</article>

CSS

article {
scroll-snap-align: start;

overflow-y: auto;
overscroll-behavior-y: contain;
}

Я решил, что article будут привязаны к их родительскому компоненту прокрутки. Мне нравится, что элементы link навигации и элементы article привязываются к началу соответствующих контейнеров прокрутки: создается ощущение гармоничных взаимоотношений.

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

Элемент article является дочерней сеткой, причем ее размер предопределен как область просмотра, в которой нам нужна прокрутка. Это означает, что стили высота и ширины здесь не нужны — достаточно определить переполнение. Для overflow-y я задаю auto, а затем захватываю взаимодействие прокрутки с помощью удобного свойства overscroll-behavior.

Резюме по трем областям прокрутки #

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

Включен показ трех полос прокрутки. Они занимают место в макете, но наш компонент по-прежнему выглядит отлично

Я думаю, что наличие контейнера для полос прокрутки в этом компоненте помогает четко показать, где находятся области прокрутки, в каком направлении они работают и как взаимодействуют друг с другом. Каждый из этих фреймов окна прокрутки также является родительским элементом flex или grid по отношению к макету.

DevTools помогают визуализировать структуру и поведение макета:

Области прокрутки с обозначением инструментов `grid` и `flex`, указывающим место, которое они занимают в компоненте, и направление развертывания
Chromium DevTools: макет для элемента `nav` адаптируемого блока, содержащий элементы со ссылками, макет `section` в виде сетки с элементами `article`, а также элементы `article` с абзацами и элементами заголовков.

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

О функциях #

Дочерние элементы с привязкой к прокрутке сохраняют зафиксированное положение при изменении размера. Это означает, что коду JavaScript не нужно ничего отображать при повороте устройства или изменении размера браузера. Перейдите в Режим устройства (Device Mode) в Chromium DevTools и выберите любой режим, кроме отзывчивого (Responsive), а затем измените размер фрейма устройства. Элемент остается в поле зрения и фиксируется вместе с содержимым. Эта функция работает так с того момента, как Chromium обновил реализацию в соответствии со спецификацией. Можете почитать запись в блоге об этом.

Анимация #

Цель анимации здесь — четко связать работу ссылок с откликом интерфейса. Так мы поможем пользователю с удобством (надеюсь) просмотреть весь контент. Я буду добавлять анимацию движения с определенной целью и и условиями. Надо помнить, что пользователи могут задавать предпочтения по движению в операционной системе, и я с удовольствием учитываю их в проектируемых мной интерфейсах.

Я свяжу подчеркивание вкладки с положением прокрутки элемента article. Привязка обеспечивает не только красивое выравнивание, но и соотнесение с началом и окончанием анимации. Это позволяет элементу <nav>, который действует как мини-карта, не терять связь с контентом. Предпочтения пользователя по движению будем проверять и с помощью CSS, и с помощью JS. В некоторых местах придется проявить особую внимательность!

Поведение прокрутки #

Мы можем улучшить поведение :target и element.scrollIntoView(). По умолчанию переход мгновенный: браузер просто устанавливает положение прокрутки. Допустим, мы хотим сделать переход в положение прокрутки не мгновенным.

@media (prefers-reduced-motion: no-preference) {
.scroll-snap-x {
scroll-behavior: smooth;
}
}

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

Индикатор вкладок #

Цель этой анимации — связать индикатор с состоянием контента. Для пользователей, предпочитающих ограничение движения, я решил делать переход цвета в стилях border-bottom, а для остальных — связанный с прокруткой сдвиг и анимацию смены цвета.

Переключая это предпочтение в Chromium DevTools, я демонстрирую оба стиля переходов. Работать над ними было очень интересно!

@media (prefers-reduced-motion: reduce) {
snap-tabs > header a {
border-block-end: var(--indicator-size) solid hsl(var(--accent) / 0%);
transition: color .7s ease, border-color .5s ease;

&:is(:target,:active,[active]) {
color: var(--text-active-color);
border-block-end-color: hsl(var(--accent));
}
}

snap-tabs .snap-indicator {
visibility: hidden;
}
}

Если пользователь хочет видеть меньше движения, я скрываю .snap-indicator, поскольку этот элемент становится не нужен. Вместо него я использую стили border-block-end и transition. Также обратите внимание на взаимодействие вкладок: активный элемент nav выделяется не только подчеркиванием, но и более тёмным цветом текста. У активного элемента более высокий цветовой контраст текста и яркий акцент подчеркивания.

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

@scroll-timeline #

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

const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
);

Сначала я с помощью JavaScript проверяю предпочтения пользователя по движению. Если результат — false (пользователь хочет видеть меньше движения), тогда мы не будем запускать эффекты привязки прокрутки.

if (motionOK) {
// код анимации с использованием движения
}

На момент написания статьи поддержки @scroll-timeline в браузерах нет. Функция пребывает в виде черновой спецификации — есть только экспериментальные реализации. Однако для нее есть полифил, который я и применяю в этой демонстрации.

ScrollTimeline #

И CSS, и JavaScript позволяют делать ScrollTimeline для прокрутки, однако я выбрал JavaScript — чтобы использовать в анимации актуальные размеры элементов.

const sectionScrollTimeline = new ScrollTimeline({
scrollSource: tabsection, // snap-tabs > section
orientation: 'inline', // прокрутка в направлении потока букв
fill: 'both', // двунаправленное связывание
});

Я хочу, чтобы один элемент следовал за положением прокрутки другого. Создав ScrollTimeline, я определяю ведущий элемент для связки с прокруткой — scrollSource. Обычно анимация в веб-дизайне запускается в соответствии с глобальным тиком интервала времени, но с помощью sectionScrollTimeline это можно изменить.

tabindicator.animate({
transform: ...,
width: ...,
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);

Прежде чем я перейду к ключевым кадрам анимации, думаю, важно упомянуть, что ведомый элемент прокрутки — tabindicator — будет анимироваться по специальной временной шкале — прокрутке нашего section. Здесь мы заканчиваем привязку, но у нас отсутствует последний ингредиент — точки с отслеживанием состояния, между которыми происходит анимация. Их еще называют ключевыми кадрами.

Динамические ключевые кадры #

Есть, конечно, очень мощный чисто декларативный способ делать анимацию в CSS с помощью @scroll-timeline, но нужная мне анимация была слишком динамичной. CSS не позволяет делать переход между шириной со значением auto и динамически создавать ключевые кадры в зависимости от длины дочерних элементов.

Однако получить эту информацию можно с помощью JavaScript. Поэтому мы будем проходить по дочерним элементам сами и захватывать вычисленные значения во время выполнения кода:

tabindicator.animate({
transform: [...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`),
width: [...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);

Для каждого tabnavitem деструктурируем положение offsetLeft и возвращаем строку, которая использует его как значение translateX. Так мы получаем четыре ключевых кадра преобразования для анимации. То же делаем и с шириной: запрашиваем ее у каждого элемента и используем как значение ключевого кадра.

Вот пример вывода с моими шрифтами и настройками браузера:

Ключевые кадры translateX:

[...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`)

// возвращает четыре элемента массива, представляющие собой четыре состояния ключевых кадров
// ["translateX(0px)", "translateX(121px)", "translateX(238px)", "translateX(464px)"]

Ключевые кадры ширины:

[...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)

// возвращает четыре элемента массива, представляющие собой четыре состояния ключевых кадров
// ["121px", "117px", "226px", "67px"]

Стратегия вкратце: индикатор вкладки будет анимироваться по четырем ключевым кадрам в зависимости от положения scroll-snap компонента прокрутки section. Точки привязки задают четкое разграничение между ключевыми кадрами и делают анимацию более синхронной по ощущениям.

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

Пользователь управляет анимацией своими действиями и видит, как ширина и положение индикатора меняются от одного section к другому, в точности следуя за прокруткой.

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

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

Как это делается:

tabnavitems.forEach(navitem => {
navitem.animate({
color: [...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
});

Для каждой ссылки nav на вкладке нужна новая анимация цвета по той же временно́й шкале, что и у индикатора подчеркивания. Я использую ту же временну́ю шкалу, что и раньше: ее задача — выдавать при прокрутке тик, поэтому мы можем использовать его в анимации любого нужного нам типа. Как и раньше, я создаю четыре ключевых кадра в цикле и получаю цвета.

[...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)

// возвращает четыре элемента массива, представляющие собой четыре состояния ключевых кадров
// [
"var(--text-active-color)",
"var(--text-color)",
"var(--text-color)",
"var(--text-color)",
]

Ключевой кадр с цветом var(--text-active-color) выделяет ссылку. В остальных случаях это стандартный цвет текста. Вложенный цикл делает процедуру вполне понятной: внешний цикл — это каждый элемент навигации, а внутренний — это их ключевые кадры. Я проверяю, совпадает ли элемент внешнего цикла с элементом внутреннего цикла и таким образом узнаю, когда он выбран.

Писать этот код — одно удовольствие.

Как еще улучшить наш JavaScript #

Напомню: то, что я здесь показываю, в основе своей работает и без JavaScript. Однако давайте посмотрим, что можно улучшить, используя JS.

Ссылки на контент #

Ссылки на контент — это скорее мобильный термин, но, думаю, что их цели вполне соответствует случай, когда URL-адрес передается непосредственно в содержимое вкладки. Браузер будет переходить на странице к идентификатору, совпадающим с хешем URL. Я обнаружил, что этот обработчик onload действует на всех платформах.

window.onload = () => {
if (location.hash) {
tabsection.scrollLeft = document
.querySelector(location.hash)
.offsetLeft;
}
}

Синхронизация с окончанием прокрутки #

Пользователи не всегда будут нажимать на вкладки или использовать клавиатуру — иногда они просто будут использовать прокрутку. Когда компонент прокрутки в section останавливается, его положение должно совпадать с состоянием верхней панели навигации.

Так мы ожидаем окончания прокрутки:

tabsection.addEventListener('scroll', () => {
clearTimeout(tabsection.scrollEndTimer);
tabsection.scrollEndTimer = setTimeout(determineActiveTabSection, 100);
});

Каждый раз при прокрутке элементов section мы сбрасываем время ожидания (если оно есть) и начинаем новый отсчет. Когда прокрутка элемента section останавливается, мы не сбрасываем время ожидания, а запускаем отсчет 100 мс с момента начала бездействия. По окончании отсчета вызываем функцию, которая определяет, где пользователь остановился.

const determineActiveTabSection = () => {
const i = tabsection.scrollLeft / tabsection.clientWidth;
const matchingNavItem = tabnavitems[i];

matchingNavItem && setActiveTab(matchingNavItem);
};

Поскольку у нас прокрутка с привязкой, то, разделив текущее положение прокрутки на ширину области прокрутки, мы должны получить целое, а не десятичное число. Затем я пытаюсь взять navitem из кеша с помощью вычисленного здесь индекса, и, если подходящий находится, делаю его активным.

const setActiveTab = tabbtn => {
tabnav
.querySelector(':scope a[active]')
.removeAttribute('active');

tabbtn.setAttribute('active', '');
tabbtn.scrollIntoView();
};

Сначала мы деактивируем вкладку, которая является активной сейчас, а затем даем полученному элементу nav атрибут активного состояния. Здесь стоит отметить вызов scrollIntoView(), который интересным образом взаимодействует с CSS.

.scroll-snap-x {
overflow: auto hidden;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;

@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}

Во вспомогательном CSS scroll-snap мы вложили запрос медиа, который применяет прокрутку типа smooth, если пользователь разрешает элементы с движением. JavaScript может легко вызывать элементы прокрутки в представление, а CSS может декларативно управлять интерфейсом. Очаровательная парочка.

Заключение #

Я рассказал свое видение решения этой задачи. А как ее решали бы вы? Получилась очень интересная архитектура компонентов! Кто же первый сделает версию с блек-джеком в своем любимом фреймворке? 🙂

Давайте разнообразим наши подходы и рассмотрим самые разные реализации для веб-сайтов. Создайте свою версию на Glitch, твитните мне, и я добавлю добавлю ее в раздел Ремиксы сообщества ниже.

Ремиксы сообщества #

  • Версия @devnook, @rob_dodson и @DasSurma с веб-компонентами (статья).
  • Версия @jhvanderschee с кнопками: Codepen.
CSSDOMJavaScriptКомпоновкаМобильные устройстваUX
Последнее обновление: Feb 17, 2021 — Улучшить статью
Return to all articles
Поделиться
подписаться

Contribute

  • Сообщить об ошибке
  • Просмотреть исходный код

Дополнительная информация

  • developer.chrome.com
  • Новости Chrome
  • Разборы конкретных случаев
  • Подкасты
  • Шоу

Соцсети

  • Twitter
  • YouTube
  • Google Developers
  • Chrome
  • Firebase
  • Google Cloud Platform
  • Все продукты
  • Условия и конфиденциальность
  • Правила сообщества

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies.