Рубрики
Без рубрики

Создание практических галерей, подобных Instagram, и горизонтальных списков с прокруткой CSS

В чем разница между каруселями и горизонтально прокручиваемыми списками? Это жесты, snappi … Tagged с CSS, WebDev, JavaScript.

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

Я посмотрел приложение Instagram iOS, чтобы узнать больше, и заметил 3 различных элемента, которые вы можете прокрутить горизонтально.

Я решил построить эти 3 элемента на основе того же кода, в основном CSS. Вот что я узнал.

Три закручиваемых элемента

Свободно прокручивающие горизонтальные списки

Горизонтальный список, который переполняет его границы. Вы можете свободно прокрутить влево и вправо. Netflix и Spotify используют его повсюду на мобильных устройствах, Instagram использует его для своих историй.

Он использует немного старой школы CSS, как Overflow-x и улучшается с большим количеством экспериментальных правил.

Ускоряющие горизонтальные списки

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

Здесь мы должны добавить несколько новых CSS, например, прокрутки. В более старых браузерах он изящно растекает до первой версии 👊. Это делает его очень практичным решением для использования в производстве.

Галерея

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

Код также идентичен второму. Тем не менее, нам не нужен разрыв и прокладки, а также добавляем несколько строк JavaScript, используя recsectionObserver, чтобы показать, какой DOT соответствует видимому в настоящее время изображению.

Создание трех разных версий

Свободно прокручивающие горизонтальные списки

Мы составляем горизонтальный список с элементами списка в горизонтальном ряду, используя Flex-Box, и мы позволяем списку прокручивать горизонтально.

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

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

.list {
  display: flex;
  padding: 20px;
  overflow-x: scroll;
}

.item {
  height: 224px;
  width: 125px;
  flex-shrink: 0;
}

.item:not(:last-child) { margin-right: 10px; }

Вы можете увидеть это здесь: это работает, но мы можем улучшить его:

Содержать перегрузку

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

Скрыть полос прокрутки

Первоначально мы можем скрыть полос прокрутки, установив Overflow-x к Авто Анкет Однако, когда вы начнете прокручивать, он появится снова. Мы можем установить ширина прокрутки к Нет Чтобы полностью скрыть это. На момент написания написания это работает только в Firefox, поэтому мы добавляем следующий беспорядок нестандартного ублюдка CSS, чтобы скрыть его в других браузерах:

.list { -ms-overflow-style: none; }
.list::-webkit-scrollbar { display: none; }

Выглядит намного лучше, но если вы чувствуете, что это повреждает доступность или ваш CSS-Purist Heart, вы можете оставить это и использовать Overflow-X: Auto вместо.

Прокрутка импульса

В iOS ему не хватает стандарта Прокрутка импульса Анкет Мы можем сказать браузеру, чтобы прокрутить прокрутку импульса, установив нестандартный: -Webkit-Overflow-Scrolling: Touch; Анкет

Предотвратить вертикальную прокрутку

Мы можем прокрутить страницу вертикально, взаимодействуя со списком. Мы можем отключить это для пользователей сенсорного экрана, добавив Прикосновение: Pan-X в список. Однако, если ваш список охватывает весь вид просмотра, это не позволит пользователю прокручивать вертикально. Лучше всего использовать его с осторожностью!

Список прокладки

Есть что -то странное, что происходит с прокладкой .List Анкет Это в начале, но в итоге исчезло 😕. Честно говоря, я понятия не имею, почему это происходит. Есть хакерское исправление, хотя : Абсолютно расположенный (псевдо) элемент с шириной прокладки, выходящей из прокручивания.

Это уродливо, и это не имеет никакого смысла! Как это вообще работает? Однако это это Важно, чтобы была прокладка, поэтому ясно, что мы прокрутили до конца списка. С болью в наших сердцах мы добавим это.

Итак, теперь CSS выглядит так:

.list {
  display: flex;
  padding: 20px;
  overflow-x: scroll;
  overscroll-behavior: contain;
  scrollbar-width: none;
  touch-action: pan-x;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}

.list::-webkit-scrollbar { display: none; }

.item {
  height: 224px;
  width: 125px;
  flex-shrink: 0;
}

.item:not(:last-child) { margin-right: 10px; }

/* hacky fix for padding at the end of the list */
.item:last-child {
  position: relative;
}

.item:last-child::after {
  position: absolute;
  left: 100%;
  height: 1px;
  width: 20px;
  display: block;
  content: "";
}

И это похоже на это:

Ускоряющие горизонтальные списки

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

.list {
  scroll-snap-type: x mandatory;
}

И в списки элементы мы добавляем Scroll-Snap-Align: Start; , что означает, что мы подхватываем к началу: слева, если вы используете английский или другой слева до правого языка * Анкет

Если мы посмотрим на «Предлагаемое для вас» в Instagram, предыдущий предмет всегда немного выходит на пик. Оказывается, мы можем установить накладку прокрутки на: прокрутка прокрутки-в-внедрения: 20px; Анкет (ПРИМЕЧАНИЕ: я добавил прокрутка леготь , поскольку Safari не имеет поддержки в настоящее время.

Можно провести больше предметов с одним ударом. Это невозможно в Instagram. Мы можем добавить Свиль-снап-стоп: всегда; в списки элементов, но Поддержка браузера все еще Spotty на данный момент.

Вот и все!

* ) Справа для rtl homies 👋

Инстаграм-подобная галерея

Если мы сделаем списки такими же широкими, как область прокрутки, и удалите прокладку и пробел, он выглядит и ведет себя в значительной степени как галерея Instagram. За исключением маленьких точек индикатора. Без точек это будет выглядеть так: мы хотим иметь эти точки индикатора. Они там по 3 причинам:

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

Самый простой способ – позволить браузеру позаботиться о том, чтобы определить, какой предмет виден, используя RecsectionObserver Анкет

Мы составляем список точек, каждая точка соответствует изображению. Когда элемент видна (пересекается) в списке, мы получаем индекс этого элемента и устанавливаем точку индикатора с соответствующим индексом для активного.

Это то, как он будет выглядеть, см. Комментарии в коде выше каждого раздела для объяснения каждого шага.

// references to DOM elements
const list = document.querySelector('.list');
const items = Array.from(document.querySelectorAll('.item'));
const indicators = Array.from(document.querySelectorAll('.indicator'));

// create an observer with the list as intersection root
const observer = new IntersectionObserver(onIntersectionObserved, {
  root: list,
  threshold: 0.6
});

// observe each item
items.forEach(item => {
  observer.observe(item);
});

// when the observer detects an entry changing 
// (item entering or exiting  list)
// and the entry is intersecting
// get the intersecting item's index
// set the correct indicator to active
function onIntersectionObserved(entries) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const intersectingIndex = items.indexOf(entry.target);
      activateIndicator(intersectingIndex);
    }
  });
}

// toggle an `active` class on the indicators
function activateIndicator(index) {
  indicators.forEach((indicator, i) => {
    indicator.classList.toggle('active', i === index);
  });
}

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

Примечание на пороге Мы установили порог на 0,6. Это означает, что если 60% предмета видны, оно считается пересекающимся.

Если мы установим его на 1, мы считаем только полностью видимый элемент как пересекающийся. Это прекрасно подойдет с включенным сбором свитков, но не работает с свободной прокруткой в более старых браузерах без поддержки сбоя свитков (возможно, с полифиллом recsectionobserver).

Когда мы опускаем порог куда -то ниже 1, мы считаем частично видимый элемент как пересекающийся. Если это 0,5 или ниже, можно пересечь несколько элементов. Таким образом, 0,6 кажется разумным значением.

Вывод

Плохо

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

Хорошо

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

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

А как насчет рабочего стола?

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

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

Бонусный совет: если вы хотите использовать индикаторы в качестве навигации, scrollintoview ({поведение: 'плавное', inline: 'start'}) Хорошее место для начала!

Оригинал: “https://dev.to/joostkiens/creating-practical-instagram-like-galleries-and-horizontal-lists-with-css-scroll-snapping-580e”