Как сделать модальное окно на HTML dialog: фокус и закрытие

Модальное окно на HTML dialog открывают через showModal и снабжают доступным закрытием. Настройте начальный фокус и проверьте возврат к странице.
Что должно получиться
Посетитель открывает окно, понимает его назначение, выполняет действие или выходит и продолжает работу. Пока окно активно, элементы перекрытой страницы не должны случайно вмешиваться в этот маршрут.
Видимая карточка поверх затемнения ещё не делает интерфейс модальным. Нужно согласовать поведение мыши, клавиатуры и вспомогательных технологий. В этой инструкции основой служит нативный элемент HTML dialog, а не самостоятельное воспроизведение всего механизма на обычном блоке.
Сначала проверьте, нужно ли прерывать текущую работу. Для длинного материала или независимой задачи отдельная страница может оказаться понятнее. Модальное окно стоит применять там, где ограниченный шаг связан с текущим контекстом и после него есть ясное продолжение.
Из чего это складывается
| Часть | Что подготовить | Какой результат проверить |
|---|---|---|
| Назначение | Заголовок и короткое пояснение задачи | Окно понятно без чтения перекрытой страницы |
| Открытие | Кнопку и вызов модального режима | Окно открывается после осознанного действия |
| Начальный фокус | Подходящий элемент внутри | Начало содержимого и текущая позиция различимы |
| Фон | Нативное модальное поведение и оформление | Действия под окном недоступны в его документе |
| Выход | Видимый доступный элемент закрытия и клавиатурный способ | Человек может выйти без мыши |
| Продолжение | Возврат фокуса или обоснованный следующий шаг | После закрытия понятно, где продолжать |
Нативная реализация уменьшает объём поведения, которое нужно писать самостоятельно. W3C описывает этот подход в технике создания модальных окон через dialog. При этом содержимое, подписи, выбор начального фокуса и проверка конкретного сценария остаются вашей задачей.
Как это сделать по шагам
- Опишите ограниченную задачу. Решите, что человек должен сделать в окне и как вернуться к основной странице. Отметьте, какие данные важно сохранить при закрытии.
- Создайте элемент dialog. Добавьте видимый заголовок, содержимое и настоящие кнопки для предусмотренных действий. Свяжите доступное имя окна с его назначением.
- Подключите открытие через showModal. Вызывайте метод при активации соответствующей кнопки. Не подменяйте модальный режим одним изменением видимости или атрибутом open.
- Выберите начальный фокус. Для короткой формы это может быть подходящее поле, для длинного пояснения — элемент в начале содержимого. Проверьте, что выбранная позиция не скрывает начало текста.
- Подготовьте закрытие. Добавьте доступную клавиатурой кнопку и сохраните ожидаемое поведение Escape. Если действие выполняется не сразу, отдельно определите, когда окно действительно можно считать завершённым.
- Проверьте продолжение. Закройте окно разными способами и проследите за фокусом. Обычно он возвращается к открывшей кнопке; если её больше нет, нужен логичный элемент следующего шага.
- Пройдите полный маршрут. Проверьте клавиатуру, телефон, длинный текст, ошибки и вспомогательное чтение. После исправлений повторите открытие, действие и выход, а не только внешний вид.
Как подготовить структуру
Начните с dialog и видимого заголовка. Для связи можно использовать aria-labelledby, ссылающийся на id заголовка. Короткий пример структуры: <dialog id='task-dialog' aria-labelledby='task-title'><h2 id='task-title'>Действие</h2><p>Пояснение действия.</p></dialog>.
Это основа разметки, к которой нужно добавить элементы вашей задачи и доступную кнопку закрытия с понятной подписью. Все действия, относящиеся к окну, размещайте внутри него. Не оставляйте необходимый для завершения элемент на заблокированном фоне.
Не заменяйте кнопку кликабельной картинкой или обычным текстом. Если используете значок закрытия, у действия должно оставаться доступное имя. Проверяйте его смысл отдельно от формы значка: человек должен понять действие и при чтении без изображения.
Длинный текст не стоит целиком превращать в одну подпись описания окна. Сохраните заголовки, абзацы и понятный порядок чтения. Настройка имени и содержимого не должна заставлять человека прослушивать весь текст как неразделённую строку.
Как подключить нативное открытие и закрытие
Получите нужный dialog из документа: const dialog = document.getElementById('task-dialog');. Для модального открытия используется dialog.showModal();, для программного закрытия — dialog.close();. Вызовы относятся к уже найденному элементу, а не создают его автоматически.
Связь методов с существующими кнопками можно записать так: openButton.addEventListener('click', () => dialog.showModal()); и closeButton.addEventListener('click', () => dialog.close());. Здесь openButton и closeButton — заранее полученные элементы кнопок вашей страницы. Фрагменты показывают подключение поведения, а не готовую форму со всеми состояниями.
По документации MDN о showModal, окно попадает в верхний слой, а остальная часть того же документа становится inert. Если dialog находится во встроенном документе, блокируется именно этот документ, а не вся внешняя страница.
Не путайте showModal с show или просто установленным open. Видимый немодальный диалог имеет другое поведение. Если задача требует модальности, проверьте вызванный метод и фактическую недоступность фона, а не только наличие затемнения.
Для нативного dialog не нужно механически переносить весь код чужой самодельной реализации. Дополнительные обработчики клавиш способны конфликтовать с поведением браузера. Сначала определите, что уже обеспечивает нативный элемент, а затем добавляйте только нужное вашему сценарию.
Как выбрать начальный фокус
Фокус должен оказаться внутри открытого окна и помогать начать задачу. Не назначайте первую попавшуюся кнопку только потому, что она стоит первой в разметке. Сопоставьте выбор с длиной содержимого и ожидаемым действием.
Для подходящего элемента можно использовать autofocus. Если начало длинного содержимого должно оставаться доступным без прокрутки назад, рассмотрите статический элемент вверху с возможностью программного фокуса. Например, tabindex со значением минус один позволяет фокусировать элемент программно, не добавляя его в обычную последовательность Tab.
Выбор начальной позиции и возврат после закрытия разобраны в модели модального диалога W3C. Учитывайте характер содержимого и следующий шаг. Это полезнее универсального правила всегда ставить фокус в первое поле.
После открытия проверьте видимость фокуса. На телефоне появление экранной клавиатуры может изменить доступную область. Текущий элемент и необходимое пояснение должны оставаться различимыми, а возможность закрытия — достижимой.
Как закрыть окно и продолжить работу
Сохраните доступный видимый выход. Escape важен для клавиатурного маршрута, но не заменяет кнопку для остальных способов управления. Если вы предусматриваете закрытие по фону, оно должно дополнять понятный выход, а не становиться единственным способом.
Для обычного нативного модального dialog закрытие через Escape предусмотрено браузером; особенности описаны в справке MDN по элементу dialog. Не отменяйте это поведение случайным общим обработчиком клавиатуры.
Обычно после закрытия человек возвращается к открывшему окно элементу. Если после действия этот элемент исчез, заранее выберите логичное продолжение. Не отправляйте фокус в произвольное начало документа только потому, что прежней кнопки больше нет.
Если в окне есть отправка данных, различайте закрытие и успешное выполнение. Ошибка не должна выглядеть как подтверждённый результат. Сохраните возможность исправить данные и покажите реальное состояние до завершения маршрута.
Повторите открытие после выхода. Проверьте, какое содержимое и состояние возвращаются: очищенные поля, прежний черновик или результат предыдущего действия. Выбор зависит от задачи, но должен быть согласованным и понятным.
Частые ошибки
- Создавать только видимый слой. Модальность включает поведение и контекст управления, а не одно оформление.
- Использовать open вместо модального вызова. Проверьте реальный режим и недоступность фона.
- Добавлять ARIA без нужного поведения. Сообщение вспомогательным технологиям не реализует механизм само по себе.
- Убирать доступный выход. Проверьте кнопку и клавиатурное закрытие.
- Терять фокус после завершения. Сохраните возврат или осмысленный следующий шаг.
- Проверять только короткий текст на компьютере. Добавьте длинное содержимое, телефон и ошибку действия.
Как проверить
- Окно решает ограниченную задачу, для которой оправдано прерывание страницы.
- Есть понятный видимый заголовок и доступное имя.
- Нативный модальный режим включается через showModal.
- Начальный фокус находится внутри и помогает начать действие.
- Tab и обратный переход не ведут к заблокированному содержимому фона.
- Видимая кнопка закрытия доступна клавиатурой, Escape работает ожидаемо.
- После закрытия фокус возвращается в осмысленное место.
- Длинный текст, увеличение, экранная клавиатура и ошибки проверены.
- Повторное открытие показывает согласованное состояние.
Для разработки опишите задачу, начальное состояние и поведение после выхода. Исполнителя можно подобрать в разделе «Разработка». В приёмку включите маршрут открытия и закрытия разными способами, а не только согласование изображения окна.
Дополнительно используйте проверку сайта с клавиатуры. Для содержимого пригодятся подписи полей и ошибки и состояния кнопки во время действия.
Если для закрытия выбран значок, отдельно проверьте понятность иконки.
Вопросы и ответы
Достаточно ли затемнить фон?
Нет, фон может оставаться доступным для действий, даже если визуально перекрыт. Используйте нативный модальный режим и проверьте управление. Оформление должно соответствовать фактическому поведению.
Чем showModal отличается от show?
showModal открывает нативный dialog в модальном режиме с предусмотренным поведением фона. show предназначен для немодального показа. Выбирайте метод по задаче и не подменяйте проверку поведения внешней похожестью.
Нужно ли вручную удерживать Tab внутри нативного окна?
Сначала проверьте поведение dialog, открытого через showModal, в поддерживаемых браузерах. Не добавляйте поверх него чужой механизм без необходимости. Для самодельного компонента пришлось бы воспроизводить больше поведения самостоятельно.
Всегда ли фокус должен сразу переходить в поле?
Нет, выбор зависит от содержимого и задачи. Для длинного пояснения начальная позиция вверху может быть понятнее. Убедитесь, что начало текста и текущий элемент видны, а человек понимает следующий шаг.
Можно ли закрывать окно только нажатием на фон?
Нет, сохраните видимый доступный выход и клавиатурный маршрут. Действие по фону может быть дополнительным, если оно подходит задаче и не приводит к неожиданной потере введённого.
Куда вернуть фокус, если исходная кнопка исчезла?
Выберите элемент, который логично продолжает выполненный сценарий. Это нужно определить в проектировании поведения и проверить после действия. Случайный переход в начало страницы не помогает восстановить контекст.
Можно ли считать окно доступным только потому, что использован dialog?
Нет, нативный элемент даёт основу поведения. Всё равно нужно проверить имя, содержимое, начальный фокус, выход, состояния и работу на поддерживаемых устройствах. Результат оценивают по полному маршруту человека.
