Представьте ситуацию, когда на вашем сайте кроме основного скролла окна браузера есть еще блоки со скроллом. Обычно это спозиционированные окошки с дополнительной информацией, появляющиеся по запросу. Если скроллить контент таких элементов до самого конца и потом продолжать скролл (находясь в фокусе того же контента) - вы увидите, что после этого начинается скролл окна браузера. Это поведение имеет название "цепочка прокрутки" - по окончании одного скролла начинается скролл внешнего элемента и т.д.
Взгляните на пример ниже и попробуйте поскроллить содержимое модального окошка и вы увидите этот цепочный эффект.
Наиболее распространенный минус этого эффекта для этого случая - при закрытии модального окна мы уже увидим другую часть страницы вместо той, которая была в момент открытия окна. Плюс, сам эффект отвлекает пользователя от фокуса на содержимом окна.
Как исправить эффект цепочной прокрутки
Старое и самое популярное решение данной ситуации - при открытии модального окна добавлять свойство overflow: hidden для тега html. Правильней это сделать путем добавления класса. Например:
html.modal-opened {
overflow: hidden;
}
Вся эта штука прекрасно работала во всех браузерах и устройствах, кроме Safari и iOS.
Один из дополнительных фиксов заключается в добавлении дополнительного стиля:
html.modal-opened {
overflow: hidden;
position: fixed;
}
С таким набором стилей прокрутки внешних элементов точно не будет. Однако при этом у нас возникает побочный эффект - при открытии модального окна скролл браузерного окна будет кидать нас в самое начало страницы. Не очень желаемое поведение, если мы открыли модальное окно где-то в середине страницы и при его закрытии хотим там же и находиться.
Чтобы не пользоваться свойством position: fixed и привести UI к единому виду на всех устройствах приходилось подключать JavaScript и вычислять скролл страницы или вообще делать его отмену. Однако все это дополнительный не желаемый код, в котором тоже можно найти массу минусов.
Современное решение - свойство overscroll-behavior
Свойство overscroll-behavior позволяет указать браузеру как себя вести при достижении конца скролла элемента. Мы можем применить как свойство overscroll-behavior-x или overscroll-behavior-y, так и сокращенный их вариант - overscroll-behavior.
Возможные значения свойства:
- auto - значение по умолчанию; цепочка прокрутки будет работать в стандартном режиме.
- contain - скролл будет доступен только в пределах текущего элемента.
- none - скролл доступен в пределах текущего элемента и предотвращает отскок экрана при достижении края контейнера.
Свойство необходимо задавать именно тому элементу, который нам нужно скроллить.
.modal-box {
overscroll-behavior: contain;
}
Важно отметить один нюанс - если контейнер, которому вы установили свойство overscroll-behavior: contain не имеет скролла, то цепочка прокрутки будет работать в обычном режиме (т.е. родитель будет скроллиться).
Примеры использования overscroll-behavior
Давайте для рассмотренного выше модального окна добавим свойство overscroll-behavior: contain и посмотрим как теперь ведет себя скролл внешних элементов при прокрутке содержимого окна. Он не работает.
Другой распространенный пример применения свойства - выезжающее навигационное меню. По клику на "бургер" появляется меню и когда ваш курсор будет в области скролла меню - по достижению конца прокрутки окно браузера скроллиться не будет. Когда курсор будет вне меню - скролл отработает по стандарту.
Нечто подобное мы можем увидеть на сайтах интернет-магазинов, где есть боковой сайдбар, в котором находится множество фильтров, не вмещающихся по высоте в экран и требующих скролл. Также похожий вид имеют появляющиеся в углу окна с чатом службы поддержки, где переписка может быть объемной и, опять же, требовать прокрутки.
Последний пример скорее всего редкость, но все же интересен для его визуализации - это многоуровневый скролл. Представим, что в нашем предыдущем модальном окне есть еще один скролл на более глубоком уровне.
Как видим, свойство overscroll-behavior прекрасно работает с несколькими уровнями прокрутки должным образом, что очередной раз позволяет решить простым способом ранее сложно реализуемые задачи.
Комментарии (0)