Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как запретить прокрутку страницы под модальным окном

Короткий ответ

Пока открыто окно <dialog>, отключите прокрутку страницы правилом с :has() — JavaScript для этого не нужен:

<style>
  html:has(dialog[open]) { overflow: hidden; }
</style>
 
<button onclick="box.showModal()">Open the dialog</button>
<dialog id="box">
  <p>The page behind does not scroll now.</p>
  <button onclick="box.close()">Close</button>
</dialog>
<p style="height: 600px;">Long page content…</p>

Окно открывает и закрывает одна строка скрипта, а прокрутку блокирует CSS: как только у <dialog> появляется атрибут open, корневой элемент получает overflow: hidden.

Прокрутка внутри окна

Если внутри окна свой длинный список, при докрутке до конца браузер начинает прокручивать страницу под ним. Это останавливает overscroll-behavior:

.modal-body { max-height: 60vh; overflow-y: auto; overscroll-behavior: contain; }

Скачок страницы

Когда полоса прокрутки исчезает, страница становится шире и содержимое сдвигается вправо. Свойство scrollbar-gutter: stable у html заранее оставляет место под полосу, и ничего не прыгает.

Частая ошибка

Ставят overflow: hidden только на body, а прокручивается на самом деле корневой элемент html — особенно если ему где-то задана высота или свой overflow. Страница продолжает прокручиваться. Указывайте правило для html, как в примере, — или для обоих элементов.

Функции из этого ответа

  • overflow — Что делать с содержимым, которое не помещается в элемент.
  • :has() — Выбирает элемент, внутри которого есть что-то подходящее под селектор в скобках, — «селектор родителя».
  • <dialog> — Диалоговое окно; модальное открывается методом `showModal()` и блокирует остальную страницу.
  • <body> — Видимая часть страницы: всё, что видит пользователь.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.