Диалог

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

Диалоги могут быть либо модальными (взаимодействовать можно только с содержимым диалога), либо немодальными (все еще возможно взаимодействовать с содержимым вне диалога). Модальные диалоги отображаются поверх остального содержимого страницы. Остальная часть страницы инертна и по умолчанию скрыта полупрозрачным фоном.

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

Вот пример модального <dialog> . Откройте диалог кнопкой «Открыть модальный диалог». После открытия есть три способа закрыть диалоговое окно: клавиша escape, отправка формы с помощью кнопки, у которой установлен formmethod="dialog" (или если в самой форме установлен method="dialog" ) и HTMLDialogElement.close() метод 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 не закрывает немодальные диалоговые окна. По этой причине еще более важно убедиться, что вы включили метод закрытия немодального диалогового окна. При этом, если ближе находится за пределами диалогового окна, следует понимать, что фокус перейдет на элемент, открывший диалоговое окно, что может быть не лучшим пользовательским интерфейсом.

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

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

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

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

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

Возможно, вы заметили атрибут autofocus , установленный для <button> закрытия в этом примере. Элементы с атрибутом 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 в само диалоговое окно.

роли АРИИ

Неявная роль – 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 .
Попробуйте еще раз.