Всплывающее (модальное) окно: 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.