Создание модальных и всплывающих окон с помощью элемента HTML5 “dialog”
На сегодняшний день в Интернете для выполнения многих действий требуется получение подтверждения от пользователя. Например, когда пользователям нужно удалить учетную запись, изменить логин или подтвердить денежный перевод.
В таких случаях чаще всего используется диалоговое окно с двумя кнопками: одна для отмены действия, вторая - для подтверждения. В течение многих лет мы использовали для этого библиотеки JavaScript. Но в этой статье мы попробуем сделать это с помощью экспериментального тега <dialog>.
Применение элемента dialog
<dialog> является элементом HTML5. Он классифицируется как "корневой элемент секционирования", подобный <body>, и <details>, каждый из которых устанавливает новый раздел контента. Вы можете использовать его как дочерний элемент <body>, или вложить его в такие элементы, как <div> или <section>:
<body>
<div>
<dialog></dialog>
</div>
<section>
<dialog></dialog>
</section>
<dialog></dialog>
</body>
Поддерживающие браузеры (Chrome 37+ и Opera 27+) выводят элемент <dialog> по умолчанию скрытым. Он становится видимым только по запросу с использованием методов JavaScript show() или showModal(), метод close() снова скрывает элемент. Как правило, мы запускаем эти методы внутри события click, например, следующим образом:
var $accountDelete = $('#delete-account'),
$accountDeleteDialog = $('#confirm-delete');
$accountDelete.on('click', function() {
$accountDeleteDialog[0].showModal();
});
$('#cancel').on('click', function() {
$accountDeleteDialog[0].close();
});
Метод show() против метода showModal()
Стоит отметить, что методы show() и showModal() характеризуются различным поведением.
Метод show() выводит элемент в соответствии с его положением внутри DOM. Если вы добавили его непосредственно перед закрывающимся тегом </body>, то он появится в нижней части страницы. Нам нужно добавить собственные стили, чтобы настроить его размещение, например, если мы хотим поместить его в центре страницы. Для этого используют свойство z-index, чтобы вывести элемент поверх других элементов; для свойства position устанавливаются значения absolute, left и top.
Посмотреть пример
Метод showModal(), в свою очередь, будет отображать элемент в виде модального окна. Оно будет отображаться в центре страницы по умолчанию и располагаться в верхнем слое, что решает проблему z-index, связанную с положением и перекрытием родительским элементом.
Посмотреть пример
В большинстве случаев удобнее использовать метод showModal(), а не show().
Настройка стилей
Диалоговое окно имеет стили браузера по умолчанию, которые можно легко переопределить. Вы можете, например, сделать рамку диалогового окна более тонкой, скруглить углы, а также добавить тень.
Когда элемент <dialog> выводится в виде модального окна (с помощью метода showModal()), у нас в распоряжении есть дополнительный псевдоэлемент ::backdrop. Он располагается непосредственно под диалоговым окном, и перекрывает всю видимую часть экрана и все элементы под ним.
Общим стилем для него является фон темного цвета с низкой прозрачностью - кликните красную кнопку в приведенном ниже примере, чтобы увидеть его в действии:
Посмотреть пример
Добавление перехода
Давайте добавим переход, чтобы диалоговое окно открывалось постепенно, с помощью эффекта масштабирования.
Шаг 1
Сначала мы уменьшим окно на 90%, укажем переход и сделаем окно скрытым:
dialog {
visibility: hidden;
transform: scale(0.1);
transition: transform 200ms;
}
Шаг 2
Определим селектор класса, который будет масштабировать окно до предполагаемого размера и делать его видимым:
dialog.dialog-scale {
visibility: visible;
transform: scale(1);
}
Шаг 3
Хитрость заключается в том, что мы будем "удерживать" диалоговое окно в уменьшенном размере в течение нескольких миллисекунд, прежде чем добавим класс dialog-scale. Чтобы достичь этого, мы используем для добавления класса метод JavaScript setTimeout():
var transition;
$accountDelete.on('click', function() {
$accountDeleteDialog[0].showModal();
transition = setTimeout(function() {
$accountDeleteDialog.addClass('dialog-scale');
}, 0.5);
});
Шаг 4
Не забудем удалить этот класс и очистить значение задержки, когда диалоговое окно закрыто:
$('#cancel').on('click', function() {
$accountDeleteDialog[0].close();
$accountDeleteDialog.removeClass('dialog-scale');
clearTimeout(transition);
});
Результат вы можете увидеть в приведенном ниже примере:
Посмотреть пример
Заключение
Элемент <dialog> действительно удобен в применении, хотя он слабо поддерживается браузерами. Если в большинстве популярных браузеров будет реализована его поддержка, то мы будем меньше зависеть от библиотек, и появится легкий и удобный способ создания модальных диалоговых окон:

До тех же пор вы можете использовать решение от Google Chrome, чтобы имитировать этот элемент в браузерах, которые его не поддерживают.