Нативні модальні вікна в HTML5 з допомогою елемента dialog

15

Від автора: Кожен з нас опинявся в ситуації, коли потрібно зробити відповідальний вибір, перебуваючи онлайн: оформлення замовлення, голосування, видалення облікового запису. Ці незмінні дії дуже часто потребують проміжного кроку, невеликого нагадування, яке дозволило б упевнитися в тому, що користувач дійсно хоче продовжити або завершити дію. Щоб запобігти виникненню помилок, подібні нагадування зазвичай роблять у вигляді модального вікна: елемент користувацького інтерфейсу, який перехоплює керування сторінкою і змушує користувача зробити якийсь вибір (зазвичай Так/Ні) перед продовженням.

Традиційно такі модальні вікна створювалися за допомогою JavaScript, у більшості випадків з використанням фреймворків або бібліотек. Сьогодні подібна модальна сутність має нативну (вбудовані) підтримку HTML5 (якщо бути точніше, то у версії HTML 5.1: елемент не зовсім входить в офіційну HTML5 специфікацію). Процес додавання цього нового елемента на сторінку є дуже простим:

Розмітка

Базова розмітка для нативного діалогового вікна не буде для вас чимось несподіваним:

Ви впевнені?

Ви натиснули на велику червону кнопку. Це може призвести до… чого-небудь.

Гаразд, продовжимо
Скасування

За замовчуванням браузер не повинен показувати вміст елемента до тих пір, поки воно не буде відображено за допомогою додавання атрибута open. Цей атрибут можна додати, використовуючи один з методів, про яку я збираюся розповісти далі. У якості дії, що викликає появу діалогового вікна, можуть використовуватися різні варіанти: завантаження сторінки, натискання (клік) на великій червоній кнопці або що-небудь ще. Наприклад, нехай це буде завантаження сторінки:

var dialog = document.getElementById(‘dialog’);
dialog.show();

Якщо ви спробуєте подивитися результат в одному з підтримують дану можливість браузерів (на момент написання статті це Chrome і Opera), то ви побачите, що елемент dialog розташований у самому верху вікна браузера. Ви також помітите, що ви можете взаємодіяти з контентом на сторінці (виділяти текст, активувати інші елементи інтерфейсу тощо). Це сильно відрізняється від виклику елемента dialog в якості модального вікна: змініть dialog.show() на dialog.showModal() і перезавантажте сторінку.

І хоча вміст елемента dialog ніяк не змінилося, ви побачите кілька важливих змін, притаманних API (інтерфейс додатка) showModal(): зараз вікно вже розміщується в центрі області перегляду (viewport), а інша частина сторінки затемнена і недоступна для взаємодії.

Управління і закриття

Теоретично, елемент dialog може містити будь-яку інформацію, на якій потрібно загострити увагу користувача: форма, відео або будь-який інший елемент. Одночасно може бути відкрито багато елементів dialog, але — тільки одне модальне вікно. У будь-якому випадку, вам напевно знадобиться елемент користувацького інтерфейсу, який буде закривати подібні вікна. Для цього ми можемо використовувати створену раніше кнопку «Скасувати»:

document.getElementById(«cancel»).onclick = function() {
dialog.close();
}

У демо-прикладі до даної статті обидві кнопки закривають діалогове вікно, але більше нічого не роблять. Щоб це виправити, їм потрібно передавати дані. А про це я розповім вже в іншій статті.

Оформлення

Елемент dialog можна оформляти з допомогою звичайного CSS:

dialog { font-family: Avenir, sans-serif; width: 25%; text-align: center; border: 3px solid; }
dialog div { display: flex; justify-content: space between; }

Додатково, API showModal() створює новий псевдо-елемент ::backdrop, який за замовчуванням закриває всю область перегляду і може бути оформлений окремо:

dialog::backdrop { background: rgba(0,0,0,0.9); }

На практиці, модальні діалогові вікна розглядаються, як проміжний крок на шляху до полноэкранному API: подібно полноэкранному контенту модальні діалогові вікна захоплюють управління областю перегляду, але в теж час вони необов’язково повинні викликатися користувачем. Модальні діалогові вікна можуть викликатися і при завантаженні сторінки, а ось повноекранний контент — ні.

Важливо відзначити, що вікно елемента dialog з’являється на самому верхньому рівні (шарі) області перегляду. Це означає, що ніяке значення властивості z-index не здатне помістити інший елемент поверх елемента dialog. Це також означає, що розташування (позиціонування) елемента dialog не буде успадковано від жодного батьківського елемента. Для безпосереднього вирівнювання даного елемента було запропоновано CSS властивість anchor-point, але поки що воно не має браузерної підтримки і не працює навіть з використанням полифилла (polyfill).

Підтримка

Елемент dialog досі не має гарної кросбраузерною підтримки: він підтримується тільки в Chrome 37+ і Opera 24+ на десктопних і мобільних пристроях, хоча, безсумнівно, інші браузери до них приєднаються. Тим часом у Google є чудовий діалоговий полифилл, який не прив’язаний до якогось фреймворку і працює шляхом вставки декількох додавань у ваш CSS.

Незалежно від того, чи використовуєте ви полифилл чи ні, браузерне визначення можливостей орієнтована на підхід, який використовується в багатьох тестах підтримки можливостей: створення елемента за допомогою JavaScript і перевірка на додавання до нього значення атрибута.

var testdialog=document.createElement(«dialog»);
testdialog.setAttribute(«open», «»);
if (testdialog.open==true){
// браузер підтримує елемент dialog
} else {
// браузер не підтримує даний елемент, тобто потрібно завантажити полифилл
}

По мірі того, як поліпшується підтримка елемента , має сенс вже зараз перейти на використання нативного елемента замість рішень, узятих з фреймворків. Це особливо актуально, якщо врахувати серйозну підтримку даних форм у даного елемента, про яку я поговорю в іншій статті.

Подивіться демо-приклад на CodePen