Модальное окно на HTML5, CSS3 и скрытых чекбоксах
Судя по комментариям, тема создания модальных окон довольно популярна. Я не раз уже описывал различные техники исполнения, как с помощью jQuery, так и на чистом CSS. Да и в интернетах, информации по теме предостаточно, и каждый может выбрать для себя оптимальный вариант.
Меня больше интересуют решения без использования javascript, не потому-что у меня какая-то фобия к js, нет, мне просто интересны эксперименты, поиск новых возможностей связки html+css, тем более что в последнее время возможности эти существенно расширились.
Скрытые чебоксы(checkbox) я пару раз использовал при разработке блоков в стиле «аккордеон», почему бы не применить эту же методу и для реализации всплывающих(модальных) окон. Оказывается всё довольно просто, давайте рассмотрим подробнее, как с помощью свойств CSS3 и новых синтаксических особенностей HTML5, можно быстро и без особых сложностей организовать на страницах своих сайтов работу привлекательных модальных окошек.
Посмотрите живой пример, протестируйте в разных браузерах и на различных устройствах, модальные окна отлично вписываются в любые размеры. В примере представил три варианта использования, стандартное диалоговое окно, интегрированная контактная форма и встроенная картинка в модальное окно.
При формировании html-каркаса модального окна руководствовался принципами построения стандартной html-страницы, т.е. наше окно состоит из базового контейнера <div class="modal">
, который в свою очередь разделён на сектора, слой затемнения, модальный блок <div class="modal-dialog">
с заголовком <div class="modal-header">
, центральным блоком <div class="modal-body">
, и подвалом <div class="modal-footer">
.
HTML Каркас
На ряду с использованием стандартных html-элементов тегов <input>
и <label>
, для определения состояния и свойства объектов, применил ARIA-атрибут из состава HTML5-спецификации, в частности атрибут aria-hidden
, который показывает состояние «hidden» у текущего элемента, в нашем случае это связка тегов <input>
и <label>
, определяющие элементы пользовательского интерфейса модальных окон.
Атрибут for
это ничто иное как идентификатор элемента, с которым следует установить связь, при использовании на одной странице нескольких модальных окон с различным содержанием, следует помнить о том, что идентификатор должен быть разным, установленным в соответствии с id того или иного мод. окна, for="modal-1"
, for="modal-2"
и т.д.
<!-- Кнопка активации --> <label class="btn" for="modal-1">Открыть</label> <!-- Модальное окно --> <div class="modal"> <input class="modal-open" id="modal-1" type="checkbox" hidden> <div class="modal-wrap" aria-hidden="true" role="dialog"> <label class="modal-overlay" for="modal-1"></label> <div class="modal-dialog"> <div class="modal-header"> <h2>Заголовок </h2> <label class="btn-close" for="modal-1" aria-hidden="true">×</label> </div> <div class="modal-body"> <p>Здесь размещаете любое содержание...</p> </div> <div class="modal-footer"> <label class="btn btn-primary" for="modal-1">Отлично!</label> </div> </div> </div> </div> |
CSS
Стилистика внешнего вида модального окна напоминает стиль всплывающих окошек из набора элементов Bootstrap, в случае необходимости, очень легко меняется в CSS. Непосредственно в код css прописал краткие комментарии, так что, вам будет легче разобраться, что к чему и зачем))).
/* Стили модального окна */ .modal-header h2 { color: #555; font-size: 20px; font-weight: normal; line-height: 1; margin: 0; } /* кнопка закрытия окна */ .modal .btn-close { color: #aaa; cursor: pointer; font-size: 30px; text-decoration: none; position: absolute; right: 5px; top: 0; } .modal .btn-close:hover { color: red; } /* слой затемнения */ .modal-wrap:before { content: ""; display: none; background: rgba(0, 0, 0, .3); position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 101; } .modal-overlay { bottom: 0; display: none; left: 0; position: fixed; right: 0; top: 0; z-index: 102; } /* активация слоя затемнения и модального блока */ .modal-open:checked ~ .modal-wrap:before, .modal-open:checked ~ .modal-wrap .modal-overlay { display: block; } .modal-open:checked ~ .modal-wrap .modal-dialog { -webkit-transform: translate(-50%, 0); -ms-transform: translate(-50%, 0); -o-transform: translate(-50%, 0); transform: translate(-50%, 0); top: 20%; } /* элементы модального окна */ .modal-dialog { background: #fefefe; border: none; border-radius: 5px; position: fixed; width: 80%; max-width: 500px; left: 50%; top: -100%; -webkit-box-shadow: 0 15px 20px rgba(0,0,0,.22),0 19px 60px rgba(0,0,0,.3); -moz-box-shadow: 0 15px 20px rgba(0,0,0,.22),0 19px 60px rgba(0,0,0,.3); box-shadow: 0 15px 20px rgba(0,0,0,.22),0 19px 60px rgba(0,0,0,.3); -webkit-transform: translate(-50%, -500%); -ms-transform: translate(-50%, -500%); -o-transform: translate(-50%, -500%); transform: translate(-50%, -500%); -webkit-transition: -webkit-transform 0.4s ease-out; -moz-transition: -moz-transform 0.4s ease-out; -o-transition: -o-transform 0.4s ease-out; transition: transform 0.4s ease-out; z-index: 103; } .modal-body { padding: 20px; } .modal-body p { margin: 0; } .modal-header, .modal-footer { padding: 20px 20px; } .modal-header { border-bottom: #eaeaea solid 1px; } .modal-header h2 { font-size: 20px; margin: 0; } .modal-footer { border-top: #eaeaea solid 1px; text-align: right; } /* адаптивные картинки в модальном блоке */ .modal-body img { max-width: 100%; height: auto; } /* кнопки */ .btn { background: #fff; border: #555 solid 1px; border-radius: 3px; cursor: pointer; display: inline-block; font-size: 14px; padding: 8px 15px; text-decoration: none; text-align: center; min-width: 60px; position: relative; } .btn:hover, .btn:focus { background: #f2f2f2; } .btn-primary { background: #428bca; border-color: #357ebd; color: #fff; } .btn-primary:hover{ background: #66A1D3; } |
Если вам не нужен какой либо из разделов, например нет надобности в заголовке, просто исключите <div class="modal-header">
из конструкции, не нужен футер, убираете <div class="modal-footer">
. Всё это хорошо видно на примере интеграции контактной формы в тело модального окна.
Для примера, использовал немного видоизменённую форму обратной связи, о вёрстке которой рассказывал ранее. Все элементы формы замечательно подстраиваются под размеры окна при просмотре на различных экранах пользовательских устройств.
/* Элементы формы контактов */ .textbox{ height:45px; width:100%; border-radius:3px; border:rgba(0,0,0,.3) 1px solid; box-sizing:border-box; font-size:14px; padding:8px; margin-bottom:20px; } .message:focus, .textbox:focus{ outline:none; border:rgba(24,149,215,1) 1px solid; color:rgba(24,149,215,1); } .message{ background: rgba(255, 255, 255, 0.4); width:100%; height: 120px; border:rgba(0,0,0,.3) 1px solid; box-sizing:border-box; -moz-border-radius: 3px; font-size:14px; -webkit-border-radius: 3px; border-radius: 3px; display:block; padding:10px; margin-bottom:20px; overflow:hidden; } /* кнопка "отправить" формы */ .btn-form{ width:100%; height:45px; border:rgba(0,0,0,.2) 1px solid; box-sizing:border-box; background: #dedede; color:#555; transition:background .4s; } /* Изменение фона кнопки при наведении */ .btn-form:hover{ background: #f2f2f2; } |
Многие, очень многие, используют модальные окна для демонстрации различных изображений, так что предусмотрел и этот вариант. Картинкам, встраиваемым в тело окна, задал 100% ширину max-width: 100%;
, при автоматическом определении высоты height: auto;
, с помощью чего, изображения будут корректно отображаться при изменении размеров окна в ту или в другую сторону, получается такая вот адаптивность)).
Чтобы получить эффект lightbox, когда изображение заполняет всё пространство всплывающего блока, достаточно убрать div
заголовка, нижний блок с кнопкой и выставить необходимые отступы внутри модального окна, в селекторе .modal-body
.
Если вдруг, захотите разместить в модальном окне видеоролик с YoTube, или другого видео-сервиса, воспользуйтесь способом, о котором я рассказывал ранее. Только следует помнить о том, что оптимального решения остановки проигрывания видео после закрытия окна, без подключения js, до сих пор не найдено, придётся довольствоваться не очень «кошерными» методами.
На этом всё! Остаётся лишь напомнить, что данный способ отлично будет работать только в современных браузерах, безоговорочно поддерживающих свойства CSS3, что одновременно является и его единственным недостатком.
Поковыряться в коде можно здесь.
В завершение, ещё раз посмотрите демо и при желании, для более детального разбора, скачивайте исходники, которые я бережно упаковал в архив, и выложил на своём Яндекс.Диске:
Буду всем признателен, если поддержите проект — добавив блог в исключения AdBlock и поделитесь ссылкой на запись в своих соц-сетях:
Здравствуйте, Андрей!
Я могу сделать на кнопку(просто так скажем картинку) ссылку на сайт, при открывании которого получается модальное окно с формой подписки. Как это можно осуществить?
Заранее благодарю за ответ.
С уважением, Марина
Здравствуйте, Марина!
Если я вас правильно понял, вам нужно модальное окно всплывающее при загрузке сайта. Внешний вид окошка другой, но его очень легко подогнать. Модальное окно открывается после полной загрузки страницы по истечении 5 секунд, время задержки можете выставить другое.
Если это оно самое, вам остаётся только встроить в тело окошка нужную вам форму.
Будут вопросы, пишите.
очень классный сайт, много что для себя из него подчеркнул. Спасибо!
есть вопрос, возможно вы поможете в его решении ))
интересует как можно сделать всплывающее модальное окно (попап) на определенной минуте при проигрывании видео, к примеру с youtube.
я видел такое есть но как реализовать?
Здравствуйте, Максим!
Спасибо за отзыв. По вашему вопросу, как-то не было необходимости, да и в целом, к всякого рода всплывающим окнам отношусь, мягко говоря — отрицательно, делаю их только виде экспериментов, и поиска новых решений. «Попапы» при проигрывании видео, вообще считаю извращением, но оно кому-то надо, а значит есть и готовые решения. Если не особо вдаваясь в подробности, так сказать на вскидку:
У видео (в html) есть такое свойство
currentTime
, определяет текущее время воспроизведения. По нему можете проверять на какой сейчас секунде видео находится пользователь и исходя из этого, выводить все что нужноВ js это будет примерно так:
var video = document.getElementsByTagName(“video”)[0];
var checkPoint = 150 // измерения в секундах
//каждый раз, когда текущее время меняется
video.ontimeupdate = function () {
if(video.currentTime != checkPoint) return;
/* тут все что хотите выполнить, когда достигается нужная точка времени */
}
var video = document.getElementsByTagName(“video”)[0];
var checkPoint = 150 // измерения в секундах
//каждый раз, когда текущее время меняется
video.ontimeupdate = function () {
if(video.currentTime != checkPoint) return;
/* тут все что хотите выполнить, когда достигается нужная точка времени */
}
Как это будет работать на практике, не проверял, думаю, логично будет прикрутить функцию вызова мод.окна работающего на jQuey. Приведённый выше пример, никак не относится к модальным окнам из статьи.
ок, спасибо! будем применять на практике!
Вам успехов и ждем новых постов!
Классный пример, но я не могу до конца понять.
Подскажите, как браузер понимает, что при нажатии на кнопку Отлично нужно закрыть модальное окно?
При нажатии кнопки «Закрыть» используем атрибут
aria-hidden
со значениемtrue
. С кнопкой «отлично» так же как и с любыми чекбоксами, один клик по кнопке «открыть» ставит галочку(в нашем случае открывает окно), повторный клик галочку снимает(закрывает окно). Тоже самое происходит и при нажатии вне модального окна, так как фон затемнения тоже скрытый чекбокс)))а возможно с нажатием кнопки «Открыть» передать get параметры?
Спасибо большое, все супер. Только есть одно большое «но» — не работает на мобильных устройствах 🙁 Ни на яблоках, ни на андроидах. Подскажите, есть возможность заставить работать? Очень-очень нужно.
Заранее огромное спасибо за ответ!
Спасибо, большое спасибо!
Вам спасибо за отзыв.
Валидатор матерится , хер просциш , че ему не нравится !
Line 1029, Column 51: The for attribute of the label element must refer to a form control.
… …
+ офигенно полезная штука для opencart, если для seo нужно убрать к чертям таблицы и разнести все как на allo.ua или на розетке , без использования скриптов (иначе page speed тебя сожрет криком «отключите скрипты или отложите их загрузку» ),а саму форму отзывов и комментариев разместить внутри модального окна! удобно и юзеру нравится ! из правок для планшетов 7# я бы только заменил % отступа от верха страницы , потому-что если форма большая доступа к низу формы нету, а портить вид скроллом не xочется !
Здравствуйте, подскажите как сделать чтоб, форма передовала значение переменных через POST,в вашем примере невозможно и через get передать.
Большое спасибо, очень помогли!
Андрей,помогите!
Я новичек. Помогите пожалуйста привязать css кнопку типа callbackhunter звонка к вашему модальному окну с формой обратной связи? Чтобы при нажатии на
кнопку всплывало окно. Помогите это сделать. Сейчас получается кнопка мерцает но при нажатии не появляется окна. Очень буду рад помощи.Сильно,сильно
надо.
Выложил: http://jsfiddle.net/Heloboy/cd8sjz71/
Здравствуйте, Илья.
Вот посмотрите: Тынц
Ваш архив посмотрю немного позже и результат отправлю на мыло.
Остается только вопрос — а как этим модальным окном перекрыть вообще все, что отображается на текущей странице.
Самое простое, это уменьшить или вовсе убрать прозрачность слоя затемнения.
Если же вам нужно окно во весь экран установите
width: 100%;
и исключитеmax-width
из стилей блока модального окна.modal-dialog
.Добавьте высоту
height: 100%;
и уберите отступ от верхнего края при появленииtop: 20%;
, установив нулевое значение.В этом случае, на мой взгляд, получается форменное извращение, а не модальное окно)))
Здравствуйте! Спасибо за ваш код, очень понравился. Но остались проблема: имеется таблица, в ней ячейки с картинками, и нужно чтобы при клике на какую-либо ячейку появлялось модальное окно.
Если я вас правильно понял и не особо вдаваясь в подробности, то примерно так: Тынц
Спасибо! Осталась еще одна проблемка: как поместить swf-анимацию в модальное окно? Искал решения в интернете, но там либо плагины, либо за деньги.
Не получается добавить в ваш пример выше swf-объект, помогите:
На IE 11 не работает, на IE 10 чекбоксы видны. Кто то решил эти проблемы?
Здравствуйте.
А никаких проблем и нет, в IE10 и 11 всё прекрасно работает: yadi.sk/i/mHERCq_tkfkfc , даже девятка пережевывает, правда без плавных переходов
Прошу прощенья, с IE 11 я где то не углядел, ваше демо работает, у меня на сайте нет буду разбираться. А в 10-ке prntscr.com/96bvts чекбоксы не скрыты, прикладываю скрин.
Андрей, спасибо Вам огромное! Всё разжевано и в рот положено в очередно раз! Приятно смотреть, читать и применять на практике ваши советы!
Алексей, за отзыв спасибо. Очень рад, что вам пригодилось)))
Очень полезный код. Спасибо большое! Единственное не могу найти, где указать email, на который прийдут данные с формы? Спасибо.
Ruslan, спасибо за отзыв.
Форма обратной связи здесь использована лишь в качестве примера возможностей использования модальных окон. Для полноценной работы формы вам потребуется подключить php-обработчик, вот именно в нём и указываете мыло, на которое будут приходить сообщения.
По скриптам-обработчикам и привязке их к формам, информации в интернетах предостаточно.
Здравствуй, не могу разобраться как мне сделать дублирующую ссылку на модальное окно. Если я указываю Заказать обратный звонок! то первая ссылка которая с иконки телефона перестает работать. Менял «modal-1» на «modal-2» Думал может так разделятся, все равно. Спаисбо
Здравствуйте! Спасибо огромное за полезнейшие уроки!)
Я пытаюсь использовать ваше модальное окно как окно регистрации пользователей, но у меня возникает проблема: после нажатия кнопки «регистрация» модальное окно закрывается.
Можно это как то исправить? мне нужно сообщить пользователю что всё хорошо или неверно введенно что то, а окно закрывается.
Заранее Спасибо!)
пс…мой код:
<div class="login"> <label title="Контактная форма в модальном окне" for="modal-2">Регистрация</label>
<div class="modal">
<input class="modal-open" id="modal-2" type="checkbox" hidden>
<div class="modal-wrap" aria-hidden="true" role="dialog">
<label class="modal-overlay" for="modal-2"></label>
<div class="modal-dialog">
<div class="modal-header">
<label for="modal-2" aria-hidden="true">X</label>
</div>
<div class="modal-body"> <?php
$connect = mysql_connect('localhost','root') or die(mysql_error());
mysql_select_db('Formoza'); if (isset($_POST['submit'])) {
$name = $_POST['name'];
$login = $_POST['login'];
$password = $_POST['password'];
$r_password = $_POST['r_password'];
if ($password == $r_password){
echo('OK');
}
else{
echo('Пароли не совподают!');
}
} ?>
<form metod="post" action="index.php">
<input type="text" name="name" placeholder="Ваше имя" required><br>
<input type="text" name="login" placeholder="Ваш логин" required><br>
<input type="password" name="password" placeholder="Ваш пароль" required><br>
<input type="password" name="r_password" placeholder="Повторите пароль" required><br><br>
<input type="submit" name="submit" value="Регистрация">
</form> </div>
</div>
</div>
</div>
</div>
У меня не работает 🙁 ничего не происходит по клику, хотя стили прописаны также
Моё демо у вас работает? Если да, то ищите ошибку на своей стороне. Проверьте путь до файла стилей, посмотрите отображаются ли они в инспекторе (F12 в Ghrome), в левой панели выбираете элемент модального окна и в правой панели смотрите, присутствуют ли необходимые селекторы, нет, значит отсутствует привязка к html.
Помогите изменить способ вызова модального окна с элемента lable на button! Поисковики индексируют тег lable, а мне не нужен лишний мусорный текст…
Заранее спасибо!
Привет всем! Друзья, подскажите пожалуйста как сделать чтобы модальное окно отображалось не по середине, а ближе к верхнему полю?
Очень просто. Находите селектор
.modal-open:checked ~ .modal-wrap .modal-dialog
и устанавливаете нужное значение в свойствеtop
. В примере у меня 20% от верхнего краяtop: 20%;
, вам достаточно уменьшить это значение до необходимого, можете вплоть до нуля. Отрицательные же значения, выведут окно за пределы верхнего края страницы, собственно на этом и построено скрытие модального окна.Здравствуйте, подскажите, как разместить ссылку в модальном окне на якорь на странице. Например, «#comments». Чтобы при клике на нее был одновременно переход к этому якорю и закрытие модального окна?
Крайне редко оставляю комментарии и этот случай — нонсенс! Вы помогли решить мою проблему красиво и ровно так, как надо! Поле действий ни в какую не хотело принимать якорные ссылки, а засорять скриптами код не есть комильфо. Чек боксы — то, что нужно! Спасибо!!
Здравствуйте! А как сделать чтобы окно закрывалось автоматически через например 5 секунд?
Скажите пожалуйста, а как открывать (показывать) модальное окно при наведении на кнопку, а не клике?