Перейти к содержанию

Dialog

Элемент dialog - это полезный элемент для представления любого вида диалога в HTML, узнайте, как он работает.

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

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

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

Модальные диалоги

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

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

1
2
3
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, который можно использовать для отключения элемента и всех его потомков, кроме активного диалога. При открытии модального диалога с помощью openModal() инертность или деактивация происходит бесплатно, атрибут не задается явно.

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

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

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

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

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

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

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

1
2
3
4
5
<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.

При открытии диалога присутствует атрибут boolean open, означающий, что диалог активен и с ним можно взаимодействовать. Если диалог открывается не через .show() или .showModal(), а добавлением атрибута open, то он будет безмодальным. Свойство 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; в своих таблицах стилей user-agent. Свойство color наследуется от dialog, а не от body или :root, что может быть неожиданным. Свойство background-color не наследуется.

Источник: Dialog

Комментарии