Браузерная поддержка и базовое использование
С тех пор, как CSS Scroll Snap был представлен в 2016 году, поддержка браузерами существенно улучшилась. К 2018 году Google Chrome (69+), Firefox, Edge, и Safari поддерживали какую-либо версию этого модуля. Согласно CanIUse, на данный момент технология поддерживается всеми современными браузерами.
Использование Scroll Snapping заключается в установке свойства scroll-snap-type для элемента-контейнера и свойства scroll-snap-align для дочерних элементов. Прокрутка элемента-контейнера осуществляться с привязкой к дочерним элементам, которые вы определили. В этом самом простом случае это будет выглядеть следующим образом:
Данный способ отличается от первой версии спецификации, которая позволяла вам устанавливать точки привязки вручную, используя ключевое слово .
Такой подход был довольно ограниченным, поскольку позволял устанавливать точки привязки только через определённые равные промежутки, что не позволяло реализовать интерфейс, который работал бы с элементами разных размеров. Например, если элементы меняются в зависимости от размера экрана, это может вызвать проблемы. На данный момент все современные браузеры поддерживают новый способ, который ориентируется не на расстояние, а на сами элементы.
Вы можете использовать оба этих метода (если ваш макет позволяет это) для поддержки старых версий браузеров:
Ещё более гибкий вариант – использовать новый синтаксис, а для браузеров, которые его не поддерживают, использовать полифилл. Именно этот способ я использую в примерах ниже.
Создание плавающих контейнеров при помощи float
Изначально элементы веб-страницы располагаются на ней друг за другом, в том порядке, в котором определены в html-коде. Размещая в коде теги абзацев, заголовков, списков и др. на странице мы видим их в том же порядке. Но при помощи некоторых атрибутов css мы можем изменить этот порядок. Один из них float.
Правило float позволяет нам создавать так называемые плавающие элементы. То есть мы можем установить для блочного элемента выравнивание по левому или правому краю родительского элемента (блочного контейнера, в который он вложен, или самой Web-страницы). При этом блочный элемент будет прижиматься к соответствующему краю родителя, а остальное содержимое будет обтекать его с противоположной стороны. Подобное мы уже видели в чистом html, когда рассматривали атрибут align со значениями left и right для тега img, который используется для вставки картинок на веб-страницу.
У этого правила может быть три возможных значения:
float: left|right|none|inherit
По умолчанию float использует значение none, то есть элементы не имеют никакого обтекания и идут по порядку друг за другом.
Значения left и right выравнивают элемент веб-страницы соответственно по левому и правому краю родительского элемента, а остальное содержимое будет обтекать его с противоположной стороны.
Рассмотрим два блочных элемента. Для начала просто подсветим их фоном различным цветом с помощью правила background:
<div style=»background:silver»>Содержимое первого блочного элемента</div>
<div style=»background:«>Содержимое второго блочного элемента</div>
Так они ведут себя в обычном случае:
А теперь для первого div-а давайте пропишем правило float со значением left, и зададим ему отступы с помощью свойства margin для наглядности его взаимодействия с соседним тегом:
<div style=»background:silver; float:left; margin:4px;»>Содержимое первого блочного элемента</div>
<div style=»background:«>Содержимое второго блочного элемента</div>
Как видим, первый div стал выравниваться по левому краю, а содержимое соседнего элемента сало обтекать его по правой стороне.
При применении правила float к строчным элементам, последние начинают вести себя как блочные при взаимодействии с другими элементами web-страниц. Так, например, в обычных ситуациях правила height и width для строчных элементов работать не будут. Но после применения атрибута float, параметры размеров сразу начинают иметь значения.
Давайте к предыдущему примеры добавим элемент span и в стилях пропишем для него размеры:
<span style=»background: #CEE2D3; width:200px; height:100px;float:left»>Содержимое строчного элемента span</span><div style=»background:silver; float:left; margin:4px;»>Содержимое первого блочного элемента</div>
<div style=»background:«>Содержимое второго блочного элемента</div>
На рисунке видно, что правила width и height для span-а не сработали и его размеры стали равны в соответствии с его содержимым.
Теперь добавим элементу span правило float со значением left:
<span style=»background: #CEE2D3; width:200px; height:100px;float:left»>Содержимое строчного элемента span</span>
<div style=»background:silver;»>Содержимое первого блочного элемента</div>
<div style=»background: #fd0″>Содержимое второго блочного элемента</div>
Теперь элемент span приобрел размеры в соответствии с правилами css, а соседние элементы стали обтекать его с правой стороны. Из этого можно сделать вывод, что правило float можно применять как к строчным, так и к блочным элементам. Причем не зависимо от того к какому элементу применяется правило, он становится блочным.
А что если задать одинаковое значение атрибута стиля float для нескольких следующих друг за другом элементов? Давайте посмотрим:
<span style=»background: #CEE2D3; width:100px; float:left»>Содержимое строчного элемента span</span>
<div style=»background:silver; width:100px; float:left»>Содержимое первого блочного элемента</div>
<div style=»background: #fd0; width:100px; float:left»>Содержимое второго блочного элемента</div>
Они выстроятся по горизонтали друг за другом в том порядке, в котором они прописаны в html-коде, и будут выровнены по указанному краю родительского элемента.
Остается заметить, что правило float применяется при блочной верстке, основанной на плавающих контейнерах. При применении такого дизайна часто приходится помещать какие-либо элементы ниже тех, что были выровнены по левому или правому краю. Если просто убрать у них правило стиля float или задать для него значение none, результат будет непредсказуемым. В этом случае на помощь приходит правило clear.
scrollTo() with smooth scrolling
The next piece of the puzzle is that most carousels have little indicator buttons that let you navigate between the items in the list.
For this, we will need a little bit of JavaScript. We can use the scrollTo() API with , which tells the browser to smoothly scroll to a given offset:
function scrollToItem(itemPosition, numItems, scroller) { scroller.scrollTo({ scrollLeft: Math.floor( scroller.scrollWidth * (itemPosition / numItems) ), behavior: 'smooth' }) }
The only trick here is that and . But we can detect support and fall back to a JavaScript implementation, such as this one.
Here is my technique for detecting native smooth scrolling:
function testSupportsSmoothScroll () { var supports = false try { var div = document.createElement('div') div.scrollTo({ top: 0, get behavior () { supports = true return 'smooth' } }) } catch (err) {} return supports }
Being careful to set s and states for the buttons, and adding a debounced scroll listener to update the pressed state as the user scrolls, we end up with something like this:
View in full mode
You can also add generic “go left” and “go right” buttons; the principle is the same.
Знакомство с CSS Scroll Snap
ВотЭлементы привязаны к началу контейнера
?Настройка жёсткости привязки
Элементы жёстко привязаны к началу контейнера
ЗдесьПрокрутка с привязкойвотРабота с интерактивным вариантом примераЭлементы привязаны к началу контейнера менее жёстко
ВотПоследствия использования значения proximity
?Свойство scroll-snap-align
Значения свойства scroll-snap-align и их влияние на содержимое, расположенное в контейнере по горизонталиЗначения свойства scroll-snap-align и их влияние на содержимое, расположенное в контейнере по вертикали
?Использование свойства scroll-snap-stop
ВотПри слишком быстрой прокрутке некоторые элементы можно пропустить
ВотБраузер не позволяет пропускать элементызнак «STOP»Точки привязки — это, при использовании значения always, то же самое, что и знаки «STOP»ЗдесьЭксперименты со свойством scroll-snap-stop
?Внутренние отступы и свойство scroll-padding
Использование свойства scroll-padding при реализации горизонтальной прокрутки
Использование свойства scroll-padding при реализации вертикальной прокрутки
Способы использования CSS Scroll Snap
Прокручиваемый список изображений
ВотЭксперименты со списком изображений
Список друзей
Без использования свойства padding-bottom тень выводится не полностью
Список аватаров
ЗдесьЭксперименты со списком аватаров
?Список разделов, занимающих всю доступную высоту области просмотра страницы
Элементы, занимающие всю высоту области просмотра страницы
ЗдесьЭлементы, занимающие всю доступную высоту области просмотра страницы
?Доступность
Прокрутить текст так, как показано справа, при таком подходе нельзя. Дело в том, что при прокрутке осуществляется привязка заголовков к началу контейнераиспытатьНеудачное использование CSS Scroll Snap
Построение геометрии карусели
В этом разделе я покажу вам ключевые правила CSS, которые я буду проходить шаг за шагом.
В следующих фрагментах кода некоторые переменные Sass используются, чтобы сделать компонент более настраиваемым. Я буду использовать, чтобы обозначить количество изображений в карусели и указать ширину изображения.
Элемент является содержащим окном для первого изображения и опорного элемента , вокруг которого другие изображения будут расположены и трансформированны.
Предположим, на данный момент, что у карусели было только одно изображение для демонстрации, я могу начать с калибровки и выравнивания:
Элемент имеет заданную ширину карусельного элемента , и он имеет такую же высоту изображений (они могут иметь различные размеры , но они должны иметь одинаковое соотношение сторон). Таким образом, высота контейнера карусели адаптируется к высоте изображения. Кроме того, горизонтально центрируется в карусельном контейнере.
Первое изображение не нуждается в дополнительных преобразованиях, потому что оно уже находится в своем целевом положении, то есть на передней стороне карусели.
Карусель можно поворачивать в трехмерном пространстве, применяя преобразование вращения к элементу. Это вращение должно быть вокруг центра многоугольника, поэтому я изменю исходное происхождение преобразования :
Это значение отрицается, потому что в CSS положительное направление оси z находится вне экрана, к зрителю. Скобки необходимы, чтобы избежать синтаксических ошибок Sass. Вычисление многоугольника apothem будет объяснено позже.
Переведя систему отсчета элемента, вся карусель может поворачиваться с вращением на (новой) оси y:
Я вернусь к деталям этого поворота позже.
Перейдем к преобразованиям для других изображений. При абсолютном позиционировании изображения складываются внутри <figure>:
Эти значения игнорируются , потому что это только предварительный шаг для следующих преобразований. Фактически, теперь каждое изображение можно поворачивать по оси y карусели на угол поворота, который зависит от стороны многоугольника, на которой назначено изображение. Во-первых, как это делается с элементом, изменяется исходное происхождение изображений по умолчанию, перемещая его в центр многоугольника:
Затем изображения могут поворачиваться на их новой оси y на величину, заданную ($i — 1) * $theta радианами, где $i индекс (начиная с одного) изображения и $theta = 2 * $PI / $n, $PI представляя математическую константу pi . Следовательно, второе изображение будет повернуто $theta третьим 2 * $theta, и так далее, до последнего изображения, которое будет повернуто ($n — 1) * $theta.
Это относительное расположение изображений будет сохранено во время поворотов карусели (т.е. Вращения вокруг измененной оси y <figure>) благодаря иерархической природе вложенных преобразований CSS.
Это количество вращения каждого изображения может быть присвоено с помощью @for директивы управления Sass :
Это использует конструкцию, а не потому, что вместо последнего значения, присвоенного переменной индекса $i, будет n-1 вместо n.
Обратите внимание на два примера #{} синтаксиса интерполяции Sass . В первом случае он используется для индекса селектора;
Во втором случае он используется для установки значения свойства вращения
Изображения
Слайд-шоуГалерея слайд-шоуМодальные изображенияЛайтбоксАдаптивная Сетка изображенияСетка изображенияГалерея вкладокОверлей изображенияСлайд с наложенным изображениемМасштабирование наложения изображенияНазвание наложения изображенияЗначок наложения изображенияЭффекты изображенияЧерно-белое изображениеТекст изображенияТекстовые блоки изображенийПрозрачный текст изображенияПолное изображение страницыФорма на картинкеГерой изображениеПараллельные изображенияОкругленные изображенияАватар изображенияАдаптивные образыЦентрировать изображенияМиниатюрыПознакомьтесь с командойЛипкое изображениеОтражение изображенияВстряхните изображениеПортфолио галереяПортфолио с фильтрациейМасштабирование изображенияИзображение увеличительное стеклоПолзунок сравнения изображений
Идеальный?
Что нужно, чтобы карусель была «идеальной»? Он должен быть доступен:
Мышь. Он должен предлагать предыдущие и следующие кнопки, которые легко нажимать и не скрывать контент. Коснитесь (сенсорный ввод): он должен отследить палец, а затем прокрутиться с тем же импульсом, что и при падении пальца с экрана. Колесико прокрутки: Часто пропускается, Apple Magic Mouse и многие треки для ноутбука обеспечивают плавное горизонтальное прокручивание. Мы должны использовать эти возможности! Клавиатура. Многие пользователи предпочитают не использовать или использовать мышь для навигации
Важно сделать нашу карусель доступной, чтобы пользователи могли использовать наш продукт
Наконец, мы сделаем еще один шаг вперед и сделаем это уверенным, восхитительным элементом UX, сделав карусель отчетливо и в явном виде с весенней физикой, когда ползунок достигнет конца.
Возможность действияСкопировать ссылку
Уже есть пара вещей, которые сообщают пользователю, что это область слайдера: стиль фокуса и тот факт, что обычно крайнее правое изображение обрезается. Предполагается, что можно увидеть больше.
Вы можете решить, что этого достаточно, в зависимости от того, насколько критично для пользователей видеть скрытый контент. Так же в этом случае сохраняется лаконичность кода. Тем не менее, мы могли бы сделать всё более очевидным. Мантра инклюзивного дизайна: если есть сомнения, объясните это более подробно.
Мы можем сделать это с помощью элемента с «инструкцией» после слайдера. Сообщение будет появляться в зависимости от его состояния. Например, мы могли бы показать при помощи сообщение «Прокрутите, чтобы увидеть больше». Смежный селектор + добавит стиль к элементу .
Сообщение в состоянии может быть реализовано примерно таким же образом. Однако для пользователей скринридеров нам нужно ещё связать это сообщение с областью слайдера. Не имеет значения представляет эта область интерес для каждого из них или нет. Это даёт больше контекста о том, почему область может быть им интересна. Также пользователи лучше понимают, чего они избегают, когда им не нужен этот элемент.
Для этого можем использовать атрибут . Мы указываем его для сообщения с фокусом, используя значение в качестве содержимого для ARIA-атрибута:
Теперь, когда фокус устанавливается на галерее слайдера, скринридеры объявят что-то вроде этого: «Галерея изображений, область, используйте клавиши со стрелками для того, чтобы увидеть больше». Как дальше описано в примечании про мультимодальность, убедитесь, что пользователям скринридеров будет просто войти в эту область и пройти через каждое изображение в определённом порядке в «режиме просмотра» (в нём они проходят через каждый элемент). Другими словами, слайдер мультимодален даже для этой группы пользователей.
Путь пользователя скринридера в режиме просмотра во многом похож на путь пользователя клавиатуры при наличии связанных/интерактивных слайдов. В любом случае, браузер или скринридер сдвинет контейнер, чтобы показать элементы, на которые сделан фокус.
Hover и focus?Скопировать ссылку
Иногда интересно то, что обнаруживаешь при тестировании. В моём случае я заметил, что, когда одновременно и фокусировался, и наводился на слайдер, появлялись оба сообщения. Конечно же.
Я обнаружил, что в качестве улучшения могу объединить состояния () и показать сообщение, в котором описаны обе ситуации.
Используя селектор следующего элемента , я могу добиться того, что два других сообщения скрыты, в противном случае увидел бы сразу три!
Попробуйте навестись на слайдер в демо, а затем кликнуть по нему:
Making sure the content overflows
We will place each section aligned next to each other so the content overflows horizontally. We are trying to create something like this, where elements are overflowing the container and therefore we can create a horizontal scrollbar for them. You can have as many sections as you want.
For the purpose of this demo we will make the elements full-screen. To do this, we will use viewport units like and to set the and properties to scale to both the edges of the screen. Then we can center the content using and .
We use making the element the flex container. We will also be hiding the scrollbar for this demo by using . There’s no need for this but we’ll be doing it for our demo. If you decide not to hide it, make sure to change it for .
And why not, we will also give each section a different background:
Вращение карусели
Чтобы облегчить тестирование поворота карусели, я собираюсь добавить элемент управления пользовательского интерфейса, чтобы перемещаться между изображениями. См. Демо-версию CodePen для HTML, CSS и JavaScript, реализующих этот элемент управления; Здесь я опишу только код, относящийся к вращению.
Мы используем целочисленную переменную, указывающую, какое изображение находится впереди карусели. Когда пользователь взаимодействует с предыдущими / последующими кнопками, эта переменная увеличивается или уменьшается на единицу.
После обновления , поворот карусели выполняется с помощью:
(Здесь и в следующих фрагментах литералы шаблонов ES6 используются для интерполяции выражений в строках, не стесняйтесь использовать традиционный оператор конкатенации «+», если вы предпочитаете)
Где theta то же самое, что и раньше:
Вращение происходит — theta из-за того, что для перехода к следующему пункту требуется вращение против часовой стрелки, и такие значения поворота отрицательны в преобразованиях CSS.
Обратите внимание, что это currImageзначение не ограничено диапазоном , но вместо этого оно может расти бесконечно, как в положительном, так и в отрицательном направлении. На самом деле, если изображение на передней панели является последним (так currImage== n-1), и пользователь нажимает следующую кнопку, если мы переустановим currImageна 0, чтобы перейти к первому изображению карусели, произойдет переход Угол поворота от (n-1)*theta до 0, и это повернет карусель в противоположном направлении по всем предыдущим изображениям. Аналогичная проблема может возникнуть при нажатии кнопки prev, когда первое изображение является первым. Чтобы быть разборчивым, я должен даже проверить потенциальные переполнения currentImage, потому что Number тип данных не может принимать сколь угодно большие значения. Эти проверки не реализованы в демо-коде
Чтобы быть разборчивым, я должен даже проверить потенциальные переполнения currentImage, потому что Number тип данных не может принимать сколь угодно большие значения. Эти проверки не реализованы в демо-коде.
Увидев базовый CSS, лежащий в основе карусели, теперь JavaScript можно использовать для улучшения компонента несколькими способами, такими как:
- Произвольное количество изображений
- Изображения с процентной шириной
- Несколько экземпляров карусели на странице
- Конфигурации для каждого экземпляра, такие как размер зазора и видимость на обратной стороне
- Конфигурация с использованием атрибутов данных HTML5 *
Сначала я удаляю из таблицы стилей переменные и правила, связанные с происхождением преобразования и поворотами, потому что это будет сделано с использованием JavaScript:
Hiding the scrollbar (optional)
Now, the next piece of the puzzle is that most carousels don’t have a scrollbar, and depending on the browser and OS, you might not like how the scrollbar appears.
Also, our carousel already includes all the buttons needed to scroll left and right, so it effectively has its own scrollbar. So we can consider removing the native one.
To accomplish this, we can start with rather than , which ensures that at least if there’s only one image (and thus no possibility of scrolling left or right), the scrollbar doesn’t show.
Beyond that, we may be tempted to add , but this actually makes the list entirely unscrollable. Bummer.
So we can use a little hack instead. Here is some CSS to remove the scrollbar, which works in Chrome, Edge, Firefox, and Safari:
.scroll { scrollbar-width: none; -ms-overflow-style: none; } .scroll::-webkit-scrollbar { display: none; }
And it works! The scrollbar is gone:
View in full mode
Admittedly, though, this is a bit icky. The only standards-based CSS here is scrollbar-width, which is currently only supported by Firefox. The -webkit-scrollbar hack is for Chrome and Safari, and the -ms-overflow-style hack is for Edge/IE.
So if you don’t like vendor-specific CSS, or if you think scrollbars are better for accessibility, then you can just keep the scrollbar around. Follow your heart!
CSS scroll snap
Let’s start off with CSS scroll snap. This is what makes the scrollable element “snap” to a certain position as you scroll it.
The is pretty good. The only trick is that you have to write one implementation for the modern scroll snap API (supported by Chrome and Safari), and another for the older scroll snap points API (supported by Firefox).
You can detect support using . As usual for iOS Safari, you’ll also need to add to make the element scrollable.
But lo and behold, we now have the world’s simplest carousel implementation. It doesn’t even require JavaScript – just HTML and CSS!
Note: for best results, you may want to view the above pen in full mode.
The benefit of having all this “snapping” logic inside of CSS rather than JavaScript is that the browser is doing the heavy lifting. We don’t have to use listeners or to try to get the pixel-perfect snapping behavior with the right animation curve – the browser handles all of it for us, in native code.
And unlike , this scroll-snapping works for any method of scrolling – touchpad, touchscreen, scrollbar, you name it.
Свойство scroll-snap-stop
Свойство (en-US) сообщает браузеру, обязательно ли ему останавливаться на каждой точке привязки дочерних элементов (это значит, что в примере выше мы бы останавливались в начале каждой секции) или допускается возможность пропускать их. Это свойство реализовано в меньшем количестве браузеров, чем другие свойства из данной спецификации.
Данное свойство может быть полезно в ситуации, когда нужно, чтобы пользователь гарантированно увидел каждую прокручиваемую секцию, случайно не пролистав какую-то из них. С другой сторона, такое поведение прокрутки может только мешать и замедлять пользователя, который ищет конкретную секцию.
Примечание: на данный момент свойство помечено рискованным для использования в данной версии спецификации, следовательно может быть вообще удалено.
3D карусель изображений
window.addEventListener(«load», () => {
var carousels = document.querySelectorAll(«.carousel-3d»);
for (var i = 0; i < carousels.length; i++) {
carousel(carousels);
}
});
function carousel(root) {
var figure = root.querySelector(«figure»),
nav = root.querySelector(«nav»),
images = figure.children,
n = images.length,
gap = root.dataset.gap || 0,
bfc = «bfc» in root.dataset,
theta = 2 * Math.PI / n,
currImage = 0;
setupCarousel(n, parseFloat(getComputedStyle(images).width));
window.addEventListener(«resize», () => {
setupCarousel(n, parseFloat(getComputedStyle(images).width));
});
setupNavigation();
function setupCarousel(n, s) {
var apothem = s / (2 * Math.tan(Math.PI / n));
figure.style.transformOrigin = `50% 50% ${-apothem}px`;
for (var i = 0; i < n; i++) images.style.padding = `0 ${gap}px`;
for (i = 0; i < n; i++) {
images.style.transformOrigin = `50% 50% ${-apothem}px`;
images.style.transform = `rotateY(${i * theta}rad)`;
}
if (bfc)
for (i = 0; i < n; i++) images.style.backfaceVisibility = «hidden»;
rotateCarousel(currImage);
}
function setupNavigation() {
nav.addEventListener(«click», onClick, true);
function onClick(e) {
e.stopPropagation();
var t = e.target;
if (t.tagName.toUpperCase() != «BUTTON») return;
if (t.classList.contains(«next»)) {
currImage++;
} else {
currImage—;
}
rotateCarousel(currImage);
}
}
function rotateCarousel(imageIndex) {
figure.style.transform = `rotateY(${imageIndex * -theta}rad)`;
}
}
Некоторые мысли об удобстве для пользователей
Связывать с прокруткой – опасное занятие. Поскольку это один из основных способов взаимодействия с приложением, любое изменение этого поведения может вызывать раздражение – термин «scrolljacking» используется для обозначения подобного рода явлений.
Достоинством реализованного в CSS управления привязкой прокрутки является то, что вы не получаете прямой контроль над позицией прокрутки. Вместо этого, вы просто даёте браузеру список позиций для привязки таким образом, который соответствует платформе, способу ввода и пользовательским предпочтениям. Это значит, что поведение прокрутки, которое вы создаёте, на любой платформе будет ощущаться как нативное (то есть, с использованием тех же анимаций и т.д).
Считаю это ключевым преимуществом привязки прокрутки, реализованной с помощью CSS, перед JavaScript библиотеками, предлагающими схожую функциональность.
По моим личным ощущениям, это работает достаточно хорошо, особенно на мобильных устройствах. Возможно, из-за того, что «scroll snapping» уже является частью встроенного в мобильные платформы UI. Вспомните главный экран на iOS и Android устройствах – это, по сути, горизонтальный слайдер с точками привязки. Взаимодействие в Chrome на Android особенно приятно, потому что воспринимается как обычная прокрутка, но область видимости всегда останавливается на точке привязки:
Your browser does not support HTML5 video.
Для реализации такого поведения, определённо нужно проводить некоторые математические вычисления. Благодаря CSS Scroll Snapping мы добиваемся такого же результата без этого.
Конечно, мы не должны создавать точки привязки на всём подряд. Например, страницы со статьями прекрасно обойдутся и без них. Но я думаю, что они могут существенно улучшить удобство взаимодействия с приложение, если будут использованы в нужный момент – галереи изображений, слайдшоу кажутся хорошими кандидатами.
Вывод
Это все для части 1. До сих пор мы рассмотрели существующие карусели, чтобы увидеть сильные и слабые стороны различных подходов к прокрутке. Мы использовали отслеживание входных данных Popmotion и физику для того, чтобы наглядно анимировать наш перевод карусели с сенсорной прокруткой. Мы также познакомились с функциональным составом и карриными функциями.
Вы можете получить прокомментированную версию «истории до сих пор» на этом CodePen.
В следующих выпусках мы рассмотрим:
- прокрутка с помощью колеса мыши
- повторное измерение карусели при изменении размера окна
- разбиение на страницы, доступность клавиатуры и мыши
- восхитительные прикосновения, с помощью источника физики
Ждем Вас там!