Раскрывающиеся блоки и диалоги
Часть интерфейса нужна не всё время: ответ на вопрос, подробности заказа, окно подтверждения. Раньше такие элементы писали целиком на JavaScript. Сейчас в HTML есть готовые теги, которые сами раскрываются, закрываются и работают с клавиатуры.
Раскрывающийся блок
<details> прячет содержимое, а <summary> — видимый заголовок, по которому щёлкают:
<details>
<summary>Сколько идёт доставка?</summary>
<p>По городу — один день, по стране — до пяти дней.</p>
</details>Щёлкните по вопросу — ответ появится, щёлкните ещё раз — скроется. Треугольник слева браузер рисует сам.
Открыт заранее
Логический атрибут open показывает блок раскрытым с самого начала. Несколько блоков подряд превращаются в список вопросов и ответов:
<details open>
<summary>Можно ли вернуть товар?</summary>
<p>Да, в течение 30 дней.</p>
</details>
<details>
<summary>Есть ли самовывоз?</summary>
<p>Да, из кофейни на Рыночной улице.</p>
</details>Аккордеон
Если дать нескольким <details> одинаковый атрибут name, открытым может быть только один: при открытии другого предыдущий закроется. Такой виджет называют аккордеоном:
<details name="faq" open>
<summary>Оплата</summary>
<p>Картой или наличными.</p>
</details>
<details name="faq">
<summary>Доставка</summary>
<p>Курьером или в пункт выдачи.</p>
</details>Атрибут name у <details> появился в браузерах в 2024 году. Старый браузер его проигнорирует, и блоки будут открываться независимо.
Модальное окно
<dialog> — диалоговое окно. Модальное окно появляется поверх страницы и блокирует её, пока его не закроют. Открывают его из JavaScript методом showModal():
<style>
body { min-height: 200px; } /* место для окна в превью */
</style>
<button onclick="document.querySelector('#hello').showModal()">Открыть окно</button>
<dialog id="hello">
<p>Привет! Это модальное окно.</p>
<form method="dialog">
<button>Закрыть</button>
</form>
</dialog>Окно встало по центру, а страницу под ним закрыл полупрозрачный фон. Закрыть его можно кнопкой или клавишей Esc.
Закрытие через форму
Форма с method="dialog" внутри <dialog> ничего не отправляет на сервер — она просто закрывает окно. Удобно для подтверждений:
<style>
body { min-height: 200px; } /* место для окна в превью */
</style>
<button onclick="document.querySelector('#confirm').showModal()">Удалить заказ</button>
<dialog id="confirm">
<p>Удалить заказ №42?</p>
<form method="dialog">
<button value="no">Отмена</button>
<button value="yes">Удалить</button>
</form>
</dialog>value нажатой кнопки сохраняется в свойстве окна returnValue — по нему скрипт узнает ответ пользователя.
Всплывающий блок без JavaScript
Атрибут popover превращает любой элемент во всплывающий блок, а кнопка с popovertarget открывает и закрывает его — без строчки кода:
<style>
body { min-height: 200px; } /* место для окна в превью */
</style>
<button popovertarget="tip">Что такое раф?</button>
<div id="tip" popover>
Раф — кофе со сливками и ванильным сахаром, взбитый паром.
</div>Щелчок мимо блока или Esc его закрывает. Атрибут popover поддерживается во всех основных браузерах с 2024 года. Как плавно анимировать открытие и закрытие окон, рассказано в уроке «Анимация появления и исчезновения».
Частая ошибка
У <dialog> тоже есть атрибут open, но окно, открытое им, не модальное: оно встаёт прямо в поток страницы, без затемнения фона, а Esc его не закрывает:
<dialog open>
<p>Я открыт атрибутом open — это не модальное окно.</p>
</dialog>
<p>Текст страницы остаётся доступным.</p>Для настоящего модального окна вызывайте showModal().