dialog
Маркира контейнер като модален или немодален диалог. Препоръчва се използването на нативния елемент <dialog> с showModal() — той осигурява захващане на фокуса, горния слой, фоновото покритие и затваряне с Escape без допълнителен код. Прибягвайте до role="dialog" само когато нативният елемент е невъзможен.
Кога да се използва
Препоръчва се използването на <dialog>, отворен чрез .showModal(). Нативният елемент е поддържан от всички актуални браузъри, управлява неактивния фон, захващането на фокуса, затварянето с Escape, кукичката за стилизиране на ::backdrop и рендирането в горния слой. Спестява приблизително 200 реда нестабилен JavaScript.
Прибягвайте до role="dialog" на <div> само когато:
- Поддържате браузъри по-стари от Chrome 37 / Firefox 98 / Safari 15.4 (малко вероятно през 2026 г.).
- Дизайнът изисква диалог, който не може да се помести в горния слой (рядко).
- Поправяте недостъпен персонализиран модален прозорец по време на рефакторинг.
Всеки диалог ТРЯБВА да има достъпно наименование (препоръчителен модел е aria-labelledby, сочещ към видим заглавен ред). Модалните диалози трябва да имат и aria-modal="true".
Договор за клавиатура и фокус
Съгласно APG модела за диалог (модален):
- При отваряне фокусът се премества върху първия фокусируем елемент вътре в диалога (обикновено бутона за затваряне или основното поле за въвеждане).
- Tab и Shift+Tab преместват фокуса САМО В рамките на диалога — „захващане на фокуса”. Tab от последния елемент се връща към първия; Shift+Tab от първия — към последния.
- Escape затваря диалога.
- При затваряне фокусът се връща на елемента, отворил диалога. Запазването и възстановяването на фокуса е задължително — потребителите, изгубили местоположението си, нямат опорна точка.
- Останалата страница е
inert(илиaria-hidden="true"плюс нефокусируема като алтернатива), докато диалогът е отворен.
Чести грешки
- Персонализиран диалог без захващане на фокуса. Tab излиза от диалога и попада зад него; потребителите губят контекст.
- Фокусът не се връща към тригера при затваряне. Следващото Tab попада върху тялото на документа.
- Фоновото съдържание остава фокусируемо чрез Tab, въпреки че е визуално скрито зад диалога.
- Липсва достъпно наименование. Диалогът се отваря и екранният четец обявява само „dialog”.
- Персонализиран диалог без
aria-modal="true"— помощните технологии го третират като вградено съдържание. - Escape затваря диалога, но диалогът е рендиран чрез портал, който губи клавиатурния фокус по време на анимацията на затваряне.
Пример
<!-- Препоръчително -->
<dialog id="confirm">
<h2>Delete this draft?</h2>
<p>This cannot be undone.</p>
<form method="dialog">
<button value="cancel">Cancel</button>
<button value="delete" autofocus>Delete</button>
</form>
</dialog>
<script>
document.getElementById('confirm').showModal();
</script>
<!-- Когато <dialog> е невъзможен -->
<div role="dialog" aria-modal="true" aria-labelledby="dlgTitle">
<h2 id="dlgTitle">Edit profile</h2>
…
</div>