Элемент dialog в HTML является пока еще экспериментальной технологией, хотя и с очень хорошей поддержкой браузерами, и  предназначен для отображения диалоговых  (всплывающих) или модальных окон.

MDN описывает его как диалоговое окно или другой интерактивный компонент, например, закрываемое предупреждение, инспектор или подокно. Элемент <dialog> является семантическим элементом в HTML. Он имеет атрибут open, который показывает браузеру, что модальное окно активно, т.е. должно быть показано. Кроме того, <dialog> имеет методы и свойства, позволяющие его показывать и прятать.

Итак, тег <dialog> создаёт диалоговое окно. По умолчанию не показывается на странице (работает свойство display: none) и может открываться в двух режимах:

  1. Всплывающее окно — не блокирует взаимодействие со страницей и не имеет перекрывающего фона-подложки.
  2. Модальное окно — откроется поверх страницы, имеет фоновое затемнение, остальной контент не доступен для взаимодействия.

Кстати,  тег <dialog></dialog> обязательно должен быть парным по спецификации, т.е. иметь закрывающий тег. Внутри него находится содержимое диалогового  окна с произвольной разметкой, в которой можно использовать заголовки, абзацы, div, img и формы. Для элемента <dialog> нельзя задавать атрибут tabindex.

В примере ниже вы сразу увидите открытое всплывающее окно, т.к. у него в разметке прописан атрибут open. Однако у вас не получится закрыть его нажатием на клавишу ESC, да и задний фон-подложку, перекрывающий остальные элементы, вы в этом случае не увидите. Закрыть окно можно только кликом на кнопку внутри этого диалогового окна.

See the Pen HTML 5.2 dialog element by Elen (@ambassador) on CodePen.

Второе окно открывается методом showModal() с помощью JavaScript-кода. И здесь уже присутствует фон, созданный с помощью псевдоэлемента ::backdrop. Закрывается окно нажатием ESC (предустановленное поведение) или кликом в любом месте, что уже сделано за счет JavaScript.

Стиль модального окна для элемента <dialog>

Итак, для нашего модального окна,  созданного с помощью элемента <dialog>, можно задавать любые стили в виде padding, border, width (max-width, min-width), height (max-height, min-height), color, line-height и т.д. По умолчанию в браузере Chrome прописаны такие стили:

При открытии диалогового окна стили меняются:

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

Те свойства, которые вы хотите изменить, вам нужно будет задать в стилях самостоятельно.

Кроме того, мы можем стилизовать для диалога псевдоэлемент ::backdrop (подложка), хотя браузеры применяют почти прозрачный серый фон по умолчанию (можно посмотреть на него в примере с заполнением формы):

Вы можете написать в своих стилях:

Плюс использовать анимацию типа animation и @keyframes (пример выше) . Для использования свойства transition придется изменить display: none/block на visibility: hidden/visible при закрытом и открытом диалоговом окне.

Использование JavaScript

Методы элемента <dialog>

  1. show() - открывает всплывающее окно,  добавляет атрибуты open и aria-modal="false". В этом случае окно является диалоговым, или всплывающим, но не перекрывает контент (он доступен для взаимодействия ().
  2. showModal() - позволяет открыть диалоговое окно, причем с отображением заднего фона (доступен для стилизации псевдоэлемент ::backdrop) плюс можно использовать клавишу ESC для закрытия этого диалогового окна. В этом случае <dialog> открывается в режиме «модального окна». К нему добавляются атрибуты open и aria-modal="true"
  3. close() - позволяет закрыть диалоговое или модальное окно.

События:

  1. close - наступает при закрытии диалогового окна.
  2. cancel - событие, которое наступает при нажатии кнопки ESC.
Имейте ввиду, что по нажатию Esc сначала запускается событие cancel, а затем событие close. Это может быть полезно, если мы хотим избавить пользователя от случайного нажатия клавиши ESC , сначала предупредив, что изменённые данные не сохранятся, и только при повторном нажатии закрывать окно.
Если вам зачем-то нужно отключить закрытие диалогового окна клавишей ESC, то вам поможет такой код:

Блокируем прокрутку в body при открытии <dialog>

Давайте используем открытие модального окна для того чтобы отменить прокрутку внутри body, которая есть почти во всех примерах в этой статье. Мы будем добавлять класс modal-open для body при клике на кнопку, которая открывает диалоговое окно:

Нам нужно добавить стиль, фиксирующий ширину прокрутки для html и body, а в классе modal-open у нас будет одно правило:

Затем мы будем убирать этот класс при обработке события close для диалогового окна:

Давайте посмотрим, как работает это на практике:

See the Pen HTML element dialog by Elen (@ambassador) on CodePen.

Свойство returnValue

Свойство returnValue позволяет нам задать некую реакцию после действий по закрытию диалогового окна в виде элемента <diallog>. Если кнопкам в форме задать атрибут value, то при закрытии диалога это значение будет присваиваться в dialog.returnValue.

Пример использования свойства returnValue

See the Pen HTML element dialog by Elen (@ambassador) on CodePen.

И второй пример со слегка изменённым кодом:

See the Pen HTML element dialog by Elen (@ambassador) on CodePen.

Формы внутри элемента <dialog>

Элементы <form> могут интегрироваться с диалогом с помощью добавления к ним атрибута method="dialog". Когда отправляется такая форма, то диалоговое окно закрывается с returnValue, равным value нажатой кнопки типа submit. Напомню, что в случае использования тега <button> внутри тега <form> атрибут type="submit" автоматически присваивается тегу <button>.

Мы уже использовали такой подход для получения value из кнопок в примере выше. Давайте посмотрим что мы можем сделать при добавлении в модальное диалоговое окно формы для входа на сайт.

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

See the Pen Simple Login Form Template by Elen (@ambassador) on CodePen.

Закрываем диалоговое окно по клику на псевдоэлемент ::backdrop

Для того чтобы не писать код закрытия окна при клике на кнопки, поместите их в тег <form method="dialog"></form>. Для того чтобы закрыть окно при клике на ::backdrop, нужно обработать клик по самому элементу <dialog>, т.к. по псевдоэлементу клик обработать не удастся. Для того чтобы клик по отступам вокруг текста в диалоговом окне не приводил к его закрытию, нужно убрать padding вокруг текста внутри элемента <dialog> , обернуть весь текст внутри <dialog> в какой-нибудь контейнер, для которого нужно задать padding, и дописать код на JavaScript, который проверяет, где был сделан клик.

В этом коде нужно понимать, что является target и currentTarget при клике на элементе в процессе делегирования событий. target - это целевой объект под курсором мыши. При наличии текста в диалоговом окне вы будете кликать то по заголовку, то по абзацу, то по кнопкам, то по div-у-обертке, но не по самому элементу <dialog>. И только при клике на ::backdrop вы будете кликать по элементу <dialog>. В этом случае target совпадет с currentTarget , и модальное окно будет закрыто.

See the Pen Click Dialog Backdrop by Elen (@ambassador) on CodePen.

Примерно такой же по сути код вы найдете в  первом примере.

Аспекты доступности элемента <dialog>

Чтобы обеспечить доступность вашего модального окна в виде элемента <dialog>, вы уже получаете фокус на первом интерактивном элементе после открытия диалогового окна помощью метода dialog.showModal(). Взаимодействие с другим содержимым на странице будет заблокировано, пока диалоговое окно активно, без вашего участия, т.е. какого-либо кода. Кроме того, диалоговое окно закрывается нажатием клавиши ESC. Все это идет «бесплатно» вместе с элементом <dialog>.

В отличие от использования элемента divв качестве оболочки вместо семантически правильного элемента <dialog>, вам не обязательно добавлять такие атрибуты, как role="dialog" и aria-modal="true.

Вы также можете добавить следующие атрибуты:

  • Поместите метку на элемент диалога — например, <dialog aria-label="Вы готовы принять участие в проекте?"> или используйте aria-labelledby="dialog_title", если вы хотите сослаться на идентификатор другого элемента внутри разметки диалога, который  представляет заголовок.
  • Если диалоговое сообщение требует дополнительной информации, которая уже может быть видна внутри диалогового окна, вы можете дополнительно сослаться на этот текст в атрибуте aria-describedby или сформулировать описание только для программ чтения с экрана внутри сообщения.aria-description
  • Добавьте полифилл для поддержки старых браузеров строкой import "dialogPolyfill from "https://cdn.skypack.dev/dialog-polyfill@0.5.6";.

Пример:

See the Pen Click Dialog Backdrop by Elen (@ambassador) on CodePen.

Другие способы создания модальных окон (CSS, JS, Bootstrap, плагины) вы найдете в отдельной статье.

Автор: Админ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *