Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Модальное окно: dialog

Модальное окно — окно поверх страницы, которое затемняет всё остальное и ждёт ответа: подтвердить действие, заполнить короткую форму. В HTML для него есть тег <dialog>, и браузер сам умеет его открывать и закрывать. Pico добавляет затемнение фона и оформляет содержимое как карточку.

Разметка окна

Внутри <dialog> кладут <article> — карточку из прошлых уроков. Кнопка с rel="prev" в шапке карточки превращается в крестик закрытия:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
 
<div style="min-height: 280px"></div>
<dialog open>
  <article>
    <header>
      <form method="dialog">
        <button aria-label="Закрыть" rel="prev"></button>
      </form>
      <p><strong>Спасибо за подписку!</strong></p>
    </header>
    <p>Новые записи блога будут приходить по пятницам.</p>
  </article>
</dialog>

Окно открыто сразу благодаря атрибуту open: фон затемнён, по центру карточка с заголовком и крестиком. Щёлкните крестик — окно закроется. Кнопка внутри <form method="dialog"> закрывает свой <dialog> без единой строки JavaScript. Пустой блок с min-height даёт окну место в превью.

Открытие по кнопке

Обычно окно скрыто, а открывает его скрипт методом showModal(). Закрывает метод close(), а также клавиша Escape:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
 
<div style="min-height: 300px">
  <button id="open-contact">Написать мне</button>
</div>
 
<dialog id="contact">
  <article>
    <header>
      <button aria-label="Закрыть" rel="prev" data-close></button>
      <p><strong>Связаться с Анной</strong></p>
    </header>
    <label for="reply">Ваш email</label>
    <input type="email" id="reply">
    <footer>
      <button class="secondary" data-close>Отмена</button>
      <button data-close>Отправить</button>
    </footer>
  </article>
</dialog>
 
<script>
  const dialog = document.querySelector('#contact');
  document.querySelector('#open-contact').addEventListener('click', () => dialog.showModal());
  dialog.querySelectorAll('[data-close]').forEach((button) => {
    button.addEventListener('click', () => dialog.close());
  });
  dialog.addEventListener('close', () => console.log('Окно закрыто'));
</script>

Нажмите «Написать мне» — откроется окно с полем email и двумя кнопками в подвале. Любая из трёх кнопок или Escape закрывает его, и под примером появляется «Окно закрыто»: событие close срабатывает при любом способе закрытия.

Что за что отвечает

ЧастьЗадача
<dialog>Затемнённый слой во весь экран
<article>Сама карточка окна
<header> с rel="prev"Заголовок и крестик
<footer>Кнопки действий, выровненные вправо
showModal() и close()Открыть и закрыть из скрипта

Метод showModal() ещё и удерживает фокус внутри окна: клавиша Tab не уйдёт к ссылкам страницы под затемнением.

Частая ошибка

Открывать окно, просто добавляя атрибут open из скрипта. Окно появится, но браузер не будет считать его модальным: Escape не закроет его, а Tab уведёт фокус на страницу под ним. Для окон, которые ждут ответа, используйте showModal().

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.