Всплывающее (модальное) окно: CSS :target и элемент dialog

Как сделать модальное окно со своим содержимым: классический вариант на CSS-псевдоклассе :target и современный — на HTML-элементе dialog.

Модальное окно пригодится, когда на одной странице нужно показать разный контент — например, маршруты на карте для нескольких адресов — не создавая отдельные страницы.

Современный способ: элемент dialog

<button type="button" data-open="route">Как проехать</button>

<dialog id="route" class="modal">
  <h2>Маршрут</h2>
  <p>Текст или карта</p>
  <form method="dialog"><button>Закрыть</button></form>
</dialog>

<script>
document.querySelectorAll('[data-open]').forEach(function (btn) {
  btn.addEventListener('click', function () {
    document.getElementById(btn.dataset.open).showModal();
  });
});
</script>
.modal { width: min(950px, 92vw); border: 0; border-radius: 12px; padding: 30px; }
.modal::backdrop { background: rgba(0, 0, 0, .5); }

Браузер сам затемняет фон, закрывает окно по Esc, удерживает фокус внутри окна и возвращает его на кнопку после закрытия. Скрипт — три строки, без библиотек.

Классический способ: псевдокласс :target

Окно открывается, когда адрес страницы заканчивается на #modal, и закрывается ссылкой на другой якорь. Работает совсем без JavaScript.

<a href="#modal" class="openModal">Открыть</a>
<div id="modal" class="modal-target">
  <div>
    <a href="#close" title="Закрыть" class="close">×</a>
    <div class="text">Текст окна</div>
  </div>
</div>
.modal-target {
  position: fixed; inset: 0; z-index: 10000;
  background: rgba(0, 0, 0, .5);
  opacity: 0; pointer-events: none;
  transition: opacity .5s ease-in;
}
.modal-target:target { opacity: 1; pointer-events: auto; }
.modal-target > div {
  position: relative;
  width: min(950px, 92vw);
  margin: 10% auto; padding: 30px;
  background: #fff; border-radius: 7px;
  box-shadow: 0 3px 20px rgba(0, 0, 0, .9);
}
.modal-target .close { position: absolute; right: 12px; top: 8px; font-size: 24px; text-decoration: none; }

Минусы: окно меняет адрес страницы и попадает в историю браузера, не закрывается по Esc и не удерживает фокус. Для новых сайтов выбирайте dialog.

Все статьи

Расскажите о задаче — подберём платформу и оценим работу

Обсудить проект