Лучше решать другим способом задачу (не перекрывая экрана) в случаях, если
- требуется вывести ошибку (можно использовать всплывающую панель или подсказку у поля ввода)
- показывать прогресс загрузки, статус ожидания/завершения (лучше на том же элементе, на котором совершали action приведший к ожиданию)
- возникает желание вывести модалку поверх модалки
Раздражают те окна, которые пользователь не вызывал сам (стремится их сразу же закрыть).
- У модального окна, как у любой обычной страницы, должен быть свой заголовок. Короткий, точно описывающий его предназначение.
<dialog aria-labeledby="subscribe-header">
<h2 id="subscribe-header">Предложение подписки</h2>
</dialog>
- Не должно быть скроллируемым (можно давать ссылку на подробности, либо скрывать их в раскрывающийся контент)
- Страница под окном не должна прокручиваться
- Количество кнопок не более двух, одна из них "предпочтительная". Название кнопок должно быть в виде глагола.
- Должна присутствовать явно кнопка "закрыть" в правом верхнем углу окна (если нет возможности считать пользовательские настройки интерфейса на этот счёт). Можно её дублировать кнопкой "отмена", если подразумевается и кнопка "предпочтительного" действия, иначе подписывать как "закрыть".
- Кнопка закрыть не должна попадать на внутреннее информационное содержимое окна, иначе будет неочевидно, какой элемент интерфейса будет скрыт. Обычно визуально явно отделяют заголовок окна.
- Функционал для автозакрытия окна при клике вне его.
- Окно должно быть выделено от основного интерфейса (например затемнением оного).
Идеальный размер окна не более 25% площади экрана в случае desktop или 100% в случае mobile.
- На первый интерактивный элемент окна должен быть переведён фокус для работы кнопки Tab. WCAG 2.1.2 Именно так ведет себя нативный в браузере. Но нельзя делать сам элемент окна фокусируемым и перемещать фокус на него.
- Если диалог запрашивает у пользователя подтверждение перед выполнением каких-то необратимых действий (удаление чего-то или выполнение финансовых операций), тогда фокус автоматически должен ставится на кнопку "отмены" этих действий, независимо от её расположения. При этом "предпочитаемое" действие всё равно второе (и окраска тоже на второй кнопке).
- По кнопке Esc окно должно закрываться.
- При закрытии диалогового окна фокус должен быть перемещён туда, где он был в момент открытия. Если элемент более не доступен, тогда фокус нужно вернуть туда, откуда наиболее логично для пользователя продолжить работу.
-
Если в браузере есть фиксированный скроллбар (который влияет на ширину страницы), то при открытии/закрытии окна происходит сдвиг контента, когда полоса прокрутки то появляется то пропадает. Необходимо компенсировать пространство полосы прокрутки. Подключенная к touch-устройству мышь влияет на отображение полосы прокрутки!
-
Открытие попапа из нижней части страницы может привести к прокрутке всей страницы до верха на заднем фоне! Это поведение следует исключить.
-
Идемпотентность. В идеальном мире повторяющиеся операции "открыть > закрыть > открыть" должны приводить к одному и тому же результату.
-
Проверить, как работает поиск по странице (ищет ли под модалкой).
-
Проверить, как отображаются открытые списки combobox'ов основного интерфейса при открытом окне (не должны перекрывать его).
-
Проверить как работает в браузере кнопка Back, закрывает ли окно или переходит на предыдущую страницу.
-
Для различных диалогов, уведомлений и прочих перекрывающих документ элементов существует тег
<dialog>
, к нему существуют полезные aria-атрибуты.- Having an open
<dialog>
scottohara.me - caniuse
<dialog>
- WAI-ARIA Dialog (Modal) Pattern
- Реализации модальных окон в Vue habr
- Having an open
WAI-ARIA pattern по модалкам
Focus-trap в модалке.