Модальное окно (lightbox) на CSS.

При открытии модального окна весь экран "гаснет" и на первый план выходит определённый элемент. Его создание не сложно.

Модальное окно с прокруткой

Для большого объёма контента, когда требуется прокрутка, скроллинг body, а не содержимого всплывающей записи вызывает неудобство.

Название. Если оно очень длинное, то обрезается, когда не помещается в одну строку, в конце появляется многоточие.
<!-- CSS прописать один раз -->


<!-- input, label и div идут друг за другом, между ними не должно быть других тегов. for тот же, что и id.
id должен использоваться на странице только единожды. То есть, чтобы создать несколько всплывающих элементов, нужно всем input задать один класс lightbox, но разные id. -->
<input type="checkbox" id="dva" class="lightbox1"/>
<label for="dva">образец</label>
<div><div>
  <label for="dva"></label>
  <div>
    <div>Название<label for="dva">✖</label></div>
    <div>Модальное окно для большого содержания</div>
  </div>
</div></div>

<!-- пока красивого решения убрать скролл body я не вижу. Могу предложить в input добавить обработчик событий JavaScript -->
<script>
var inp = document.getElementsByClassName('lightbox1');
for (var i = 0; i < inp.length; i++) {
  inp[i].onclick = function() {
    document.documentElement.style.overflow=(this.checked ? 'hidden' : 'auto');
    document.documentElement.style.marginRight=(this.checked ? '17px' : '');
  }
}
</script>

Простое модальное окно с затемнением

Если в нём разместить небольшое содержание, например, форму обратной связи, форму регистрации, форму "заказать обратный звонок" или текстовое сообщение, то оно будет располагаться по центру.

форма обратной связи

Видео YouTube в модальном окне

переправа
<style>
img[src$="/mqdefault.jpg"] + iframe {
  position: fixed;
  z-index: 11;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  -moz-box-sizing: border-box; box-sizing: border-box;
  border: solid rgba(0,0,0,.3);
  border-width: 5vh 5vw;
}
</style>

<img title="видео: переправа" alt="переправа" src="http://img.youtube.com/vi/JMJXvsCLu6s/mqdefault.jpg" height="180" width="320" class="tr-caption-container"/>

<script>
var img = document.querySelectorAll('img[src$="/mqdefault.jpg"]');
for (var i = 0; i < img.length; i++) {
  img[i].onclick = function() {
    var idImg = this.src.replace(/http...img.youtube.com.vi.(.*?).mqdefault.jpg/gi, '$1');
    theIframe = document.createElement('iframe');
    theIframe.src = '//www.youtube.com/embed/' + idImg + '?rel=0&autoplay=1';
    theIframe.onclick = function () {this.parentElement.removeChild(this);};
    this.parentNode.insertBefore(theIframe, this.nextSibling);
  }
}
</script>

Но возможно этот вариант всё же лучше?

Сделать, чтобы картинка была во весь экран при нажатии на неё

семья медведей лебедь

Если нужно только увеличение изображений при клике на них, то можно воспользоваться кодом ниже (не идеально: теги, выше элемента остаются активными):


<!-- размер фотографии, видимой на HTML-странице делается меньше, чем он есть на самом деле. При щелчке по картинке фото принимает свой настоящий вид -->
<img src="адрес" alt="" width="150" tabindex="0"/>
<img src="адрес" alt="" width="400" tabindex="0"/>
семья медведей лебедь

Второй способ основан на этой технике.


<!-- размер фотографии, видимой на HTML-странице делается меньше, чем он есть на самом деле. При щелчке по картинке фото принимает свой настоящий вид -->
<img src="адрес" alt="" width="150" class="zoom"/>
<img src="адрес" alt="" width="400" class="zoom"/>
Эффекты http://tympanus.net/codrops/2013/06/25/nifty-modal-window-effects/
в f t
наверх ↑

68 комментариев:

Tanka
Последний код надо указывать в нужном месте сообщения? Вместо слова "Содержание" надо указывать свое слово или ссылку на картинку?
Xstroy
Спасибо. Очень понравилась данная реализация. Думаю попробовать применить в своих постах.
Люблю использовать говорящие фото, а этим методом можно на порядок увеличить их эффект.
NMitra
Правильно.

"Содержание" может быть любое: текст, таблица, картинка (тег img), скрипт и т.д.
Александр
Здравствуйте, Наталья. Как бы Вы предложили модифицировать
этот код (именно этот код, без создания новой вкладки или окна), чтобы по клике на картинке открывалось окошко со страничкой с другого сайта?
Важно, чтобы подгружаемая страничка не грузилась до клика.
NMitra
По-поводу страницы другого сайта, на ум приходит только использование IFRAME, которое можно положить в DIV.

В этой реализации страница будет загружаться полностью, только её часть будет скрыта до клика. Нужно применить другой метод.
Онлайн
Спасибо. 1 вариант больше нравится кстати)
NMitra
Мне тоже)
Анонимный
1 вариант однозначно лучше.

http://softodle.ru/
NMitra
Посмотрела в Хроме, так второй выигрывает.
Анонимный
первый у меня в фаерфоесе ваще криво как то.второй нормалек!
Владислав
Все бы ничего, но есть один минус, использовать можно только 1 окно, а если к примеру я хочу использовать 10 модальных окон?
NMitra
Да, получается, что каждый раз нужно прописывать код с новым id.
Вашковцы
Средствами php легко.
Большое спасибо, очень искал, негде не нашол такого хорошего решения.
Кликну на рекламе.
Анонимный
Что именно нужно сделать чтоб прописать дольше изображений , чему именно менять id ?:)
NMitra
Я подумаю на недельке. Статью немного перепишу. Ориентируйтесь пока на этот пример http://www.cssplay.co.uk/menu/lightbox-hover.html

Варианты увеличения изображений http://shpargalkablog.ru/2011/05/kak-uvelichit-izobrazhenie.html и http://shpargalkablog.ru/2012/01/pri-navedenii-na-kartinku-ona.html Последний мне особо импонирует.
Asaf Bakhshiyev
Здрасте)Я вапще не разбераус в этом.открыл себе блог недавно.хотел б добавить модальное окно.Вопрос: Куда надо вставить эти тексты.Было б лучше если б вы более подробно написали об этом.Например вот текст и сюда вот вставте.Очень признателен за такие уроки).Блогодарю
NMitra
Смотря куда. Если единожды в тело сообщения, то посмотрите картинку отсюда http://shpargalkablog.ru/2012/04/script-parolya-na-stranitsy.html , потренируйтесь, посмотрите вариант, который наиболее подходит.

Если многократно хотите применять (во многих сообщениях), то стили CSS лучше убрать в шаблон http://shpargalkablog.ru/2011/12/kak-izmenit-shablon-blogger.html . Но только после того, как потренируетесь на сообщении.

Стили CSS - это код между

<style type="text/css">
...содержание...
</style>

А именно только "содержание" без тега style ( http://shpargalkablog.ru/2011/08/kak-ispolzovat-css.html )
Анонимный
00
Анонимный
SЗамечательный код, спасибо большое.

Единственная загвоздка с вариантом видео, закрываешь окошко с видео, а оно продолжает дальше работать фоном, пока в ютубе его не остановишь.
Есть ли здесь решение?

Olesya
NMitra
Олеся, это CSS, только внешнее оформление. Вам нужно посмотреть альтернативные варианты на JavaScript или PHP.
Анонимный
Здравствуйте. Нужна ваше помощь=)

Мне нужно что бы в модельном окне отображалась html страница: почему когда я у iframe прописываю адрес этой страницы то: в "Opera" у меня всё отображается отлично, а в "Chrome" всё модельное окно оказывается под слоем a[href="#close"], то есть всё окно затемнено, скроллинг недоступен потому что везде активна ссылка #close.

Подскажите пожалуйста чайнику)) это дело можно как-то поправить?
Анонимный
Отбой.)) Ложная тревога =) Проблема решена следующим образом: в классе lightbox удалил параметр position: fixed;
Анонимный
Да... сложно быть чайником)) Но уже у всём разобрался. Спасибо за ваш отличный ресурс!
NMitra
Вовсе нет, вы задали очень нужный вопрос. Когда я писала статью, не проверяла в Хроме, а он подкидывает сюрпризом не меньше IE. Попозжей посмотрю.
kjhmnbm,
Доброго времени суток! Вопрос такой, глюк возникает в IE 10 что первый раз когда кликаешь на картинку все ок, а вот когда второй раз ее вызываешь то блок не загружается. Куда нужно копать?
NMitra
Хороший вопрос. Предполагаю в сторону процентов. Будет время, перепишу статью на следующей недели
NMitra
kjhmnbm,, если срочно нужно, посмотрите тут http://shpargalkablog.ru/2013/08/bell-site.html Очень здорово получилось, позже отредактирую статью.
Богдан Дорин
Подскажите пожалуйста что именно нужно прописать что бы блок растягивался под содержимое,а то чёт туплю и не как не получается,спасибо
NMitra
Что там у вас получилось? Покажите ссылку.
Анонимный
Народ! В хроме первый пример перекрывается темным фоном, т.е. ссылкой на закрытие. Поэтому дальнейшая работа с открытым окном не представляется возможной.
NMitra
Никак не перепишу статью. Ловите код. Думаю, вы сможете его довести до ума:

<style>
.lightbox {
  display: none;
  height: 100%; width: 100%;
  position: fixed; top: 0%; left: 0%;
}
.lightbox:target {
  display: block;
}
.lightbox div {
  display: block;
  position: absolute; top: 50%; left: 50%; z-index: 1;
  transform: translate(-50%, -50%);
  border: 1px solid red;
  background: #fff;
}
a[href="#close"] {
  position: fixed; top: 0; bottom: 0; right: 0; left: 0;
  background: rgba(0, 0, 0, .6);
}
</style>

<a href="#showimage1" class="vkl">Îáðàçåö</a>
<div class="lightbox" id="showimage1">
<a href="#close">?</a>
<div>
      <img src="àäðåñ_èçî"/>
      Òåêñò
</div></div>
Sandro
Здравствуйте! Я правильно понимаю, что во всех приведенных случаях нужно загружать 2 фото-большое и превью? Мне надо чтоб увеличивалось одно имеющееся.
NMitra
Здравствуйте, учту ваши слова. Пока сделала упрощённый вариант, см. начало статьи.
Vladimir Knyazev
Очень понравилось окно, все работает прекрасно. Только серый повлиял на цвет ссылок в меню. Подскажите как исправить и что? Сайт http://never-vladimir.narod.ru/index/moj_teatr/0-6
Vladimir Knyazev
/* Site Menus */
.uMenuH li {float:left;padding:0 5px;}


.uMenuV .uMenuItem {font-weight:normal;}
.uMenuV li a:link {text-decoration:none; color:#8B8881}
.uMenuV li a:active {text-decoration:none; color:#8B8881}
.uMenuV li a:visited {text-decoration:none; color:#8B8881}
.uMenuV li a:hover {text-decoration:underline; color:#000000}

.uMenuV .uMenuItemA {font-weight:bold;}
.uMenuV a.uMenuItemA:link {text-decoration:none; color:#000000}
.uMenuV a.uMenuItemA:visited {text-decoration:none; color:#000000}
.uMenuV a.uMenuItemA:hover {text-decoration:underline; color:#0C5BFE}
.uMenuV .uMenuArrow {position:absolute;width:10px;height:10px;right:0;top:3px;background:url('/.s/img/wd/1/ar1.gif') no-repeat 0 0;}
.uMenuV li {margin: 0; padding: 0 0 0 13px; background: url('/.s/t/971/12.gif') no-repeat 0px 3px; margin-bottom: .6em;}
/* --------- */

/* Module Part Menu */
.catsTable {}
.catsTd {padding: 0 0 6px 13px; background: url('/.s/t/971/12.gif') no-repeat 0px 3px;}
.catName {font-family:Verdana,Tahoma,Arial,Sans-Serif;font-size:11px;}
.catNameActive {font-family:Verdana,Tahoma,Arial,Sans-Serif;font-size:11px;}
.catNumData {font-size:7pt;color:#555555;}
.catDescr {font-size:7pt; padding-left:10px;}
a.catName:link {text-decoration:none; color:#8B8881;}
a.catName:visited {text-decoration:none; color:#8B8881;}
a.catName:hover {text-decoration:underline; color:#000000;}
a.catName:active {text-decoration:none; color:#8B8881;}
a.catNameActive:link {text-decoration:none; color:#000000;}
a.catNameActive:visited {text-decoration:none; color:#000000;}
a.catNameActive:hover {text-decoration:none; color:#0C5BFE;}
a.catNameActive:active {text-decoration:underline; color:#000000;}
/* ----------------- */

/* Entries Style */
.eBlock {}
.eTitle {font-family:Verdana,Arial,Sans-Serif;font-size:13px;font-weight:bold;color:#779F00; padding: 0 0 0 15px; background: url('/.s/t/971/13.gif') no-repeat 0px 3px;}

.eTitle a:link {text-decoration:underline; color:#779F00;}
.eTitle a:visited {text-decoration:underline; color:#779F00;}
.eTitle a:hover {text-decoration:none; color:#000000;}
.eTitle a:active {text-decoration:underline; color:#779F00;}

.eMessage {text-align:justify;padding-bottom:5px;}
.eText {text-align:justify;padding-bottom:5px;padding-top:5px;border-top:1px solid #C2C2C2}
.eDetails {border:1px solid #D7D7D7;font-family:Verdana,Tahoma,Arial,Sans-Serif;color:#1A1A1A;padding-bottom:5px;padding-top:3px;text-align:left;font-size:7pt;background:#FFFFFF;}
.eDetails1 {border:1px solid #D7D7D7;font-family:Verdana,Tahoma,Arial,Sans-Serif;color:#1A1A1A;padding-bottom:5px;padding-top:3px;text-align:left;font-size:8pt;background:#FFFFFF;}
.eDetails2 {border:1px solid #D7D7D7;font-family:Verdana,Tahoma,Arial,Sans-Serif;color:#1A1A1A;padding-bottom:5px;padding-top:3px;text-align:left;font-size:8pt;background:#FFFFFF;}

.eRating {font-size:7pt;}

.eAttach {margin: 16px 0 0 0; padding: 0 0 0 15px; background: url('/.s/t/971/14.gif') no-repeat 0px 0px;}
/* ------------- */

/* Entry Manage Table */
.manTable {}
.manTdError {color:#FF0000;}
.manTd1 {}
.manTd2 {}
.manTd3 {}
.manTdSep {}
.manHr {}
.manTdBrief {}
.manTdText {}
.manTdFiles {}
.manFlFile {}
.manTdBut {}
.manFlSbm {}
.manFlRst {}
.manFlCnt {}
/* ------------------ */
Vladimir Knyazev
Вынесла стили из цсс на саму страницу и все восстановилось. как только вношу в общие - все сначала(( Наверное, придется оставить на станице((
NMitra
Ничего не поняла.

Объясните так: есть то-то, когда нажимаю на то-то, то должно происходить то-то, а происходит то-то.

Например, ссылки в блоке "Меню сайта" оранжевого цвета, нажимаю на фото человека, фото человека увеличивается, появляется затемняющий фон, а цвет ссылки становится белым. А я хочу зелёным.
Vladimir Knyazev
Были: ссылки в меню черного цвета. Вставила стиль от модального окна в общую таблицу стилей - и цвет ссылок в меню стал rgba(210,210,210,.4)
Удаляю из цсс и вставляю прямо на страницу - ссылки опять становятся как и должно черными. Пытаюсь найти логическую связь - и не могу.Сейчас оставила стиль на странице.
NMitra
Уберите

border: solid rgba(210,210,210,.4);
border-width: 100vh 100vw;

из кода модального окна
NMitra
или box-shadow: 0 0 20px #000, 0 0 0 1000px rgba(210,210,210,.4); из первого варианта
Vladimir Knyazev
Спасибо сейчас буду пробовать. Столько всего интересного и главное в доступной форме у вас в блоге! Многие люди умеют делать разные сложные вещи, но не все могут научить этому других. Спасибо еще раз.
NMitra
Благодарю, очень приятно слышать!
Анонимный
Кто подскажет... В первом варианте вывода изображения при открытии в окне почему то весь фон затемняется кроме полоски меню. И получается что увеличенная картинка находится под полоской меню.
NMitra
Нужно увеличить значение z-index: 10;
Макс
Классный примерчик! У меня проблемка в overflow: hidden -> overflow:visible. У меня слайдер из картинок в классе с overflow: hidden. Хочу чтобы при клике на картинку работал ваш zoom-images, переключая overflow на visible, иначе пока зум зумится внутри слайдера и ничего не видно. Возможно ли это? Спасибо!
NMitra
Честно говоря слабо понимаю что там у вас. Вот вариант, как может он работать http://shpargalkablog.ru/2014/02/gallery.html
Макс
прикрепил html с контентом вам в личку на почту! =)
Анонимный
#31 класс код) без всяких библиотек, гуглескриптов)))
NMitra
:))
dumptyhumpty
Спасибо за интересные практические примеры. Сделал на основе вашей галереи удобный сниппет для вордпресс. Если интересно, могу выдать исходники и инструкцию для применения - напишите статью )))
Использовал один из вышеописанных вариантов для работы увеличения на весь экран картинок.
Но есть один момент. Всякие pagespeed и другие анализаторы скорости загрузки, ругаются на то, что размер картинки изначально большой и его нужно подстраивать.
Можно набросать вариант (пусть хотя бы теоретический, сам поэкспериментирую и доведу до ума) такой, чтобы
Было примерно так: ссылка на качественную картинку /а>
при щелчке на картинку она увеличивалась до экрана (ссылка из тэга берется). При щелчке по большой фотке обратно. Цель: большие картинки индексируются поисковиками, но не загружаются при открытии страницы.
Ну и как дополнение, вариант, чтобы картинки не индексировались, т.е. чтоб не src, а к примеру rel использовался? Сделаю на основе этого сниппет, опять же, напишите статью )
В идеале, маленькая картинка - превью и "галерея", хоть из одной фотки, хоть из многих, чтобы грузилась только одна превьюшка, а остальные подгружались по необходимости.
Хотя бы намек, куда копать. Через after реализовать? или как проще?
dumptyhumpty
Выше я имел в виду, что сделал из галереи шорткоды для вордпресс, чтоб не набирать код каждый раз в ручную. Для увеличения картинки (в одну или в галерею) так же могу сделать, так что объем кода не пугает.
NMitra
По URL.

http://2.bp.blogspot.com/-NEvSypEsQv0/TZQ1tka_UwI/AAAAAAAABqo/qjYR-YSjjws/s400/mishki.jpg - миниатюра
http://2.bp.blogspot.com/-NEvSypEsQv0/TZQ1tka_UwI/AAAAAAAABqo/qjYR-YSjjws/s00/mishki.jpg - полный размер

Стилями задавать позиционирование, JavaScript-ом менять кусок URL при click на картинку. Ссылки не нужны.
NMitra
Хм, при фокусе на картинку, а не click.
dumptyhumpty
Т.е. без JS в таких случаях никак?
То, что в это статье (лебеди и мишки) у меня по клику работает. Т.е. оставляем стили такими для изменения размера, а еще добавляем скрипт, который при фокусе меняет урл картинки. Где "хранить" урлы тогда?
А нельзя "соединить" вариант с img[tabindex="0"] и что-то из вашего же http://shpargalkablog.ru/2012/01/pri-navedenii-na-kartinku-ona.html?
dumptyhumpty
А код в статье совсем недавно менялся? а то у меня с использованием класса zoom-image...
Идея с "При фокусе меняем урл", "при клике размер во весь экран" очень нравится.
будет ли работать что-то вроде того, если в выше описанный код с tabindex="0" вставить что-то вроде
i mg[tabindex="0"]:hover{src="урл на большой размер" а вот сюда i mg[tabindex="0"] {
cursor: zoom-in; вставить src=урл миниатюры
}
dumptyhumpty
Хотя и правда , проще обрамлять картинку ссылкой на js скрипт, который меняет туда-сюда урлы...
Эх и тяжко у вас тут :) и профиль выбирать и потом еще капчу заполнять :)
dumptyhumpty
Вот здесь, как я понимаю изначально задумывалось передавать урлы в функцию!?
"s cript>function miniatuyra3(cual,url) {var imagen1 = "уменьшенная_картинка";var imagen2 = "исходный_рисунок";var imagenactual = cual.src;if(imagenactual==imagen1) {cual. src = imagen2;} else {cual. src = imagen1;}} s cript>

i mg on click="miniatuyra3(this);" s rc="уменьшенная_картинка"/>"
Почему отказались? в миниатюру3 передается объект картинка и вторым параметром урл? т.е. можно же сделать универсальную функцию по типу miniatuyra3(cual, url1, url2) хотя в этом случае не снимается вопрос индексации большой картинки, но это можно решить как-то по другому )))
NMitra
Спама много шибко.

Комментарий 55: только для
1) background-image http://shpargalkablog.ru/2011/08/fon-dlya-saita-html.html#image
2) :before { content: url(адрес); } http://shpargalkablog.ru/2012/02/before-after-css.html (Хм, неплохая идея, но нужна ещё одна обёртка).

Комментарий 57: http://dev.opera.com/articles/responsive-images/ (Это для индексации)
dumptyhumpty
Сделал через маленький скриптик, за основу взял, который ваш и я упомянул в 57 комменте.
Я вешаю скрипт на onfocus и сравниваю только один раз, т.е. если урл у меня не сходится с переданным, то я подставляю переданный.
На onClick не работало вместе с CSS. Теперь могу ставить маленькие изображения, а при наведении и потом клике подменяется урл и дальше увеличивается/уменьшается уже оригинал :)
Спасибо за подсказки. Лайкнул в фейсбуке.
NMitra
См. скрипт http://jsfiddle.net/NMitra/jwnsj5fq/ С помощью регулярных выражений можно вычислять /s150/ и /s300/ и /s400/... Поскольку большая картинка уже загружена, то смысла делать onblur нет. Достаточно прописать атрибут width и/или height.
dumptyhumpty
Случайно не в курсе, почему-то на айфоне верхний вариант, где табиндекс=0, отрабатывает на увеличение картинки, а вот обратно не отрабатывает. То ли я не так под себя подогнал, то ли просто ~ * {
pointer-events: none; не отрабатывает почему-то...
NMitra
http://caniuse.com/#feat=pointer-events Хотя некоторые свойства имеют различие в поддержке на разных устройствах.
NMitra
Зачем на айфоне картинки увеличивать? По хорошему на телефоне нужно избавляться от бокового меню, а картинки в ряд прописать.
Ralina
У меня такая проблема. Картинка увеличивается, фон затемняется, но сайт за картинкой остается активным, т.е. я могу нажать на другую картинку сквозь увеличенную. Что с этим делать?
NMitra
Да, есть такая проблема, родительский селектор пока не принят браузерами. Поэтому нужно сделать div на том же уровне, что и картинки, как тут http://shpargalkablog.ru/2014/02/gallery.html
Ralina
Не могли бы вы объяснить поподробнее, если не сложно? Просто я почти ноль в этом. Дело в том, что я делаю не галерею (так то она идеально работает), а увеличение картинок в постах блога по нажатию. Т.к. знаю я мало, бьюсь над этим уже долго... Я использовала ваш код, и он слава богу работает (спасибо вам за это огромное), но этот ньанс всё портит. Чтобы это исправить, я создала див для"подкладки" и поместила его в... в то что моделирует посты с фото?... :D но он не исчезает, а постоянно находится на странице, и блокирует вообще всё. Яяя уже не знаю что делать, ума не хватает, гугл не помогает

код подложки .black{
color:#000000;
position:fixed;
height:100%;
width:100%;
z-index:15000;
}

код для формирования постов
{block:Photo}

{/block:Photo}

ссылка на блог если надо http://imreertest.tumblr.com/
Ralina
Для постов стерся почему-то...
NMitra
В вашем случае трудно сделать, у каждой картинки свой родитель. Остаётся только дождаться, когда начнёт действовать родительский селектор.