То, что мы собираемся сделать, это модальное окно, которое открывается в центре экрана при нажатии на ссылку, в то время как все, что лежит в основе окна, становится размытым. Это можно сделать с помощью элемента ` 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; }