То, что мы собираемся сделать, это модальное окно, которое открывается в центре экрана при нажатии на ссылку, в то время как все, что лежит в основе окна, становится размытым. Это можно сделать с помощью элемента ` Dialog` , но в настоящее время нам не нужен JavaScript для решения этой задачи. Ну, есть два основных метода обработки событий onClick в CSS — checkbox-hack и selection by: target. Второй способ привязывает наше модальное окно к хешу URL. Таким образом, вы можете обратиться к модальному окну в URL, что довольно удобно. Крис Койер привел пример выделения текста в соответствии с целевым состоянием на http://css-tricks.com/on-target/. Он также отметил побочный эффект «прыжка» и предложил исправление JavaScript. Ян Ханссоноднако сделал пример виджета со вкладками контента, фиксирующего эффект путем установки целевых якорей в фиксированном положении. Вот и все. Давайте напишем теперь наш пример HTML. Сначала нам нужны якоря, чтобы сохранить состояние хэша URL. Один — открыть модальное окно (id = about), а второй — закрыть все окна (id = start). Поскольку нам не нужны реальные ссылки, мы можем сделать якоря некоторых нейтральных элементов, например span.
<span id="start" class="target"><!-- Hidden anchor to close all modals --></span> <span id="about" class="target"><!-- Hidden anchor to open adjesting modal container--></span>
Далее мы помечаем модальное окно:
<div class="modal">
<div class="content vertical-align-middle">
<h2>About</h2>
<article>Lorem ipsum</article>
<a class="close-btn" href="#start">X</a>
</div>
</div>
И чтобы показать, что модальное окно действительно размывает подстилающий контент, мы помещаем фиктивную страницу HTML в контейнер (`.page-container`) ниже:
<div class="page-container"> <h1>Lorem ipsum dolor sit amet,</h1> <p><a href="#about">Open Modal Window</a> Lorem ipsum dolor sit amet.../p> </div>
Мы прячем наши якоря и устанавливаем их в фиксированное положение, как предложил Ян Ханссон.
.target {
display: block;
left: 0;
position: fixed;
top: 0;
width: 0;
height: 0;
visibility: hidden;
pointer-events: none;
}
Затем мы расширяем контейнер модального окна, чтобы заполнить все видимые области просмотра.
.modal {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
z-index: 100;
text-align: center;
display: none;
/* Fallback for legacy browsers */
background-color: rgba(0,0,0,0.6);
}
Обратите внимание, что z-index, как ожидается, будет выше, чем любой в .page-container. Нам нужна модальная коробка прямо в центре экрана. Поскольку его высота изначально неизвестна, мы используем трюк с «вертикальным центрированием» .
.modal::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin: 0;
}
.modal > .content {
text-align: left;
display: inline-block;
background-color: #b13e12;
box-sizing: border-box;
color: white;
position: relative;
width: 500px;
padding: 20px;
}
Как вы, наверное, заметили, изначально модальное окно контейнера скрыто. Мы должны показать это, когда хеш URL совпадает с привязкой к ближайшему соседу (.target).
/* Behaviour on legacy browsers */
.target:target + .modal {
display: block;
}
Это открытие не выглядит нарядно. Но мы можем улучшить UX в современных браузерах:
:root .modal {
display: block;
transition: transform 0.3s cubic-bezier(0.5, -0.5, 0.5, 1.5);
transform-origin: center center;
transform: scale(0, 0);
background-color: transparent;
}
:root .modal > .content {
box-shadow: 0 5px 20px rgba(0,0,0,0.5);
}
:root .target:target + .modal {
transform: scale(1, 1);
}
Устаревшие браузеры, не поддерживающие CSS3, будут игнорировать любые стили с префиксом: root и, следовательно, будут отображать окно без этих эффектов.
Как насчет размытия содержимого страницы, лежащего в основе окна? Мы применим фильтр размытия к .page-container, когда идентификатор любого модального окна (кроме #start) совпадает с хешем URL.
:root .target:target ~ .page-container {
filter: blur(5px);
-webkit-filter: blur(5px);
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' ><filter id='blur5'><feGaussianBlur in='SourceGraphic' stdDeviation='5' ></feGaussianBlur></filter></svg>#blur5"); // for Firefox
filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='5');
}
:root span[id="start"]:target ~ .page-container {
filter: none;
-webkit-filter: none;
}
Вот что мы получаем:
Смотрите модное окно Pen Fancy без JavaScript от Дмитрия Шейко ( @dsheiko ) на CodePen .
Улучшение для лучшего пользовательского опыта
Возможно, вам не хватает некоторых дополнительных функций, таких как закрытие модов при нажатии Esc или клик за пределами модального содержимого. Мы можем внести это с помощью небольшого количества JavaScript:
Посмотрите Модное окно Pen Fancy с небольшим количеством JavaScript от Дмитрия Шейко ( @dsheiko ) на CodePen .
Откат для IE8
: псевдо-селектор target имеет хорошую поддержку среди современных браузеров, но, как вы можете догадаться, он не поддерживается в браузерах IE с версиями меньше 9. Тем не менее, мы можем изменить это поведение, используя некоторый JavaScript:
(function( window ){
var doc = window.document,
/**
* Remove .is-expanded from all modals and add it to the target
* @returns {void}
*/
shimTargetOnModals = function() {
var i = 0,
len,
id = window.location.hash.substr( 1 ),
nextSibling = doc.querySelector( "#" + id + " + .modal" ),
nodeList = doc.querySelectorAll( ".target + .modal" ),
len = nodeList.length;
// Close all other modals
for ( ; i < len ; i++ ) {
nodeList[ i ].className = "modal";
}
// Expand requested window
if ( nextSibling ) {
nextSibling.className = "modal is-expanded";
}
};
window.attachEvent( "onload", function(){
window.attachEvent( "onhashchange", shimTargetOnModals );
shimTargetOnModals();
});
}( window ));
Требуются некоторые дополнительные стили:
.modal.is-expanded {
display: block;
}
.modal.is-expanded > .content {
top: 50%;
margin-top: -45px;
}