Создание модальных и всплывающих окон с помощью элемента 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, чтобы имитировать этот элемент в браузерах, которые его не поддерживают.

Вадим Дворниковавтор-переводчик статьи «Active Pop ps and Modes With the HTML5 “dialog” Elements»