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

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

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

Как исправить эффект цепочной прокрутки

Старое и самое популярное решение данной ситуации - при открытии модального окна добавлять свойство 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 прекрасно работает с несколькими уровнями прокрутки должным образом, что очередной раз позволяет решить простым способом ранее сложно реализуемые задачи.

Поддержка браузерами
chrome
Chrome
63
firefox
Firefox
59
internet explorer
IE
 
edge
Edge
18
safari
Safari
16
opera
Opera
50