Вёрстка модальных окон
Практически каждый сайт использует модальные окна для различных целей: отображение уведомлений, подтверждение действий, сбор информации и прочее. В этой главе мы рассмотрим два способа отображения модальных окон: новый и универсальный.
Новые модальные окна
Новые модальные окна имеют очень простой синтаксис HTML:
<dialog open>Это модальное окно</dialog>
Для отображения модального окна, необходимо добавить атрибутopen
К сожалению, обойтись совсем без JavaScript здесь невозможно, поэтому далее я приведу пример кода, который минимизирует ваше взаимодействие с JavaScript.Мы можем использовать DATA-атрибуты для задания идентификатора модального окна, которое будет перехватываться JavaScript. Работать с этим просто:
<dialog data-modal="my-first-modal"> <button class="close">×</button> </dialog> <button data-modal-open="my-first-modal">Показать модальное окно</button>
Здесь, в атрибутеdata-modal
, мы задаем идентификатор модального окна. А далее, в кнопке, позволяющей
показать модальное окно, используя атрибутdata-modal-open
, мы говорим, что эта кнопка показывает
модальное окно с нашим идентификатором.
Простое решение может выглядеть примерно так:
Запустить примерСтилизация
Модальное окно, открытое с помощьюdialog.openModal()
, имеет псевдо-элемент::backdrop
.
Этот элемент является подложкой под модальным окном и растянут на весь экран. Обычно этот элемент красят в
прозрачно-чёрный цвет и добавляют к нему
backdrop-filter.
Этот набор фильтров позволяет, например, размыть всю страницу кроме модального окна для создания акцента на окно.
Кроме того, можно добавить эффект появления модального окна. Для этого можно добавить немного CSS-кода:
dialog { animation: fadeIn 250ms ease-in-out; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
Этот код позволит модальному окну плавно появляться на экране.
Рассмотренный выше способ в 2019 году работает далеко не во всех браузерах. Поддержку этого способа браузерами можно посмотреть здесь: Can i use Dialog element?
Универсальные модальные окна
Что делать, если нужно поддерживать большее количество браузеров? Выход один - использовать старые методы. Код будет не так изящен, зато работать будет везде.
<button data-modal-open="hello-world">Открыть модальное окно</button> <div class="modal" data-modal="hello-world"> <div class="dialog"> <button class="dialog-close" aria-label="Close modal"></button> <section class="dialog-content"> <h2>Модальное окно</h2> <p>Какой-то контент</p> </section> </div> </div>
Конечно же, придётся добавить много стилей:
.modal { /* Подложка будет занимать 100% площади экрана*/ position: fixed; top: 0; left: 0; bottom: 0; right: 0; width: 100%; height: 100vh; z-index: 1000; /* Скрываем подложку с модальным окном*/ display: none; /* Overflow позволит нам скроллить модальное окно, если контента в нём будет больше, чем может поместиться на экране */ overflow-y: auto; /* Цвет подложки */ background: rgba(0, 0, 0, 0.8); /* Размытие фона */ -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); /* Анимация появления */ animation: fadeIn 250ms ease-in-out; /* Добавляем дополнительные стили */ align-items: flex-start; justify-content: center; padding: 5vh 0 10vh; /* Через JavaScript мы будем добавлять атрибут open, что должно сделать модальное окно видимым */ } .modal[open] { display: flex; } .modal .dialog { /* Стилизуем само модальное окно */ width: 100%; max-width: 960px; min-height: 100px; border-radius: 4px; position: relative; border: none; color: white; font-weight: 300; } .modal .dialog .dialog-close { /* Стилизуем кнопку закрытия модального окна */ position: absolute; top: 0; right: 0; width: 3em; height: 3em; background: none; border: none; cursor: pointer; outline: none; } .modal .dialog .dialog-close::before, .modal .dialog .dialog-close::after { content: ""; display: block; position: absolute; top: 50%; right: 5px; left: 5px; border-bottom: 1px solid white; transform: rotate(45deg); } .modal .dialog .dialog-close::after { transform: rotate(-45deg); } .modal .dialog .dialog-close:focus::before, .modal .dialog .dialog-close:hover::before, .modal .dialog .dialog-close:focus::after, .modal .dialog .dialog-close:hover::after { border-color: tomato; } .modal .dialog .dialog-content { /* Дополнительные стили для контента*/ padding: 2em; background-color: rgba(0, 0, 0, 0.6); border: none; } /* Анимация появления*/ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
Далее сложно: JavaScript. Чтобы уменьшить количество вашего взаимодействия с JavaScript, был снова сделан модуль, работающий через DATA-атрибуты. Всё, как и в предыдущий раз. С ним можно ознакомиться в коде примера:
Запустить примерНе изобретай велосипед
Часто, лучшим способом является не создание собственного "велосипеда", а использование уже готового продукта. Модальные окна здесь не исключение.Можно просто найти хороший модуль модальных окон, прочитать к нему документацию и использовать его. Тогда практически не придется задумываться насчёт JavaScript и вёрстки окна. Примером могут послужить Tingle или Micromodal.