Популярный пост
Открытие модального окна
Классический вариант с использованием JavaScript
Многим знакомый вариант, когда открытие и закрытие модального окна происходит за счет JS. Приведу расширенный пример, когда внутри каждой карточки товара своё окошко. Здесь связь выполнена по родственным отношениям в DOM, но можно связывать и по data атрибутам или другими способами.
See the pen (@Websitio) on CodePen.
Модальные окна с помощью тега <dialog>
Этот тег появился относительно недавно и значительно упрощает создание модальных окон и попапов. Рассмотрим, как его использовать, как открывать и закрывать такие модальные окна, а также какие есть варианты их отображения.
Тег <dialog> — это встроенный в HTML элемент, который позволяет создавать модальные
и немодальные окна. Модальные окна блокируют взаимодействие с остальной частью страницы, пока они открыты, а немодальные
(попапы) — нет. Тег <dialog> предоставляет встроенные методы для управления состоянием окна
(открыто/закрыто) и поддерживает стилизацию через CSS.
Для доступности добавьте краткое имя диалога с помощью атрибутов aria-label или
aria-labelledby
Как открыть и закрыть модальное окно?
Открытие модального окна
По умолчанию содержимое модального окна скрыто. Показать его можно, добавив атрибут open
<dialog>
Закрытое, скрытое
</dialog>
<dialog open>
Открытое окно
</dialog>
Также можно открывать и закрывать окна с помощью методов JavaScript. Чтобы открыть модальное окно, используется метод
showModal():
const dialog = document.querySelector('dialog');
dialog.showModal();
Этот метод делает диалог модальным, то есть блокирует взаимодействие с остальной частью страницы.
Если нужно открыть диалог как попап (без блокировки страницы), используйте метод show():
dialog.show();
Не забывайте блокировать скролл у body при открытии модального окна. Подробнее
Закрытие <dialog>
Для закрытия модального окна используется метод close()
dialog.close();
Также модальные окна закрываются из HTML по событию submit, например, по нажатию кнопки button
type="submit", если в
dialog есть тег form с атрибутом method="dialog".
Модальные диалоги закрываются и по нажатию на Esc с клавиатуры
Возвращаемое значение
Если кнопкам в форме задать value, то при закрытии диалога это значение будет присваиваться dialog.returnValue.
See the pen (@Websitio) on CodePen.
Стилизация <dialog> и его оверлея
Модальные окна можно стилизовать с помощью CSS. Например, можно изменить фон, добавить анимацию или изменить внешний вид кнопок.
dialog {
padding: 20px;
border: 1px solid #ffffff;
}
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
Или сделаем, например, градиентную заливку:
dialog::backdrop {
background: linear-gradient(to right bottom, #6a11cb, #2575fc);
}
Псевдоэлемент ::backdrop позволяет стилизовать фон, который появляется за модальным окном.
По умолчанию при открытии и закрытии окна у него меняется display с none на
block. С помощью стилей можно изменить такое поведение и анимировать появление и скрытие.
Напомню, что dialog открывается с помощью разных методов: show() и showModal(). А значит, что может возникнуть необходимость разные стили в зависимости от того, какой метод был вызван. Ключевое отличие в наличии псевдокласса :modal. :modal — это нативное состояние элемента <dialog>, которое браузер автоматически добавляет только при вызове showModal(). При show() его нет.
dialog {
стили для dialog в любом случае
}
/* Состояние, когда окно открыто именно как модальное окно через showModal() */
dialog[open]:modal {
background: deeppink;
}
/* Окно открыто через show() */
dialog:not(:modal)[open] {
background: deepskyblue;
}
Для полного волшебства уберем скролл на body при dialog открытом только как модальное окно
body:has(dialog[open]:modal) {
/* Убираем прокрутку при открытом dialog только как модальное окно */
overflow: hidden;
}
Особенности
- Модальные окна «ускользают» от контекста: даже если в HTML-разметке после модального окна указан тег
divсz-index: 99999, то модальное окно всё равно отобразится поверх этогоdiv. Или если родитель наклонён с помощьюskew(), то дочернее модальное окно всё равно откроется без наклона. - Модальные окна
<dialog>, открытые методомshowModal(), не наследуют «инертность» своих предков. То есть, если на родителе был задан атрибутinertдля блокировки взаимодействия с контентом, то это не помешает работе диалога. На данный момент (2026) никакой другой элемент не обладает таким свойством.
MDN: атрибутinert -
dialog[open]— любой вариант открытия окна.
dialog[open]:modal— это нативное состояние элемента dialog, которое браузер автоматически добавляет только при вызове showModal(). При show() его нет. - У
<dialog>нельзя использовать атрибутtabindex. - При навигации с клавиатуры, при открытии
dialogфокус будет переключаться только между элементами открытого окна (потом перейдет на интерфейс браузера), то есть включается так называемая ловушка фокуса (focus lock). - Также браузер запоминает на каком элементе был фокус до открытия диалога и после закрытия возвращает его на то же место.
Popover API
Нативная, встроенная в CSS, возможность создавать всплывающие элементы (попапы, поповеры, тултипы) и управлять ими. Но это не отменяет и возможность управления через JavaScript.
Не забывайте смотреть поддержку на caniuse.com
В отличие от <dialog> в режиме модального окна, поповеры не блокируют взаимодействие с остальной страницей.
<button popovertarget="my-popover" popovertargetaction="toggle">
Open
</button>
<div id="my-popover" popover>
text
</div>
Даже такой простой код уже даст нам рабочий пример, в котором окошко будет открываться, а закрываться по клику мимо него.
Чтобы элемент стал поповером, необходимо задать ему атрибут popover и идентификатор с уникальным именем, например, id="my-popover". Элементу, который вызывает открытие поповера, нужно задать атрибут popovertarget и указать в него значение из id.
Возможно, в будущем атрибут popovertarget заменят на invoketarget. Следите за обновлением спецификации.
Закрытие popover
По умолчанию поповеры закрываются по клику мимо него, по нажатию клавиши Esc или по повторному клику на открывающий элемент (обычно кнопку) или другую кнопку с атрибутом popovertarget и соответствующим именем в нём.
<button popovertarget="my-popover" popovertargetaction="toggle">
Open
</button>
<div id="my-popover" popover>
<p>text</p>
<button popovertarget="my-popover">Close</button>
</div>
Поведение кнопки можно изменить с помощью атрибута popovertargetaction
toggle— значение по умолчанию. Переключатель состояния поповера с закрытого на открытое и обратно;show— открывает;hide— скрывает (закрывает).
В примере ниже поповер не будет закрываться по нажатию на первую кнопку:
<button popovertarget="my-popover" popovertargetaction="show">
Open
</button>
<div id="my-popover" popover>
<p>text</p>
<button popovertarget="my-popover" popovertargetaction="hide">Close</button>
</div>
Атрибут popover
В примерах выше атрибут popover указывался вообще без какого либо значения. На самом деле, при такой записи, его значение было auto. Но есть и второе значение: manual
auto— одновременно можно показать только один поповер. При этом, поповер можно скрыть при клике за его пределами.manual— можно открыть несколько поповеров одновременно. Такие поповеры не будут закрываться при клике за их пределами, а только по своей закрывающей кнопке.
See the pen (@Websitio) on CodePen.
Посмотрите, закрытие любого из manual окон приводит и к закрытию окна с auto, если такое было открыто.
Стилизация popover
По умолчанию поповеры имеют размеры по содержимому, фиксированное позиционирование в центре вьюпорта. Это поведение можно изменять при желании
[popover] {
position: fixed;
width: fit-content;
height: fit-content;
inset: 0px;
margin: auto;
border: solid;
padding: 0.25em;
}
По аналогии с <dialog> можно изменить и оверлей:
[popover]::backdrop {
background: linear-gradient(to right bottom, #6a11cb, #2575fc);
}
Анимации
Появление и скрытие поповеров можно анимировать.
Пропишем стили для уже открытого элемента
[popover]:popover-open {
opacity: 1;
translate: 0 0;
transition: translate 0.5s, opacity 0.5s, display 0.5s, overlay 0.5s;
}
В директиве @starting-style зададим стили от которых будет начинаться анимация открытия. На состояние открытого поповера указывает псевдокласс :popover-open
@starting-style {
[popover]:popover-open {
opacity: 0;
translate: 0 calc(-50vh - 50%);
}
}
И стили при закрытии окна:
[popover]:not(:popover-open) {
scale: 0;
translate: 0 0;
transition: translate 0.5s, scale 0.5s, display 0.5s allow-discrete, overlay 0.5s;
}
Для анимации всплытия элемента, в свойстве transition нужно не забыть указать анимацию для overlay.
Также мы должны анимировать и display, иначе закрытие будет мгновенным, но оно дискретно и изначально не анимируется. В некоторых браузерах можно к анимации display добавить allow-discrete, чтобы получить анимацию закрытия.
See the pen (@Websitio) on CodePen.
Взаимодействие с popover методами JavaScript
Если есть необходимость управлять окном на JavaScript, то вот доступные методы:
.togglePopover()— по аналогии с атрибутомpopoverпереключает состояния с закрытого на открытое и обратно;.showPopover()— открывает;.hidePopover()— закрывает.
document.getElementById('my-popover').showPopover();
Проверить, что поповер открыт, можно при помощи .matches(':popover-open'), .checkVisibility() или
event.newState === 'open'.
Особенности popover
Как и <dialog>, такие окна всплывают на самый верх вне зависимости от установленного z-index
Закрываются по клику мимо области элемента или по нажатию на клавишу Esc без дополнительных усилий.
При открытии срабатывает «ловушка фокуса».
Семантическая связь поповера с открывающим его элементом.
Доступность тултипов
Статья на Доке Как сделать элемент тултипом с помощью WAI-ARIA
HTML атрибут inert
Атрибут inert делает тег недоступным для скринридеров и взаимодействия с пользователем (клики, фокус, таб с клавиатуры и т.д.). С осени 2025 года имеет зеленую галочку Baseline Widely available.
Отлично подходит для того, чтобы заблокировать страницу, когда открыто модальное окно.