HTML5

HTML5

HTML5

Запрос, который часто вводят в поиске: «HTML5 dialog модальное окно пример». В этой статье вы получите готовые шаблоны для тега <dialog>, узнаете разницу между show() и showModal(), настроите закрытие по клику на фон и добавите плавные анимации без тяжёлых JS-плагинов.

Что такое <dialog> и когда его использовать

<dialog> — нативный HTML-элемент для диалоговых окон. Он умеет:

  • Быть модальным (showModal()) — блокирует фон и перехватывает фокус.
  • Быть немодальным (show()) — просто плавающее окно без блокировки фона.
  • Закрываться программно (close(value)) или из формы с method="dialog".
  • Выдавать returnValue — удобно для результата диалога (например, OK/Cancel).
  • Базовый модальный диалог: минимальный шаблон

    HTML, CSS и JS, которых достаточно для рабочего модального окна.

    <button id="openDialog">Открыть модалку</button>
    
    <dialog id="modal" aria-labelledby="modal-title">
      <form method="dialog" class="box">
        <h2 id="modal-title">Подтвердите действие</h2>
        <p>Вы уверены, что хотите продолжить?</p>
        <div class="actions">
          <button value="cancel">Отмена</button>
          <button value="ok" class="primary">OK</button>
        </div>
      </form>
    </dialog>
    
    <style>
      dialog {
        border: none;
        padding: 0;
        border-radius: 12px;
        width: min(90vw, 420px);
        max-width: 100%;
        box-shadow: 0 10px 30px rgba(0,0,0,.2);
      }
      dialog::backdrop { background: rgba(0,0,0,.4); }
      .box { padding: 20px; display: grid; gap: 16px; }
      .actions { display: flex; gap: 12px; justify-content: flex-end; }
      .primary { background: #2563eb; color: #fff; border: 0; padding: 8px 14px; border-radius: 8px; }
      button { cursor: pointer; }
    </style>
    
    <script>
      const dialog = document.getElementById('modal');
      document.getElementById('openDialog').addEventListener('click', () => dialog.showModal());
    
      // Логируем результат (OK/Cancel)
      dialog.addEventListener('close', () => {
        console.log('dialog closed with:', dialog.returnValue);
      });
    
      // Закрытие по клику на фон (backdrop)
      dialog.addEventListener('click', (e) => {
        const rect = dialog.getBoundingClientRect();
        const inDialog = (
          e.clientX >= rect.left && e.clientX <= rect.right &&
          e.clientY >= rect.top && e.clientY <= rect.bottom
        );
        if (!inDialog) dialog.close('backdrop');
      });
    </script>
    

    Кнопки внутри формы с method="dialog" автоматически закроют диалог и заполнят returnValue значением атрибута value на кнопке.

    show() vs showModal()

  • showModal() — настоящий модал: блокирует скролл и фон, фокус внутри окна; закрывается по Esc (генерирует событие cancel).
  • show() — немодальный: не блокирует фон и не перехватывает фокус; подходит для подсказок и плавающих панелей.
  • Плавные анимации открытия и закрытия

    По умолчанию диалог появляется резко. Добавим плавность. Фишка: при закрытии <dialog> сразу исчезает. Поэтому сначала запустим анимацию, а затем вызовем close().

    <style>
      dialog { opacity: 0; transform: translateY(10px) scale(.98); transition: .18s ease; }
      dialog[open] { opacity: 1; transform: translateY(0) scale(1); }
      dialog.closing { opacity: 0 !important; transform: translateY(10px) scale(.98) !important; }
      dialog::backdrop { opacity: 0; transition: opacity .18s ease; }
      dialog[open]::backdrop { opacity: 1; }
    </style>
    
    <script>
      const dlg = document.getElementById('modal');
    
      function closeWithAnimation(value) {
        dlg.classList.add('closing');
        const onEnd = () => {
          dlg.classList.remove('closing');
          dlg.close(value);
          dlg.removeEventListener('transitionend', onEnd);
        };
        dlg.addEventListener('transitionend', onEnd);
      }
    
      // Esc (событие cancel) — дадим сыграть анимации
      dlg.addEventListener('cancel', (e) => {
        e.preventDefault();
        closeWithAnimation('cancel');
      });
    
      // Клик по фону — тоже с анимацией
      dlg.addEventListener('click', (e) => {
        const r = dlg.getBoundingClientRect();
        const inDlg = e.clientX >= r.left && e.clientX <= r.right && e.clientY >= r.top && e.clientY <= r.bottom;
        if (!inDlg) closeWithAnimation('backdrop');
      });
    </script>
    

    Доступность (a11y): важные детали

  • Задайте понятный заголовок и свяжите его: aria-labelledby="modal-title" + <h2 id="modal-title">...</h2>.
  • Не используйте role="dialog" — он встроен нативно, браузер сам объявит роль и модальность.
  • Фокус: showModal() автоматически ставит фокус внутрь. Добавьте autofocus важной кнопке или инпуту.
  • Не вкладывайте модальные диалоги друг в друга — это ломает навигацию и фокус.
  • Немодальный диалог (панель подсказки)

    Иногда нужна «лёгкая» панель без блокировки фона — используйте show().

    <dialog id="tip">Подсказка: нажмите Ctrl+K для поиска.</dialog>
    <script>
      const tip = document.getElementById('tip');
      tip.show(); // не блокирует страницу и фокус
    </script>
    

    Частые ошибки и как их избежать

  • Ручная установка атрибута open вместо вызова методов. Для модального поведения используйте showModal(), а не setAttribute('open', '') — иначе не будет блокировки фона и ловушки фокуса.
  • Отсутствие обработчика клика по фону. По умолчанию клик в бэкдроп не закрывает окно. Добавьте обработчик, как в примерах выше.
  • Кнопка закрытия внутри формы без type=»button». Если это не method="dialog", явно ставьте type="button", чтобы не триггерить лишние сабмиты.
  • Кроссбраузерность и запасной план

    Поддержка <dialog> есть во всех современных браузерах, включая Safari 15.4+. В старых браузерах (например, IE) используйте graceful degradation: просто показывайте блок как обычный контент без модальности или подключайте небольшой полифилл при необходимости.

    <script>
      if (!HTMLDialogElement) {
        console.warn('Ваш браузер не поддерживает <dialog>. Показ будет упрощён.');
        // Fallback: показывать скрытый блок, управлять aria-hidden и прокруткой вручную
      }
    </script>
    

    Советы по развитию навыков вёрстки

  • Практикуйте паттерн: «кнопка — диалог — метод dialog — логика закрытия» в маленьких демо-проектах.
  • Соберите компонент «Dialog» со скелетом HTML/CSS/JS и переиспользуйте его в проектах.
  • Покройте сценарии: Esc, клик по фону, кнопка OK/Cancel, анимации, фокус и мобильная адаптация.
  • Хотите системно прокачать HTML/CSS и научиться собирать интерфейсы быстрее? Загляните на «Вёрстка сайта с нуля 2.0» — практический курс с упором на реальные задачи: присоединиться к курсу «Вёрстка сайта с нуля 2.0» и ускорить обучение.

    Итоги

    <dialog> — лучший старт для модальных окон в 2025: просто, нативно, доступно. Используйте showModal() для модальности, method="dialog" для быстрых кнопок закрытия, добавляйте обработчик клика по фону и анимации для приятного UX. Так вы получите лёгкий и поддерживаемый компонент без сторонних зависимостей.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий