Как создать простое модальное окно на CSS

Содержание:
  1. Демо модального окна
  2. HTML и CSS код модального окна
  3. Комментарии

Статья, в которой рассмотрим, как сделать адаптивное модальное окно на чистом CSS.

Как создать модальное окно на чистом CSS

Модальные (всплывающие) окна – это очень популярный элемент интерфейса современных сайтов. Оно может использоваться для вывода различного контента веб-страниц такого, например, как формы (обратной связи, регистрации, авторизации), блоки рекламной информации, изображения, уведомления и др.

В большинстве случаев модальное окно создают на JavaScript. Но его можно создать не только с помощью JavaScript, но и посредством только HTML5 и CSS3.

Демо модального окна

Демонстрацию всплывающего окна, работающего только на HTML5 и CSS3, вы можете посмотреть здесь:

Демо модального окна на CSS

HTML и CSS код модального окна

HTML разметка модального окна:

HTML
<div id="openModal" class="modal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h3 class="modal-title">Название</h3>
        <a href="#close" title="Close" class="close">×</a>
      </div>
      <div class="modal-body">    
        <p>Содержимое модального окна...</p>
      </div>
    </div>
  </div>
</div>

Ссылка, с помощью которой осуществляется открытие модального окна:

HTML
<!-- openModal - id модального окна (элемента div) -->
<a href="#openModal">Открыть модальное окно</a>

CSS модального окна:

CSS
/* стилизация содержимого страницы */
body {
    font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
    font-size: 16px;
    font-weight: 400;
    line-height: 1.5;
    color: #292b2c;
    background-color: #fff;
} 
  
/* свойства модального окна по умолчанию */
.modal {
    position: fixed; /* фиксированное положение */
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0,0,0,0.5); /* цвет фона */
    z-index: 1050;
    opacity: 0; /* по умолчанию модальное окно прозрачно */
    -webkit-transition: opacity 200ms ease-in; 
    -moz-transition: opacity 200ms ease-in;
    transition: opacity 200ms ease-in; /* анимация перехода */
    pointer-events: none; /* элемент невидим для событий мыши */
    margin: 0;
    padding: 0;
}
/* при отображении модального окно */
.modal:target {
    opacity: 1; /* делаем окно видимым */
	  pointer-events: auto; /* элемент видим для событий мыши */
    overflow-y: auto; /* добавляем прокрутку по y, когда элемент не помещается на страницу */
}
/* ширина модального окна и его отступы от экрана */
.modal-dialog {
    position: relative;
    width: auto;
    margin: 10px;
}
@media (min-width: 576px) {
  .modal-dialog {
      max-width: 500px;
      margin: 30px auto; /* для отображения модального окна по центру */
  }
}
/* свойства для блока, содержащего контент модального окна */ 
.modal-content {
    position: relative;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    background-color: #fff;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
    border: 1px solid rgba(0,0,0,.2);
    border-radius: .3rem;
    outline: 0;
}
@media (min-width: 768px) {
  .modal-content {
      -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5);
      box-shadow: 0 5px 15px rgba(0,0,0,.5);
  }
}
/* свойства для заголовка модального окна */
.modal-header {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-align: center;
    -webkit-align-items: center;
    -ms-flex-align: center;
    align-items: center;
    -webkit-box-pack: justify;
    -webkit-justify-content: space-between;
    -ms-flex-pack: justify;
    justify-content: space-between;
    padding: 15px;
    border-bottom: 1px solid #eceeef;
}
.modal-title {
    margin-top: 0;
    margin-bottom: 0;
    line-height: 1.5;
    font-size: 1.25rem;
    font-weight: 500;
}
/* свойства для кнопки "Закрыть" */
.close {
    float: right;
    font-family: sans-serif;
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
    color: #000;
    text-shadow: 0 1px 0 #fff;
    opacity: .5;
    text-decoration: none;
}
/* свойства для кнопки "Закрыть" при нахождении её в фокусе или наведении */
.close:focus, .close:hover {
    color: #000;
    text-decoration: none;
    cursor: pointer;
    opacity: .75;
}
/* свойства для блока, содержащего основное содержимое окна */
.modal-body {
  position: relative;
    -webkit-box-flex: 1;
    -webkit-flex: 1 1 auto;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 15px;
    overflow: auto;
}
Модальное окно на чистом CSS

Если вам необходимо убрать скролл страницы после отображения модального окна, то к элементу body нужно добавить CSS-свойство overflow со значением hidden. А после скрытия модального окна данное свойство убрать у элемента body. Данное действие можно осуществить только с помощью JavaScript:

JavaScript
document.addEventListener("DOMContentLoaded", function(){
  var scrollbar = document.body.clientWidth - window.innerWidth + 'px';
  console.log(scrollbar);
  document.querySelector('[href="#openModal"]').addEventListener('click',function(){
    document.body.style.overflow = 'hidden';
    document.querySelector('#openModal').style.marginLeft = scrollbar;
  });
  document.querySelector('[href="#close"]').addEventListener('click',function(){
    document.body.style.overflow = 'visible';
    document.querySelector('#openModal').style.marginLeft = '0px';
  });
});

Комментарии: 80

aelita
aelita
Здравствуйте, почему после закрытия второго модального окна пропадает скроллинг вниз страницы?
serge r
serge r
Здравствуйте. А как сделать, чтобы нижний край модального окна не «уезжал» за границы видимой области в случае, если много контента?
AA
AA
Добрый день, а как можно настроить чтоб модальное окно появлялась автоматом, например у меня есть ajax запрос там к примеру данные всегда выше 600, если будет 500, то сработает модальное окно, можно так настроить?
Анастасия
Анастасия
Доброго времени суток
Я дублирую html блок с разным описанием, но отображается содержание только первого блока. Можете, пожалуйста, подсказать как решить эту проблему?
Заранее спасибо
Анастасия
Анастасия
Александр Мальцев
Александр Мальцев
Привет!
Тут нужно просто установить разным модальным окнам разные id:
<div id="openModal-1" class="modal">...</div>
<div id="openModal-2" class="modal">...</div>
<div id="openModal-3" class="modal">...</div>
После этого указать какая ссылка какое модальное окно должна открывать:
<a class="button" href="#openModal-1">...</a>
<a class="button" href="#openModal-2">...</a>
<a class="button" href="#openModal-3">...</a>
Песочница: открыть пример
Сергей
Сергей
Подскажите пожалуйста, как изменить скрипт чтоб он работал не только на главной странице сайта, но и на внутренних. Когда я на внутренней странице открываю окно, то автоматом перехожу на главную. Подскажите как исправить код.
document.addEventListener('DOMContentLoaded', function () {
  var scrollbar = document.body.clientWidth - window.innerWidth + 'px';
  console.log(scrollbar);
  document.querySelector('[href="#otkrutokno"]').addEventListener('click', function () {
    document.body.style.overflow = 'hidden';
    document.querySelector('#otkrutokno').style.marginLeft = scrollbar;
  });
  document.querySelector('[href="#zakrutokno"]').addEventListener('click', function () {
    document.body.style.overflow = 'visible';
    document.querySelector('#zakrutokno').style.marginLeft = '0px';
  });
});
Александр Мальцев
Александр Мальцев
Вам необходимо при нажатии на ссылку отменить стандартное действие браузера, т.е. вызвать метод preventDefault:
document.addEventListener('DOMContentLoaded', function () {
  var scrollbar = document.body.clientWidth - window.innerWidth + 'px';
  document.querySelector('[href="#otkrutokno"]').addEventListener('click', function (e) {
    e.preventDefault();
    document.body.style.overflow = 'hidden';
    document.querySelector('#otkrutokno').style.marginLeft = scrollbar;
  });
  document.querySelector('[href="#zakrutokno"]').addEventListener('click', function (e) {
    e.preventDefault();
    document.body.style.overflow = 'visible';
    document.querySelector('#zakrutokno').style.marginLeft = '0px';
  });
});
Сергей
Сергей
Вставил Ваш код и почему то окно вообще перестало открываться(.Спасибо что быстро отвечаете.
Александр Мальцев
Александр Мальцев
В этом случае вызывать окно следует с помощью JavaScript, либо убирать preventDefault и прописывать полный URL (это у вас из-за того, что в HTML коде имеется атрибут base).
Сергей
Сергей
Вот прописал полный урл (правильно?) но работает как работал. а атрибут Base нужен для сео?
document.addEventListener('DOMContentLoaded', function () {
  var scrollbar = document.body.clientWidth - window.innerWidth + 'px';
  console.log(scrollbar);
  document.querySelector('[href="[[++site_url]]#otkrutokno"]').addEventListener('click', function () {
    document.body.style.overflow = 'hidden';
    document.querySelector('[[++site_url]]#otkrutokno').style.marginLeft = scrollbar;
  });
  document.querySelector('[href="#zakrutokno"]').addEventListener('click', function () {
    document.body.style.overflow = 'visible';
    document.querySelector('#zakrutokno').style.marginLeft = '0px';
  });
});
Александр Мальцев
Александр Мальцев
Здесь тогда нужно прописывать полный путь к странице, а не [[++site_url]].
Второй вариант — это сделать через JavaScript, как предлагал выше (открыть пример).
Для этого в CSS вставляем следующее правило:
.modal.open {
  opacity: 1;
  pointer-events: auto;
  overflow-y: auto;
}
В JavaScript добавляем класс «open» при нажатии на ссылку и удаляем его при нажатии на кнопку «Закрыть»:
document.addEventListener('DOMContentLoaded', function () {
  var scrollbar = document.body.clientWidth - window.innerWidth + 'px';
  var $modalWindow = document.querySelector('#otkrutokno');
  document.querySelector('[href="#otkrutokno"]').addEventListener('click', function (e) {
    e.preventDefault();
    $modalWindow.classList.add('open');
    document.body.style.overflow = 'hidden';
    document.querySelector('#otkrutokno').style.marginLeft = scrollbar;
  });
  document.querySelector('[href="#zakrutokno"]').addEventListener('click', function (e) {
    e.preventDefault();
    $modalWindow.classList.remove('open');
    document.body.style.overflow = 'visible';
    document.querySelector('#zakrutokno').style.marginLeft = '0px';
  });
});
А как атрибут base влияет на SEO? Не встречал информации на эту тему.
Сергей
Сергей
все работает спасибо огромное, только в формах на сайте перестала работать функция в форме &submitVar=`pred` она помогала отличать формы друг от друга, а сейчас при нажатии на одну кнопку в форме отправляются все формы со страницы. Оно добавляло в скрытое поле найм `pred`вот в это поле
<input type="hidden" name="pred" value="1" />
Сергей
Сергей
Точнее оно добавляло найм `pred`в кнопку отправить в форме
Александр Мальцев
Александр Мальцев
Так добавьте его в кнопку с помощью JavaScript.
Сергей
Сергей
попробовал добавить в поле найм значение и не получилось, отредактируете код как правильно.

<button  class="form-btn vol" type="submit" >Отправить </button>

   document.querySelectorAll("button.form-btn[name^='zvon']").forEach(item => {
  item.addEventListener("click", e => {
    let elem = e.currentTarget;
    let name = elem.getAttribute("name");
    document.querySelector("button.form-btn>name").innerHTML = name;
  });
});

Александр Мальцев
Александр Мальцев
Опишите подробнее что вы хотите сделать, а то не совсем понятно, как вам его поправить. Сейчас у вас есть несколько кнопок «button.form-btn» с name, которые начинаются на zvon. При нажатии на них вы хотите добавить обработчик события click, в котором нужно получить значение атрибута name этой кнопки, а дальше?
Сергей
Сергей
мне нужно без обработчика просто чтоб name zvon при нажатию на кнопку ей присваивалась name zvon, чтоб кнопки в формах отличались друг от друга. а то при нажатии на одну кнопку срабатывают целые три формы на странице а хочется чтоб форма работала отдельно от остальных.
Если знаете как форму сделать независимой от остальных другим способом то я соглашусь на другой способ. Просто я какой знал способ отличия такой и использовал.
Александр Мальцев
Александр Мальцев
Можно просто кнопку с type="submit" поместить в форму (<form>...</form>), в этом случае будет отправляться только эта форма.
Сергей
Сергей
<button  class="form-btn vol" type="submit"  >Отправить </button>
вот кнопка, в ней есть type=«submit» и не работает. в остальных формах без джава скрипта работает &submitVar=`content` на двух формах. а с джава скриптом перестал работать &submitVar, у меня формы на Formit может поэтому не работает type=«submit»
Сергей
Сергей
.modal.open {
      opacity: 1;
      pointer-events: auto;
      overflow-y: auto;
    }

.modal помоему лишнее с ним не работает а без него работает
Александр Мальцев
Александр Мальцев
Сложно что-то посоветовать, т.к. не вижу полной картины. Для начала я бы проверил страницу (разметку) через валидатор w3c может какие-то теги не закрыты или что-то другое. Да, и CSS бы проверил через валидатор. А потом бы уже двигался дальше. Т.к., по сути, ничего не поменялось, изменения коснулись только открытия модального окна, какой-то взаимосвязи с формой тут не вижу.
Сергей
Сергей
steklograd-rostov.su/ вот сайт
Александр Мальцев
Александр Мальцев
Понял, вы хотите добавить к формам какой-то опозновательный признак. Тогда можно так:
const forms = document.querySelectorAll('form');
forms.forEach($form => {
  const name = $form.name;
  const $input = document.createElement('input');
  $input.type = 'hidden';
  $input.name = 'type';
  $input.value = name;
  $form.appendChild($input);
});
Теперь у вас в каждой форме будет находится скрытое поле с name=«type» и значением равное name формы:
<input type="hidden" name="type" value="zakazform">
Сергей
Сергей
поставил код сейчас и в остальных &submitVar перестал работать. наверное еще снопке button поле name добавлять.
Сергей
Сергей
попробовал создать кнопку button с таким же name как и в скрытом поле и не сработало.
const forms = document.querySelectorAll('form');
forms.forEach($form => {
  const name = $form.name;
  const $input = document.createElement('input');
 const $button = document.createElement('button');
$button.name = name;
  $input.type = 'hidden';
  $input.name = 'type';
  $input.value = name;
  $form.appendChild($input);
$form.appendChild($button);
});
Александр Мальцев
Александр Мальцев
Кнопки submit у вас в формах уже есть. Вам нужно просто к каждой из них добавить атрибут name со значением, например, равным значению этого атрибута у формы:
const forms = document.querySelectorAll('form');
forms.forEach($form => {
  const name = $form.name;
  const $input = document.createElement('input');
  $input.type = 'hidden';
  $input.name = 'type';
  $input.value = name;
  $form.appendChild($input);
  $submit = $form.querySelector('[type="submit"]');
  $submit.name = name;
});
После этого в вызовах сниппетах FormIt для обработки форм добавить параметр submitVar с соответствующим значением:
...
&submitVar=`dopolnitform`
...
&submitVar=`contactform`
...
&submitVar=`zakazform`
Сергей
Сергей
формы неработали когда я просто добавил &submitVar=`dopolnitform` а когда добавил название dopolnitform в скрытое поле то заработало как прежде с отправлением всех форм
<input type="hidden" name="dopolnitform" value="1" />
убераю это скрытое поле и форма опять не работает. Может у submit должно быть одинаковое имя с &submitVar=`dopolnitform`
Сергей
Сергей
начал проверять на своей почте вроде всё работает спасибо огромное. если будешь проверять формы то в имени пиши проверка чтоб не подумал на настоящий заказ.
Виталий
Виталий
Доброго дня.
Спасибо за текст. Вижу много времени прошло, но рискну задать вопрос.

1) Почему если поместить внутри ссылки картинку, то окно не появляется, только страница тускнеет?
2) не закрывается окно по клику на X, ( я пользую вариант из комментария где много окон)
Александр Мальцев
Александр Мальцев
Привет! Для этого нужно немного изменить JavaScript код (пример):
document.addEventListener('click', function (e) {
  let $target = e.target;
  if ($target.closest('[data-toggle="modal"]')) {
    e.preventDefault();
    $target = $target.closest('[data-toggle="modal"]');
    document.querySelector($target.dataset.target).classList.add('open');
  } else if ($target.dataset.close === 'modal') {
    e.preventDefault();
    $target.closest('.modal').classList.remove('open');
  }
});
Виталий
Виталий
спасибо.
Владимир
Владимир
Добрый день, Александр!
Я дублирую html блок под каждую новость, чтобы на главной любая аннотация переходила в полную (по Вашему примеру модального окна), но каждая из них лишь отображает содержание первого блока!
Пожалуйста, подскажите, как реализовать под каждую новость!
Спасибо!
Владимир
Владимир
UPD Вроде разобрался
Александр Мальцев
Александр Мальцев
Привет! Рад что получилось.
Анастасия
Анастасия
Подскажите, пожалуйста, как Вам удалось это сделать? Я столкнулась с точно такой же проблемой. Заранее благодарю
Владимир
Владимир
Судя по Вашей песочнице (вверху прикреплённой), вместо «openmodal» используйте, например, индексы 1,2,3 и т.д. под каждую новость:
<a class="button" href="#1">Подробнее</a>
</div>
<div id="1" class="modal">
...
Анастасия
Анастасия
Спасибо большое! Так и думала
Vladislav
Vladislav
Добрый день, хотелось бы понять как реализовать возможность не закрывать модальное окно автоматически при выборе какого-то селектора внутри, у меня их два, и мне нужно подождать пока на оба нажмут и только потом закрывать окно.
Vladislav
Vladislav
Более того, при выборе селекторов внутри, обновляется страница с данными, и вот даже не знаю как решить эту проблему, что бы страница обновилась (при выборе пользователем) но модальное окно не закрывалось
Александр Мальцев
Александр Мальцев
Добрый день! Сделайте эту ситуацию (модальное окно с селекторами) в какой-нибудь песочнице и укажите ссылку на неё.
Andrei
Andrei
а как на этом сайте file:///C:/Users/%D0%A1%D0%B5%D0%B2%D0%B5%D1%80%D0%B8%D0%BD/Desktop/30/index.html#close сделать модальное окно при нажатии на хогвардс и т.д. модальные окна котрые я хочу добавить вы увзидите если прокрутите сайт вни3… ответьте срочно пожайлуста. 3аранее спасибо
Andrei
Andrei
нужет ответ до 09.07.2020
Амир
Амир
Здравствуйте подскажите дело вот в чём. У меня данный код работает на всех браузерах хорошо кроме Сафари. В Сафари вообще не открывается. То есть нажимаю на кнопку но ничего не происходит. Как это можно исправить?
Александр Мальцев
Александр Мальцев
Здравствуйте! Может каких-то вендорных префиксов в CSS не хватает. В Safari >= 9 должно работать.
Святослав
Святослав
Подскажите пожалуйста, если планируется размещать слайдер в модальном окне, как предпочтительней на CSS или на яваскрипт делать модальное окно.

Александр Мальцев
Александр Мальцев
Без CSS вам в любом случае не обойтись. Т.к. это единственная возможность, которая у нас есть для стилизации элементов в браузере. А вот использовать вам дополнительно JavaScript или нет, никто кроме вас не знает. Это зависит от функционала. Если вас будет устраивать то, что у вас получится только с использованием CSS, то тогда JavaScript не используйте. А если нет, то тогда с JavaScript.

Поэтому, когда у вас есть возможность создать что-то без JavaScript и оно вас будет полностью устраивать, то JavaScript использовать не надо.
Святослав
Святослав
Спасибо огромное Александр, ваши статьи и комментарии очень помогают в изучении ЯвасКрипт.
Александр Мальцев
Александр Мальцев
Пожалуйста!
blade23204
blade23204
Добрый день.
Сделал по вашему примеру с JS.
Если у меня несколько модальных окон что нужно менять?
Александр Мальцев
Александр Мальцев
Привет!
Если вы хотите доработать пример с JS, то нужно к ссылкам добавить какой-нибудь признак, который будет определять, что они предназначены для открытия модального окна. Например, атрибут data-toggle=«modal». А атрибут data-target использовать для указания селектора на то модальное окно, которое эта ссылка должна открывать.
Например:
<a href="#" data-toggle="modal" data-target="#modal-1">Открыть модальное окно 1</a>
<a href="#" data-toggle="modal" data-target="#modal-2">Открыть модальное окно 2</a>
Далее нужно переработать JavaScript код, например, следующим образом:
document.addEventListener('click', function (e) {
  let target = e.target;
  if (target.dataset.toggle === 'modal') {
    e.preventDefault();
    document.querySelector(target.dataset.target).classList.add('open');
  } else if (target.dataset.close === 'modal') {
    e.preventDefault();
    target.closest('.modal').classList.remove('open');
  }
});
Ссылка на пример: открыть
blade23204
blade23204
Спасибо большое! Особенно, за разжевывание информации) так понимаешь, что и как работает! еще раз спасибо!
Дмитрий Устинов
Дмитрий Устинов
Здравствуйте, спасибо за пример. Классный!
На локальной машине шикарно отработал, а на хостинге разворачивает модальные окна сразу :(( Битый час экспериментирую. Посмотрите? Картон и скотч открываются модально. Это получается только в браузере Avast, и IE. А в Эдж и Хроме — сразу открывает.
www.sk-resurs.upakovkaprom.ru/resurs_upakovka.html
Александр Мальцев
Александр Мальцев
Здравствуйте! Спасибо! Попробуйте перегрузить страницу с использованием Ctrl + F5.
У вас в коде ошибка:
document.querySelector([href="#openModal"]' || '[href="#openModal_skotch"]).style.marginLeft = '0px';
Дмитрий Устинов
Дмитрий Устинов
Благодарю, получилось )) В чем прикол? И как можно быть уверенным в том, что у пользователя не возникнет такого прочтения кода?
Дмитрий Устинов
Дмитрий Устинов
И вот еще возник вопрос, модальное окно появляется в истории окон %) Можно его не записывать туда (убрать из истории)? А то по стрелке «назад» открывается, чтобы Вы думали?!)) — модальное окно, а не предыдущая страница
Александр Мальцев
Александр Мальцев
Это пример реализации на чистом CSS. Чтобы этого не было можно просто немного поменять логику и добавить чуть-чуть JavaScript кода. Пример модального окна открывающегося и закрывающего с использованием JavaScript.
Александр Мальцев
Александр Мальцев
Когда браузер открывает страницу, он кэширует в соответствии с настройками вашего сервера ресурсы сайта, такие как стили, скрипты, изображения и т.д.
И когда вы что-то изменяете, например, в CSS, браузер об этом не знает. Он при следующей загрузки берёт это из своего кэша. Это позволяет браузеру, когда пользователь переходит по страницам сайта или снова возвращается на него через некоторое время, не загружать эти ресурсы.
Для того чтобы браузеру указать, что у вас изменились стили, к ссылке можно просто добавить GET-параметр, например, ver с некоторым значением:
<link rel="stylesheet" href="/assets/css/main.css?ver=1.0.1">
Elena
Elena
не понимаю какое событие влияет на закрытие окна? в теге а есть ссылка на id="#close" который в стилях не отмечен, зачем она?
Александр Мальцев
Александр Мальцев
Закрытие модального окна осуществляется посредством смены хэша, которое указывает на модальное окно (в данном случае «#openModal» на «#close»). Т.е. когда мы нажимаем на ссылку с «href="#openModal"», мы добавляем хэш «#openModal» к URL, после этого применяется CSS правило с селектором «.modal:target» и модальное окно становится видимым. Далее для того, чтобы скрыть модальное окно необходимо просто изменить хэш «#openModal» на какой-то другой (например, на «#close»). После этого правило с CSS селектором «.modal:target» уже не применяется и модальное окно скрывается.

Вместо «#close» можете указать любой другой хэш, здесь основная задача — это сменить «#openModal» на что-то другое. Для него не нужны никакие стили, здесь просто необходимо чтобы CSS правило с селектором «.modal:target» не применялось к элементу (модальному окну).

Можно, например установить href="#":
<a href="#" title="Close" class="close">×</a>
Владимир Сергеевич Ладный
Владимир Сергеевич Ладный
А как сделать, чтобы модальное окно закрывалось на клике вне области модального окна (на сером фоне вокруг модального окна)
Александр Мальцев
Александр Мальцев
Для этого нужно добавить немного JavaScript на страницу:
document.addEventListener('click', function (e) {
  if (location.hash === '#openModal') {
    if (!e.target.closest('.modal-dialog')) {
      location.hash = '#close';
    }
  }
});
Пример с этим кодом можно посмотреть на этой странице.
Ирина
Ирина
Здравствуйте. Скажите пожалуйста, какую роль здесь играет класс container?
Александр Мальцев
Александр Мальцев
Здравствуйте. В конкретно этом примере данный класс никакой не играет роли. К нему не привязан код CSS и (или) JavaScript. В реальном же примере вы его можете использовать, чтобы установить элементам, которые его будут иметь, например, поля слева и справа.
snt
snt
Приветствую! Исключительно нравятся ваши окна. Обнаружил баг на Сматрфоне iOS11, MobileSafari. Прокручивается не содержимое окна, а содержание страницы. При попытке закрыть окно — вместо него открывается другое с этой же страницы. Как можно поправить? И как сделать, чтобы окно закрывалось при клике за его областью?
Александр Мальцев
Александр Мальцев
Если окна не большие, то можно попробовать изменить overflow на hidden:
.modal:target {
  opacity: 1;
  pointer-events: auto;
  overflow: hidden;
}
Если на странице несколько модальных окон, то они должны иметь разные id.
Клик за областью можно реализовать, например, так:
document.querySelector('#openModal').addEventListener('click', function() {
  location.hash = ''         
});    
document.querySelector('#openModal .modal-dialog').addEventListener('click', function(e) {
  e.stopPropagation();
});
Denis
Denis
Добрый день, Александр)
Подскажите как сделать тоже самое, но чтобы открывал в pop up другого документа, например test.html
Александр Мальцев
Александр Мальцев
Добрый! Вы хотите открыть в popup содержимое другого документа? Если да, то это выполняется с помощью AJAX (например, с помощью метода load или ajax библиотеки jQuery).
Denis
Denis
спасибо
Владимир
Владимир
Добрый день!
После выполнения условий в браузерной строке остаются якоря #close и #openModal.
Можно ли реализовать тоже самое, но без использования URL, а например, выполнять событие с привязкой к классу?
Спасибо!
Александр Мальцев
Александр Мальцев
Добрый! Можно, но тогда придётся использовать JavaScript. Если интересно, то могу привести решение.
Владимир
Владимир
Было бы здорово, спасибо!
Александр Мальцев
Александр Мальцев
Для этого необходимо:
1. В CSS заменить селектор .modal:target на .modal.show:
.modal.show {
  opacity: 1;
  pointer-events: auto;
  overflow-y: auto;
}
2. Добавить JavaScript (с использованием jQuery):
$('a[href="#openModal"]').click(function(e){
  e.preventDefault();
  $($(this).attr('href')).addClass('show');
});

$('#openModal').on('click','.close', function(e){
  e.preventDefault();
  $(e.delegateTarget).removeClass('show');
});
Если необходимо на JavaScript без использования jQuery, то код можно посмотреть в примере. Пример доступен по этой ссылке.
Олег
Олег
Добрый день Александр, я перечитал всю историю переписки но не нашел что искал, т.е. находил но не полностью. Прошу помочь с одним JavaScript. Модальное окно прекрасно работает, но хотел не много поправить. Как и раннее был вопрос от (Владимира) чтоб в браузерной строке не оставались якоря #close и #openModal, и это работает. Второй вопрос это по закрытию мод. окно. Подскажите пожалуйста как ещё правильно дописать код чтоб модальное окно закрылось при клике вне окна?

Когда я прописал JavaScript, то при клике закрытии за пределы окна не работает :(

document.addEventListener("DOMContentLoaded", function () {
      var scrollbar = document.body.clientWidth - window.innerWidth + 'px';
      console.log(scrollbar);
      document.querySelector('[href="#openModal"]').addEventListener('click', function () {
        document.body.style.overflow = 'hidden';
        document.querySelector('#openModal').style.marginLeft = scrollbar;
      });
      document.querySelector('[href="#close"]').addEventListener('click', function () {
        document.body.style.overflow = 'visible';
        document.querySelector('#openModal').style.marginLeft = '0px';
      });
    });
$('a[href="#openModal"]').click(function(e){
  e.preventDefault();
  $($(this).attr('href')).addClass('show');
});

$('#openModal').on('click','.close', function(e){
  e.preventDefault();
  $(e.delegateTarget).removeClass('show');
});

  document.addEventListener('click', function (e) {
  if (location.hash === '#openModal') {
    if (!e.target.closest('.modal-dialog')) {
      location.hash = '#close';
    }
  }
});
Александр Мальцев
Александр Мальцев
Привет!
Пример: itchief.ru/examples/lab.php?topic=javascript&file=modal-01
Описание примера добавлю в статью немного попозже.
Олег
Олег
Спасибо большое за оперативную помощь Александр! Единственное другая проблемка вылезла. Код я переписал по новому который вы скинули пример, всё как я хотел работает, чтоб не добавлялись в адресной строке якоря #close и #openModal и закрывать окно в любом месте, вне окна. Но по каким то причинам окно открывается, если нажимать только на текст т.е. (Открыть модальное окно). Просто в место текста я использую иконками как кнопки, сами иконки у меня не картинки jpeg, я я использую через тэг . Я поэкспериментировал и понял что если добавить любой тег p, div, span и т.д. в ну три тега <а> перестает работать и окно не открывается. Вот и сижу теперь кумекаю почему не хочет так работать, ведь на старом JavaScript работал.

На всякий случай ниже код который не хочет так работать
<div class="container">
    <div style="text-align: center;">
      <a href="#" data-toggle="modal" data-target="#modal-1"><span class="fa-stack fa-lg">
  <i style="color:#9199a5;" class="fa fa-circle fa-stack-2x"></i>
  <i class="fa fa-phone fa-stack-1x fa-inverse"></i>
</span></a>
    </div>
    <div id="modal-1" class="modal">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h3 class="modal-title">Название</h3>
            <a href="#" class="close" data-toggle="modal" title="Закрыть">×</a>
          </div>
          <div class="modal-body">
            Содержимое модального окна...
          </div>
        </div>
      </div>
    </div>
  </div>
Александр Мальцев
Александр Мальцев
Подправил код в примере для таких сценариев.
Олег
Олег
Александр подскажите пожалуйста, где или в ком примере вы поправили? т.е. я предполагал что в этом Пример: itchief.ru/examples/lab.php?topic=javascript&file=modal-01, но там ни чего по моему не изменилось. Модальное окно конечно работает, но при добавить любой тег p, div, span и т.д. в ну три тега <а> то перестает работать. Может это в другом примере поправили JavaScript или может в стилях?
Александр Мальцев
Александр Мальцев
Да, в этот пример. JavaScript код изменил. Должно работать.
Олег
Олег
Александр всё работает, спасибо большое!!!