Содержание статьи
соображения UX
Я не буду углубленно обсуждать аспекты горизонтальной прокрутки UX; однако, при использовании горизонтальной прокрутки, кажется, что должны быть выполнены по крайней мере два принципа UX:
- . В вашем дизайне должен быть визуальный намек на то, что набор контента горизонтально прокручивается. Лучший способ сделать это — разрешить часть прокручиваемого содержимого.
- Важно, чтобы пользователь знал, когда заканчивается прокрутка. Мы заметили, что пользователи повторяют операцию прокрутки, потому что считают, что они не прокрутили достаточно в предыдущей попытке.
Обозначение макета
Прежде чем мы начнем, давайте набросим макеты, которые мы хотим выполнить:
- Контейнер для прокрутки должен следовать общей компоновке страницы — т. е. соблюдение полей и отступов
- Часть прокручиваемого содержимого должна заглядывать из края
- . Содержимое контейнера должно скользить с краев экрана при прокрутке
- Водосточный желоб между содержимым должен быть меньше, чем у краев, так что на обоих концах контейнера будет больше места (указывая пользователю, что они прокручиваются до конца)
Итак, что-то вроде этого:
Notice, что на обоих концах горизонтального прокручивающего контейнера имеется равное количество пространства, соответствующее окружающему
Общая компоновка
Теперь, когда у нас есть фундаментальное понимание функций, которые мы хотим использовать в нашем горизонтальном контейнере прокрутки, давайте посмотрим, как мы можем его кодировать с помощью CSS Grid , Удобная вещь в CSS Grid заключается в том, что мы можем легко управлять канавкой между элементами без дальнейших вычислений.
Для общей компоновки мы будем использовать простую, но мощную технику CSS Grid:
. app {
display: grid;
grid-template-columns: 20px 1fr 20px;
}
.app> * {
grid-column: 2 / -2;
}
.app> .full {
grid-column: 1 / -1;
}
Любые прямые дети из .app будут быть «контейнерным» с 20px зазором на обоих концах, сохраняя содержимое с краев. Если ребенок оборудован классом .full он будет охватывать весь видовой экран без каких-либо дополнений на стороне (ака. Полное кровотечение).
Прокручивающийся контейнер
Создадим горизонтальный прокручивающийся контейнер с шестью картами, показывающий по два за раз. Поскольку мы хотим, чтобы контейнер горизонтальной прокрутки соответствовал общей компоновке с дополнением с обеих сторон, мы опускаем класс .full и можем попробовать что-то вроде этого:
.hs {
display : сетка;
сетчатая щель: 10 пикселей;
grid-template-columns: repeat (6, calc (50% - 40px));
grid-template-rows: minmax (150px, 1fr);
}
Используя grid-template-columns мы можем настроить, сколько места мы хотим, чтобы каждая карта должна была занимать — в этом примере карты занимают 50% окна просмотра ,
. Однако, когда вычитание желоба, вычитая сточную канаву, как вы могли заметить — карты обрезаны с обоих концов. Помните, мы хотим, чтобы прокручиваемый контент скользил по краям экрана при прокрутке.
Итак, добавим класс контейнера .full в контейнер и компенсируем отсутствие прокладки:
.hs {
дисплей: сетка;
сетка-зазор: 10 пикселей;
grid-template-columns: repeat (6, calc (50% - 40px));
grid-template-rows: minmax (150px, 1fr);
padding: 0 20px;
}
На первый взгляд кажется, что мы достигли желаемого результата, но как только вы прокрутите до конца, вы заметите, что нет места — (19459005)
Возможно, вы захотите с этим справиться, добавив крайний край к последнему элементу следующим образом:
.hs> li: last-child {
margin-right: 20px;
}
U К сожалению, это тоже не работает. Итак, как мы можем это решить?
Предлагаемое решение
Давайте рассмотрим, что у нас есть, как только мы удалим заполнение контейнера:
.hs {
display:
сетчатый зазор: 10px;
grid-template-columns: repeat (6, calc (50% - 40px));
grid-template-rows: minmax ( 150px, 1fr),
}
Если мы добавим несколько пустых пространств по обе стороны от столбцов grid-template, выступающих в качестве дополнения, мы сможем достичь желаемого макета .
Давайте добавим 2 x 10px пустых пространств к столбцам сетки с обоих концов.
.hs {
дисплей: сетка;
сетчатая щель: 10 пикселей;
сетка-шаблон-столбцы:
10px
повтор (6, вычислено (50% - 40px))
10px
template-rows: minmax (150px, 1fr);
}
Для того, чтобы первая карта не занимала пространство первого столбца 10px, мы вводим пустые псевдоэлементы на каждом конце:
.hs :: before,
.hs :: after {
content: '';
}
The :: элементы before и :: after прекрасно вписываются в столбцы сетки, так как они автоматически добавляются к началу и концу контейнера с горизонтальной прокруткой. К счастью, в сетке участвуют псевдоэлементы.
Теперь мы выполняем все макеты, которые мы изложили в начале:
Предостережения
Одно из предостережений этого :
grid-template-columns:
10px
repeat 6 calc (50% - 40px))
10px;
Если в одном из контейнеров содержится только 4 карты, вам нужно будет установить новое правило сетки для этот конкретный контейнер. И это не очень гибко.
. Один из способов сделать его более гибким — подсчитать, сколько карт есть в конкретном контейнере с помощью Javascript, а затем присвоить это число переменной CSS:
var root = document.documentElement;
const lists = document.querySelectorAll ('. hs');
lists.forEach (el => {
const listItems = el.querySelectorAll ('li')
const n = el.children.length;
el.style.setProperty ('- total', n);
})
Затем вы можете использовать переменную внутри столбцов grid-template:
grid-template-columns:
10px
repeat ( var (- total) calc (50% - 40px))
10px;
ОБНОВЛЕНИЕ: Как отмечает Алекс Бачиу в комментариях, вы можете опустить javascript (или переменные CSS решение) полностью, используя неявную сетку. Таким образом, нам не нужно вычислять количество переполняющих столбцов, которые нам нужны, поскольку это вычисляется для нас браузером.
Чтобы это сработало, нам нужно будет немного изменить наш код :
.hs {
...
grid-template-columns: 10px;
grid-auto-flow: column;
...
.hs: before,
... .hs: after {
content: '';
width: 10px;
}
Нам по-прежнему нужен наш начальный 10px для компенсации заполнения; однако остальные карты теперь выкладываются алгоритмом автоматического размещения. Для того, чтобы это сработало, нам нужно установить автопоток на «столбец» (по умолчанию «строка»).
Наконец, нам нужно убедиться, что .hs: after — which наследуйте размер других карт — не занимает больше места, чем 10 пикселей. Таким образом, мы ограничиваем размер псевдоэлементов, применяя фиксированную ширину.
Вы можете утверждать, что код становится менее разборчивым, так как значения разбросаны немного больше, что делает его несколько менее очевидным, что продолжается. Однако, я думаю, это прекрасно:)