Модальное окно: dialog
Модальное окно — окно поверх страницы, которое затемняет всё остальное и ждёт ответа: подтвердить действие, заполнить короткую форму. В HTML для него есть тег <dialog>, и браузер сам умеет его открывать и закрывать. Pico добавляет затемнение фона и оформляет содержимое как карточку.
Разметка окна
Внутри <dialog> кладут <article> — карточку из прошлых уроков. Кнопка с rel="prev" в шапке карточки превращается в крестик закрытия:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
<div style="min-height: 280px"></div>
<dialog open>
<article>
<header>
<form method="dialog">
<button aria-label="Закрыть" rel="prev"></button>
</form>
<p><strong>Спасибо за подписку!</strong></p>
</header>
<p>Новые записи блога будут приходить по пятницам.</p>
</article>
</dialog>Окно открыто сразу благодаря атрибуту open: фон затемнён, по центру карточка с заголовком и крестиком. Щёлкните крестик — окно закроется. Кнопка внутри <form method="dialog"> закрывает свой <dialog> без единой строки JavaScript. Пустой блок с min-height даёт окну место в превью.
Открытие по кнопке
Обычно окно скрыто, а открывает его скрипт методом showModal(). Закрывает метод close(), а также клавиша Escape:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
<div style="min-height: 300px">
<button id="open-contact">Написать мне</button>
</div>
<dialog id="contact">
<article>
<header>
<button aria-label="Закрыть" rel="prev" data-close></button>
<p><strong>Связаться с Анной</strong></p>
</header>
<label for="reply">Ваш email</label>
<input type="email" id="reply">
<footer>
<button class="secondary" data-close>Отмена</button>
<button data-close>Отправить</button>
</footer>
</article>
</dialog>
<script>
const dialog = document.querySelector('#contact');
document.querySelector('#open-contact').addEventListener('click', () => dialog.showModal());
dialog.querySelectorAll('[data-close]').forEach((button) => {
button.addEventListener('click', () => dialog.close());
});
dialog.addEventListener('close', () => console.log('Окно закрыто'));
</script>Нажмите «Написать мне» — откроется окно с полем email и двумя кнопками в подвале. Любая из трёх кнопок или Escape закрывает его, и под примером появляется «Окно закрыто»: событие close срабатывает при любом способе закрытия.
Что за что отвечает
| Часть | Задача |
|---|---|
<dialog> | Затемнённый слой во весь экран |
<article> | Сама карточка окна |
<header> с rel="prev" | Заголовок и крестик |
<footer> | Кнопки действий, выровненные вправо |
showModal() и close() | Открыть и закрыть из скрипта |
Метод showModal() ещё и удерживает фокус внутри окна: клавиша Tab не уйдёт к ссылкам страницы под затемнением.
Частая ошибка
Открывать окно, просто добавляя атрибут open из скрипта. Окно появится, но браузер не будет считать его модальным: Escape не закроет его, а Tab уведёт фокус на страницу под ним. Для окон, которые ждут ответа, используйте showModal().