Диалоговое окно

Модальное диалоговое окно – это особый тип всплывающего окна, которое прерывает действия пользователя на веб-странице. Хотя есть некоторые допустимые варианты использования всплывающих диалоговых окон, вам следует тщательно подумать, прежде чем добавлять их. Модальные диалоговые окна заставляют пользователей сосредоточиться на определенном контенте и временно игнорировать остальную часть страницы.

Диалоговые окна могут быть:

  • Модальное. Пользователи могут взаимодействовать только с контентом в диалоговом окне. Модальные диалоговые окна показываются поверх контента страницы. Страница становится инертной и по умолчанию скрывается за полупрозрачным фоном.
  • Немодальные. Пользователи могут взаимодействовать с контентом за пределами диалогового окна.

Семантический элемент HTML <dialog> для создания диалогового окна включает семантику, взаимодействие с клавиатурой и все свойства и методы интерфейса HTMLDialogElement.

Посмотрите на пример модального окна <dialog>. Нажмите Открыть модальное диалоговое окно. После открытия диалогового окна его можно закрыть тремя способами: нажав клавишу Esc, отправив форму с помощью кнопки с атрибутом formmethod="dialog" (или если у самой формы есть атрибут method="dialog") и с помощью метода HTMLDialogElement.close().

У класса HTMLDialogElement есть три основных метода, а также все методы, унаследованные от HTMLElement.

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

Поскольку этот объект <dialog> был открыт с помощью метода HTMLDialogElement.showModal(), он является модальным диалоговым окном. При открытии модального диалогового окна все остальные элементы становятся неактивными и скрываются. Когда вы наводите указатель мыши на интерфейс за пределами диалогового окна, все элементы ведут себя так, как если бы было установлено значение pointer-events: none;. Даже кнопка, открывающая диалоговое окно, не будет реагировать на взаимодействия.

Когда диалоговое окно открыто, фокус перемещается в него. Фокус устанавливается на первом элементе в последовательном порядке навигации с клавиатуры в этом диалоговом окне. Если вы будете нажимать клавишу tab, фокус будет перемещаться только по элементам диалогового окна. Все, что находится за пределами модального окна, остается инертным.

Когда диалоговое окно закрывается, фокус возвращается к элементу, который его открыл. Не открывайте диалоговое окно программно без действия пользователя. Если это необходимо, убедитесь, что вы возвращаете фокус туда, где он был до открытия диалогового окна, особенно если пользователь закрывает диалоговое окно, не взаимодействуя с ним.

Существует глобальный атрибут inert, который можно использовать для отключения элемента и всех его потомков, кроме активного диалогового окна. Когда модальное диалоговое окно открывается с помощью showModal(), инертность или деактивация происходит по умолчанию. Атрибут не задан явным образом.

Фон, который скрывает все, кроме диалогового окна, можно стилизовать с помощью псевдоэлемента ::backdrop. Фон отображается только тогда, когда <dialog> отображается с помощью метода .showModal(). Этот псевдоэлемент соответствует всем фонам, включая тот, который отображается при использовании FullScreen API, например при просмотре видео в полноэкранном режиме, соотношение сторон которого не совпадает с соотношением сторон экрана или монитора.

Немодальные диалоговые окна

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

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

Закрытие диалогового окна

Для закрытия диалогового окна метод HTMLDialogElement.close() не требуется. JavaScript вам вообще не нужен. Чтобы закрыть <dialog> без JavaScript, добавьте форму с методом dialog, задав method="dialog" в <form> или formmethod="dialog" в кнопке.

Когда пользователь отправляет данные с помощью метода dialog, состояние введенных им данных сохраняется. При отправке формы выполняется проверка ограничений (если не задан атрибут novalidate). Пользовательские данные не удаляются и не отправляются. Вы можете создать кнопку закрытия без JavaScript:

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

Возможно, вы заметили, что в этом примере для закрывающего тега <button> задан атрибут autofocus. Элементы с атрибутом autofocus, заданным в <dialog>, получают фокус при загрузке страницы, только если она уже была загружена с видимым диалоговым окном. Если страница не загружена, фокус переходит на эти элементы при открытии диалогового окна.

Когда диалоговое окно открывается, фокус получает первый элемент, который может его получить, если только для другого элемента не задан атрибут autofocus. Атрибут autofocus, заданный для кнопки закрытия, гарантирует, что она будет в фокусе при открытии диалогового окна. Однако добавлять autofocus в <dialog> следует только после тщательного анализа. Все элементы в последовательности, предшествующие элементу с автоматической фокусировкой, пропускаются. Подробнее об этом атрибуте рассказывается в модуле, посвященном фокусу.

Интерфейс HTMLDialogElement включает свойство returnValue. При отправке формы с method="dialog" для returnValue задается name кнопки, которая использовалась для отправки формы. Если бы мы написали <button type="submit" name="toasty">close</button>, то returnValue было бы равно toasty.

Когда диалоговое окно открыто, присутствует логический атрибут open, который означает, что диалоговое окно активно и с ним можно взаимодействовать. Если диалоговое окно открывается с помощью атрибута open, а не .show() или .showModal(), оно не является модальным. Свойство HTMLDialogElement.open возвращает true или false в зависимости от того, доступно ли диалоговое окно для взаимодействия, а не от того, является ли оно модальным.

Хотя JavaScript является предпочтительным методом открытия диалогового окна, включение атрибута open при загрузке страницы и последующее его удаление с помощью .close() может помочь обеспечить доступность диалогового окна, даже если JavaScript недоступен.

Дополнительные сведения

Не использовать tabindex

Элемент, который активируется для открытия диалогового окна, и кнопка закрытия в нем (и, возможно, другой контент) могут получать фокус и являются интерактивными. Элемент <dialog> не является интерактивным и не получает фокус. Не добавляйте свойство tabindex в сам диалог.

Роли ARIA

Неявная роль – dialog. Если диалоговое окно является окном подтверждения, которое передает сообщение, требующее ответа или подтверждения пользователя, задайте role="alertdialog". Добавьте доступное название для диалогового окна. Если видимый текст может служить доступным названием, добавьте aria-labelledby="idOfLabelingText".

Стандартные настройки CSS

Браузеры предоставляют стиль по умолчанию для dialog. Firefox, Chrome и Edge устанавливают color: CanvasText; и background-color: Canvas;. Safari устанавливает для color: black; background-color: white; в таблицах стилей агента пользователя. Значение color наследуется от dialog, а не от body или :root, что может быть неожиданным. Свойство background-color не наследуется.

Проверьте себя

Проверьте свои знания об элементе диалога.

Как стилизовать область за диалоговым окном?

С помощью псевдоэлемента ::background.
Повторите попытку.
С помощью псевдоэлемента ::backdrop.
Верно!
со свойством background.
Повторите попытку.