Как сделать модальное окно на сайте
Привет друзья, в этому году меня несколько раз просили объяснить, как сделать модальное окно на сайте. Кто-то, изучая азы веб-разработки неизбежно приходил к ситуации, когда часть контент необходимо отобразить в модальном окне, кто-то, работая с формами, хочет показать ее не в открытом виде, а в pop-up при клике на кнопку.
Несмотря на то, что на блоге уже были статьи, косвенно связанные с реализацией этого эффекта, вопросы все равно остаются и я решил сделать несколько статей, связанных с этой темой. Сегодня разберемся просто с модальными окнами, а в следующий раз сделаем пульсирующую кнопку в углу экрана, как у сервисов обратного звонка и еще просили урок с анимацией блика на кнопке.
Все это выйдет друг за другом. Конечно, это статьи, ориентированные на новичков, и мастодонтам они будут не очень интересны, но тем, кто использует блог как справочник, возможно, пригодятся эти наработки, чтобы быстро реализовывать тот или иной эффект, не описывая одно и тоже каждый раз в новом проекте и сэкономят немного времени. Приступим.
Чтобы статья получилась максимально полной, будем придерживаться следующего плана и сделаем:
- модальное окно с использованием jQuery.
- Простое модальное окно с использованием чистого js.
Конечно же я покажу как вызывать несколько модальных окно на станице, так как это тоже один из частых вопросов, возникающих у новичков. Разберем возможность закрытия окна при клике вне области контента, решим проблему вертикальной прокрути и другие нюансы, которые возникнут в ходе работы или о которых сообщите вы в комментариях.
Структура проекта для понимания какие файлы и где находятся.
Начнем с разметки. Для создания модального окна я обычно пользуюсь такой структурой.
Где «modal» — это затемненный фон, а «modal__content» — область контента. При этом, когда срабатывает триггер, вызывающий окно, например нажатие кнопки, то к «modal» добавляется класс «modal_active», который дает понять, что модальное окно находится в открытом состоянии. Добавляя или удаляя «modal_active» мы будем открывать или скрывать модальное окно манипулирую стилями.
Большинству читающих нужна будет форма в модальном окне. Можно использовать эту.
Я, для примера, просто выведу текст:
Создал простейшую шапку сайта с кнопкой обратного звонка, которая должна вызвать модальное окно. Классический пример любого лендинга.
Давайте добавим немного стилей и приведем в порядок открытое состояние модалки. Вот, что получилось у меня.
Обратите внимание, что в правом углу контентной области модального окна появилась кнопка с изображением крестика. Файл лежит в папке «img», рядом с папкой «js» и «css».
.modal < position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1000; background: rgba(0, 0, 0, 0.9); display: flex; justify-content: center; align-items: flex-start; overflow-y: scroll; padding: 60px 15px; >.modal__content < width: 100%; max-width: 500px; padding: 50px; background: #f9f9f9; border-radius: 3px; position: relative; box-shadow: 0 5px 15px black; >.modal__close-button < background: #ff0000; height: 30px; width: 30px; display: flex; justify-content: center; align-items: center; border: none; position: absolute; right: 0; top: 0; background: none; cursor: pointer; transition: .3s; outline: none; >.modal__close-button:hover < transition: .3s; transform: rotate(180deg); >.modal__title < font-size: 1.8rem; text-transform: uppercase; margin: 0 0 15px; >.modal__description
Тут нас больше всего интересует класс «.modal». Как я и говорил, это само модальное окно с полупрозрачным фоном. Давайте подробнее разберем что там за стили.
Первым делом «вырвем» из потока блок с модальным окном при помощи фиксированного позиционирования. Затем, при помощи свойств «top», «left», «right», «bottom» растянем модальное окно по ширине на весь экран. Z-index — нужен для того, чтобы расположить окно над всеми элементами. Если у кого-то другого элемента значение этого свойства будет выше, то модальное окно не перекроет его.
position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1000;
Далее задаю цвет фона модального окна.
Цвет задаю в RGBA формате. Первые 3 цифры — это цвет, а последняя — прозрачность. Где «.9» — это прозрачность в 90%.
Далее использую flexbox для центрирования элемента «modal__content» внутри «modal», задаю возможность вертикальной прокрутки и внутренние отступы.
display: flex; justify-content: center; align-items: flex-start; overflow-y: scroll; padding: 60px 15px;
Окно прекрасно смотрится, но есть одно «но!». Помните я говорил, что активное состояния модального окна, это когда у нас есть класс «modal_active», а без этого класса, окно закрыто? Сейчас мы доведем до ума эту концепцию. Суть в том, чтобы при «modal» сделать окно скрытым, а при «modal_active» — показать.
Давайте создадим этот класс в стилях и настроим отображение окна только при его наличии.
Для показа/скрытия окна будем пользоваться «visibility», «opacity», «position» и свойство «transition» для плавности анимации появления.
Если еще подробнее, то сначала зададим нулевую прозрачность, а при помощи абсолютного позиционирования и свойства «top» уберем модальное окно за пределы видимости. Дополнительно, для надежности, при помощи свойства «visibility» скроем разметку окна.
В момент, когда появится класс «modal_active» инвертируем «visibility» и «opacity», а также поменять «position» и положение в свойстве «top».
Звучит страшнее, чем кажется, на сам деле все довольно просто.
Теперь в таком состоянии окно скрыто:
Попробуйте добавить вручную и убедиться, что окно успешно появляется.
Пол дела сделали, осталось добавлять этот класс модальному окну при клике по кнопке. Тут подход и разделится. Первый вариант сделаем с использованием jQuery, а второй без него на чистом js.
Но прежде нужно подключить файл скриптов к нашей html страничке. Делается это так:
Вызов модального окна при помощи jQuery
Исходник модального окна с использованием jQuery
Полезные ссылки
* Модальное окно вызывается при клике на кнопку Click me.
Создаем модальное окно
В качестве примера сделал простое модальное окно, которое открывается при клике на кнопку и закрывается также.
В нашем примере модальное окно:
- Имеет заголовок, текстовое содержимое и две кнопки.
- Адаптируется под мобильные устройства.
- Блокирует скролл веб-страницы.
- При переполнении контентом — появляется скролл в самом модальном окне.
Разметка
В начале сделаем разметку для модального окна и кнопки.
Модальное окно можно разместить в самом начале веб-страницы.
Кнопку для вызова окна разместите в нужном вам месте кода.
Стили
Стили для модального окна.
.modal < display: none; /* По умолчанию окно закрыто */ z-index: 10; /* Чтобы сделать окно поверх всех элементов */ background-color: rgba(0, 0, 0, 0.5); /* Полупрозрачный темный фон */ position: fixed; top: 0; left: 0; width: 100%; height: 100%; align-items: flex-start; justify-content: center; overflow-y: scroll; /* При переполнении окна делаем скролл */ padding: 20px; >.modal--open < display: flex; /* Модификатор для открытого окна */ >.modal__box < width: 100%; max-width: 600px; padding: 20px; background-color: #fff; border-radius: 10px; margin-top: auto; margin-bottom: auto; >.modal__title < color: #111; font-size: 32px; text-align: center; margin-bottom: 20px; >.modal__info < color: #111; font-size: 16px; margin-bottom: 30px; >.modal__bottom
.btn < box-sizing: border-box; display: block; width: max-content; background-color: #0066cc; padding: 10px 20px; font-size: 1.2rem; color: #fff; border-radius: 10px; >.modal__bottom > .btn < margin-right: 20px; >.modal__bottom > .btn:last-child < margin-right: 0; >.modal__bottom > .btn--close
Чтобы заблокировать скролл веб-страницы добавим дополнительный класс lock.
Скрипт
// считываем все элементы const body = document.body; const btn = document.querySelector("#btn"); const btnClose = document.querySelector("#btn_close"); const modal = document.querySelector("#modal"); // обработчики клика на кнопки btn.addEventListener("click", btnHandler); btnClose.addEventListener("click", btnCloseHandler); // при нажатии на кнопку Click me function btnHandler(e) < e.preventDefault(); body.classList.add("lock"); // блокируем скролл веб-страницы modal.classList.add("modal--open"); // открываем модальное окно >// при нажатии на кнопку Close function btnCloseHandler(e) < e.preventDefault(); body.classList.remove("lock"); // разблокируем скролл страницы modal.classList.remove("modal--open"); // закрываем окно >// при нажатии на пустое пространство - закрываем окно window.addEventListener("click", function (e) < if (e.target == modal) < body.classList.remove("lock"); modal.classList.remove("modal--open"); >>);