Техники наложения CSS

Техники наложения CSS

От автора: Есть несколько методов создания наложения: от использования абсолютно позиционированного элемента до контуров и псевдоэлементов. В этой статье мы собираемся исследовать стили каждой из методик со всеми их «за» и «против».

Дизайнерские шаблоны, набор лучших практик и методов, нацеленных на решение одной из самых распространенных «проблем» дизайна, обычно представлены в контексте дизайнерских принципов. Один из них – принцип «остаться на странице» (Stay On Page). Он базируется на том факте, что обновления страницы плохо действуют на мыслительные процессы пользователя, вызывая явление, известное как ослепление при смене, и нам нужно избегать визуальной перегрузки пользователя там, где и когда это возможно.

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

Поверхностные наложения можно применять для того, чтобы задать вопросы, представить свойства, обозначить прогресс, дать инструкции или показать информацию. Их можно активировать напрямую действиями пользователя (например, щелкнув на действие, проведя мышью над объектами) или представить веб-приложениями на различных стадиях при завершении действия.Дизайн веб-интерфейсов

Когда пользовательский интерфейс воспринимается только в появляющемся модальном окне, обычно применяется эффект Lightbox, а остальная страница затемняется, обозначая ее неактивность. Задача этого учебника – представить вам несколько методов, которые можно применить для создания затемняющего наложения с помощью CSS, и обозначить «за» и «против» каждой техники по мере их описания.

МЕТОД №1: АБСОЛЮТНО ПОЗИЦИОНИРОВАННЫЙ ЭЛЕМЕНТ

Первый способ создания наложения – абсолютное позиционирование на странице элемента HTML. В разметке будет пустой div, а с помощью CSS этот div абсолютно позиционируется и ему назначается болшое значение z-index для того, чтобы гарантировать, что он останется на странице поверх всех прочих элементов, кроме модального окна, открывающегося сверху этого наложения, которое получит еще более высокий z-index, чем оверлей.

<html>
  <body>
   <divclass="overlay"></div>
   <!--...-->
  <body>
<html>

Предположим, в нашу разметку уже добавлен пустой div, и ему назначен класс .overlay, а вот CSS для позиционирования этого наложения на странице:

html, body{
  min-height: 100%;
}
body{
  position: relative;
}
.overlay{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  background-color: rgba(0,0,0,0.5); /*затемнитефон*/
}

Данный код очень прост, но при использовании этого способа нужно знать еще кое о чем.

Во-первых, убедитесь, что оверлей абсолютно позиционирован по отношению к body. Так что, если наложение, например, содержится в другом div’е и позиционирование этого другого div’а установлено на относительное, то оверлей будет позиционирован абсолютно относительно его контейнера, а не body. Поэтому вам нужно либо дать наложению возможность быть прямым подчиненным узлом body, или убедиться, что ни у одного из его дочерних элементов позиционирование не установлено на relative.

Кроме того, вам следует убедиться, что содержимое страницы растягивается до самого низа окна просмотра или ниже, потому что body увеличивается таким образом, чтобы соответствовать высоте своего содержимого (естественно, предположим, что контент не расположен абсолютно), а если содержимого недостаточно для того, чтобы растянуть высоту body до низа окна просмотра, то наложение, достигающее 100% высоты тела, так же не достигнет низа окна просмотра и, следовательно, не закроет его.

Что бы этого избежать и не беспокоиться о количестве контента на странице, а оверлей при этом закрывал бы все окно просмотра, вы должны установить высоту корневого элемента html и body. Однако помните при установке высоты элементов html и body:

Если вы назначаете элементу html высоту в 100% (100% высоты относительно окна просмотра) и назначаете body так же высоту в 100% (что высчитывается относительно коренного html), то устанавливаете высоту этих обоих элементов на 100% высоты окна просмотра, и следовательно, неважно насколько далеко простирается содержимое body, его высота остается равной высоте окна просмотра, и такой же будет высота наложения. В этом случае при прокрутке страницы вниз наложение станет прокручиваться вверх и вы увидите содержимое под ним без оверлея, как будто он обрезан.

Решение этой проблемы – установка минимальной высоты корневого элемента и body вместо установки значения высоты, что в большинстве ситуаций предпочтительнее. Установив минимальную высоту, вы гарантируете, что он станет достигать низа окна просмотра и будет увеличиваться по мере увеличения содержимого. И наконец, чтобы величина оверлея увеличивалась и растягивалась для покрытия всего контента при прокрутке страницы вы должны установить position:relative; к body для того, чтобы высота наложения растягивалась вместе с увеличением высоты тела.

Еще об этой методике следует заметить, что не следует пользоваться слишком высокими значениями z-index. Многие разработчики любят брать очень большие значения, вроде z-index: 999999; при позиционировании оверлея или любого другого элемента поверх других элементов страницы. Это не требуется. Чаще всего значения z-index равного 10, иногда даже меньше, достаточно для того, чтобы элемент на странице оставался поверх остальных. Вам лишь следует знать, что если другие элементы получают z-index, и таковые имеются, то просто установите z-index наложения больше самого высокого у прочих элементов.

И наконец, нужно также помнить, что при этом методе вы добавляете в свою разметку пустой div, и это, конечно, не семантично.

Преимущество этого способа в том, что он поддерживается во всех основных браузерах и даже старых, вплоть до IE8.

Я поместила пример на Codepen, чтобы вы могли протестировать результат этой техники. Попробуйтезаменить min-height в html и body на height, или удалить позиционирование relative из body и посмотреть, как при прокрутке оверлей обрезается внизу.

See the Pen Creating an Overlay with an Absolutely Positioned Element by Sara Soueidan (@SaraSoueidan) on CodePen

МЕТОД №2: ЭЛЕМЕНТ С POSITION FIXED

Второй способ добавления наложения очень похож на предыдущий, и в разметке используется тот же самый элемент .overlay, но вместо абсолютного позиционирования наложения вы назначаете ему фиксированное позиционирование и полную ширину и высоту для покрытия окна просмотра целиком. А так как в данном случае оверлей фиксирован, то в не зависимости от того, как далеко вниз вы прокручиваете, он будет оставаться на месте, покрывая всю область окна просмотра, а это именно то, что нам нужно.

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  z-index: 10;
  background-color: rgba(0,0,0,0.5);
}

В отличие от абсолютно позиционированных элементов, установленных относительно контейнера с помощью position:relative, фиксированные элементы позиционированы относительно окна просмотра:

Тогда как расположение и размеры элемента с position:absolute относительны к своему содержащему блоку, расположение и размеры элемента с position:fixed всегда относительны к исходному содержащему блоку. Обычно это окно просмотра: окно браузера или разворот страницы. — W3CWiki

Обычно при использовании фиксированного позиционирования не приходится волноваться по поводу того, куда в разметку вставить div. Неважно куда вы его вставите, он получит фиксированное расположение по отношению к окну просмотра, кроме случая, когда вы трансформируете один из родительских блоков для div-а оверлея, в таком случае трансформированный элемент создает содержащий блок для всех своих позиционированных потомков, даже тех, которые получают фиксированное позиционирование. Этот факт сбил с толку многих разработчиков, включая меня. Так что, если вдруг вы станете фиксировать элемент и результат окажется не тем, которого вы ожидали, проверьте, не является ли этот фиксированный элемент потомком трансформируемого элемента.

See the Pen Creating an Overlay with an Element with Fixed Position by Sara Soueidan (@SaraSoueidan) on CodePen

И снова, в этой технике мы добавляем в разметку пустой элемент, что против семантики разметки. Как же этого избежать?

МЕТОД №3: ПРИМЕНЕНИЕ ПСЕВДОЭЛЕМЕНТА

Во избежание добавления пустых элементов в разметку вместо них при создании наложения можно использовать псевдоэлементы. Стили и решения этого метода во многом похожи на предыдущие, за исключением того, что вместо стилей и расположения пустого элемента с классом .overlay мы назначим стили псевдоэлементам body :before или:after.

html, body {
  min-height: 100%;
}
 
body {
  position: relative; /* требуется, если вы позиционируете псевдоэлемент абсолютно */
}
 
body:after {
  content: "";
  display: block;
  position: fixed; /* тоже могла бы быть абсолютной */
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  z-index: 10;
  background-color: rgba(0,0,0,0.2);
}

Вы можете выбрать позиционирование псевдоэлемента абсолютно относительно body, или назначить ему фиксированное позиционирование. Что бы вы ни избрали, вам придется обдумать упомянутые нами в первых двух методах вопросы. А вот пример:

See the Pen Creating an Overlay with a Pseudo-Element by Sara Soueidan (@SaraSoueidan) on CodePen

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

МЕТОД №4: ПРИМЕНЕНИЕ К МОДАЛЬНОМУ ОКНУ ШИРОКОГО КОНТУРА

Создание наложения с затемненным фоном этим способом не требует дополнительных элементов. Вместо них можно применить к модальному окну большой контур для получения эффекта затемнения на остальной странице.

Благодарить за эту технику следует Леа Веру (LeaVerou), она первой поделилась ею с нами через twitter. Итак, представьте, что у вас в разметке имеется элемент, представляющий модальное окно, которое появится в наложении:

<divclass="modal">I'm the Modal Window!</div>

Когда оно появляется поверх остальных элементов страницы, к нему можно применить широкий контур, который станет действовать как затемняющий слой. Контуру обычно устанавливается очень большое значение, но ему следует быть широким лишь настолько, чтобы покрывать всю область окна просмотра независимо от его размера.

.modal {
    /* стили для позиционирования модального окна в центре страницы */
    position: fixed;
    top: 50%;
    left: 50%;
    width: 300px;
    line-height: 200px;
    height: 200px;
    margin-left: -150px;
    margin-top: -100px;
    background-color: #f1c40f;
    text-align: center;
   
    /* нужные для оверлея стили */
    z-index: 10; /* удерживайте поверх остальных элементов страницы */
    outline: 9999px solid rgba(0,0,0,0.5);
}

Конечно, не забудьте установить z-index модального окна для того, чтобы оно оставалось поверх остальных элементов страницы.

See the Pen Creating an Overlay with an Outline by Sara Soueidan (@SaraSoueidan) on CodePen

Здесь нужно помнить о том, что при использовании этого метода темное наложение под модальным окном не устранит взаимодействие мыши с остальными элементами страницы. Вы не сможете предотвратить запуск событий указателя и мыши, если щелкнете на другой элемент страницы, что в большинстве случаев может оказать нежелательное действие. Так что придется обдумать, нужен ли такой эффект вашему приложению или нет, до того, как решите, применять ли вам этот метод.

Также обратите внимание, что контур нарисован вне border-a и не последует за скругленными углами. Если они у вас есть, как в примерах, то вы заметите зазор. Так что этот метод может оказаться не лучшим выбором, если у вас модальное окно с скругленными углами.

МЕТОД №5: ПРИМЕНЕНИЕ К МОДАЛЬНОМУ ОКНУ ШИРОКОЙ ТЕНИ БЛОКА

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

.modal {
    /* стили для позиционирования модального окна в центре страницы */
    position: absolute;
    top: 50%;
    left: 50%;
    width: 300px;
    line-height: 200px;
    height: 200px;
    margin-left: -150px;
    margin-top: -100px;
    background-color: #f1c40f;
    text-align: center;
    border-radius: 5px;
   
    /* нужные стили для оверлея */
    z-index: 10; /* удерживайте поверх остальных элементов страницы*/
    box-shadow: 0 0 0 9999px rgba(0,0,0,0.5);
}

Результат, конечно, тоже сильно похож.

See the Pen Creating an Overlay with a Large Box Shadow by Sara Soueidan (@SaraSoueidan) on CodePen

Конечно, темное наложение, являющееся результатом этого способа, также не предотвращает взаимодействия с остальными элементами страницы, находящимися под модальным окном.

Теперь, не смотря на упоминание этой техники как одного из возможных способов создания наложений, я настоятельно рекомендую вам не пользоваться им. Более того, вообще не применяйте слишком много теней на своих страницах/приложениях.
Тени в сочетании с другими стилями вроде border-radius или в случае частого применения способны вызывать сильные помехи производительности, и даже сделать ваше приложение неприменимым в смартфонах и планшетах, так как они склонны становиться очень неадаптивными в приложениях, сильно переполненных box-shadow.

Тени блока не легко отображать, и все становится еще хуже, когда широкие тени применяются к фиксированным элементам, так как это может заставлять браузер перерисовывать большие области страницы при прокрутке. Особенно плохо выходит в Firefox’е, где фиксированные элементы и широкие тени блока CSS способны существенно снизить скорость, вплоть до 2 кадров в секунду при прокрутке и манипулировании DOM.

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

МЕТОД №6: ПРИМЕНЕНИЕ ЭЛЕМЕНТА HTML DIALOG

Последняя обсуждаемая нами методика весьма новая и действительно потрясающая! И самая семантическая из всех, если вы создаете наложения для диалогового или модального окна.

Теперь их можно легко создать и назначить им стили с помощью элемента HTML dialog. Элемент dialog обеспечивает внутреннюю функциональность. Диалог существует в дереве DOM, а назначить ему стили можно с помощью простого CSS. Элемент dialog представляет часть приложения, с которым пользователь взаимодействует для выполнения задачи, например, диалог, инспектор или окно. — спецификация HTML WHATWG

У элемента HTML dialog имеется четыре основных свойства, в трех из которых мы больше всего заинтересованы при создании оверлеев (четвертое на момент написания этой статьи еще не применяется):

Поумолчанию диалог при открытии центрируется по вертикали в окне просмотра. Он позиционирована бсолютно, поэтому его можно прокручивать. Центрирование окна просмотра происходит вне зависимости от расположения диалога в дереве DOM.

Диалоги могут быть модальными. Когда модальный диалог открывается, он блокирует остальной документ. Для управления случаем применения множества модальных диалогов существует штабель «выполняемых диалогов».

Новый накладывающийся слой поверх существующих контекстов CSS выполняет поведение «всегда сверху». И dialog, и спецификация Fullscreen пользуются верхним слоем. Модальные диалоги постоянно находятся в верхнем слое. Поэтому вам не нужно тревожиться об установке z-index вручную для того, чтобы ваше модальное окно оставалось поверх всех элементов страницы.

Здорово, да? Элемент dialog центрируется поумолчанию, но, как говорилось в первом пункте, он применяет абсолютное позиционирование, поэтому его можно прокручивать. Можно обойти абсолютное позиционирование по умолчанию, установив position на fixed в таблице стилей. Если действительно решите изменить позицию на фиксированную, вам также придется установить значения top и left и тоже отцентрировать их. Элемент dialog можно поместить в DOM где угодно.

<dialog class="modal">This is the dialog!</dialog>

Ему можно назначить стили точно так же, как любому другому элементу блочного уровня.

.modal{
  /* произвольные стили */
  background-color: white;
  border-radius: 5px;
  box-shadow: 2px2px2pxrgba(0,0,0,0.2);
  height:200px;
  width:300px;
 
  /* измените positionнаfixed, если хотите предотвратить прокрутку диалога, и отцентрируйте его */
  position:fixed;
  top:50%;
  left:50%;
  margin-left: -150px;
  margin-top:-100px;
}

Кроме того, элемент dialog идет вместе с псевдоэлементом под названием ::backdrop, который дает возможность назначать стили фону под модальным окном, создавая, таким образом, затемненный эффект наложения, который ранее мы создавали в предыдущих пяти техниках, только на этот раз можно легко создать такое наложение, назначив стили псевдоэлементу, идущему по умолчанию с элементом dialog.

Так, для создания эффекта наложения с помощью элемента HTML dialog вы просто применяете фоновый цвет к связанному псевдоэлементу и располагаете его так, чтобы он закрывал область окна просмотра, как мы это делали в предыдущих методах:

.modal::backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0,0,0,0.5);
}

Вот на что будет похож результат:

Вот и все, что требуется для создания наложения с помощью элемента dialog! Заставить его работать еще проще – dialog идет в комплекте с API, отчего показ и скрытие модального окна становятся задачей-конфеткой и где, помимо прочего, применяются функции типа show() и hide(). Больше узнать об элементе dialog и его API и посмотреть живые примеры можно в этом демо от Эйжи Китамура (Eiji Kitamura). Демо-пример идет в режиме полифила, когда вы просматриваете его в браузере, который еще не поддерживает элемент dialog.

ПОСЛЕСЛОВИЕ

Думаю, мы рассмотрели почти все методы, применимые для создания наложения на странице для модальных окон. Как вы, возможно, догадались, последняя техника с применением элемента dialog лучше всего подходит для создания оверлеев модельного окна или диалога, но на момент написания этой статьи она поддерживается только в Chrome Canary с доступным полифилом. Так что вам нужно быть осторожнее с браузерной поддержкой, если попытаетесь использовать его сейчас. Но как только его поддержка будет добавлена во все основные браузеры, он станет лучшим способом создания страничных оверлеев, при этом станут доступны великолепные свойства работы с ним.

Надеюсь, вам понравилась и оказалась полезной эта статья. Спасибо за прочтение!

Автор: Sara Soueidan

Источник: http://tympanus.net/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки: ,

Комментарии Вконтакте:

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

Комментарии (1)

  1. Андрей

    А как сделать чтобы модальное окно было полупрозрачным и элементы под ним имели кликабельность, сможете?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree