CSS слои, абсолютное и относительное позиционирование, z-index. Очередной блог фрилансера
Любые позиционированные элементы на веб-странице могут накладываться друг на друга в определенном порядке, имитируя тем самым третье измерение, перпендикулярное экрану. Каждый элемент может находиться как ниже, так и выше других объектов веб-страницы, их размещением по z-оси и управляет z-index . Это свойство работает только для элементов, у которых значение position задано как absolute , fixed или relative .
Краткая информация
Обозначения
Описание | Пример | |
---|---|---|
<тип> | Указывает тип значения. | <размер> |
A && B | Значения должны выводиться в указанном порядке. | <размер> && <цвет> |
A | B | Указывает, что надо выбрать только одно значение из предложенных (A или B). | normal | small-caps |
A || B | Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. | width || count |
Группирует значения. | [ crop || cross ] | |
* | Повторять ноль или больше раз. | [,<время>]* |
+ | Повторять один или больше раз. | <число>+ |
? | Указанный тип, слово или группа не является обязательным. | inset? |
{A, B} | Повторять не менее A, но не более B раз. | <радиус>{1,4} |
# | Повторять один или больше раз через запятую. | <время># |
Значения
В качестве значения используются целые числа (положительные, отрицательные и ноль). Чем больше значение, тем выше находится элемент по сравнению с теми элементами, у которых оно меньше. При равном значении z-index , на переднем плане находится тот элемент, который в коде HTML описан ниже. Допустимо использовать отрицательное значение.
Кроме числовых значений применяется auto — порядок элементов в этом случае строится автоматически, исходя из их положения в коде HTML и принадлежности к родителю, поскольку дочерние элементы имеют тот же номер, что их родительский элемент.
Пример
В данном примере при наведении курсора на карту она выходит на передний край, частично перекрывая остальные собой остальные изображения (рис. 1).
Рис. 1. Изменение порядка карт
Объектная модель
Объект .style.zIndex
Примечание
Список, созданный с помощью
Internet Explorer до версии 7.0 включительно интерпретирует auto как 0.
В браузере Firefox до версии 2.0 включительно отрицательное значение z-index располагает элемент ниже фона веб-страницы и его контента.
Спецификация
Каждая спецификация проходит несколько стадий одобрения.
- Recommendation (Рекомендация ) - спецификация одобрена W3C и рекомендована как стандарт.
- Candidate Recommendation (Возможная рекомендация ) - группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
- Proposed Recommendation (Предлагаемая рекомендация ) - на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
- Working Draft (Рабочий проект ) - более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
- Editor"s draft (Редакторский черновик ) - черновая версия стандарта после внесения правок редакторами проекта.
- Draft (Черновик спецификации ) - первая черновая версия стандарта.
Проблема z-index в том, что многие просто не понимают, как он работает.
Всё, описанное ниже, есть в спецификации W3C. К сожалению, не все её читают.
Описание проблемы:
Итак, пусть у нас есть HTML код, состоящий из 3 элементов.Каждый из них внутри себя содержит по одному. А каждый, в свою очередь, имеет свой фон: красный, зеленый и синий, соответственно. Плюс ко всему, каждый позиционирован абсолютно левого верхнего края документа таким образом, что он немного перекрывает собой следующий за ним. Первый имеет z-index , равный 1, у остальных двух z-index не задан.
Ниже представлен HTML код с базовым css оформлением.
.red, .green, .blue { position: absolute; } .red { background: red; z-index: 1; } .green { background: green; } .blue { background: blue; }
Пример на jsfiddle
Задача: сделать так, чтобы красный был позади синего и зеленого, при этом не нарушая ни одно из следующих правил:
- Нельзя менять HTML разметку
- Нельзя менять/добавлять z-index к элементам
- Нельзя менять/добавлять позиционирование к элементам
Решение:
Решение состоит в том, чтобы добавить прозрачность чуть меньше единицы первому (родителю красного).Вот css, иллюстрирующий это:
div:first-child { opacity: .99; }
Хм, что-то тут не так. Причем тут вообще прозрачность? Каким образом она может влиять на порядок перекрытия элементов? Вы думаете так же? Добро пожаловать в клуб!
Надеюсь, во второй части статьи всё встанет на свои места.
Порядок наложения элементов:
Z-index кажется очень простым: чем значение больше, тем ближе к нам будет элемент, т.е. элемент с z-index 5 будет перекрывать собой элемент с z-index 2, верно? На самом деле нет.Это и есть проблема z-index. Всё кажется настолько очевидным, что большинство разработчиков не уделяют достаточно времени для изучения этого вопроса.
Любой элемент в HTML документе может быть либо на переднем, либо на заднем плане. Это известно всем. Правила, задающие этот порядок четко описаны в спецификации, но, как я уже говорил выше, не все в полной мере их понимают.
Если свойства z-index и позиционирование не заданы явно, всё просто: порядок наложения равен порядку следования элементов в HTML. (На самом деле всё немного сложнее , но пока вы не будете использовать отрицательные значения отступов для перекрытия строчных элементов, вы не будете сталкиваться с крайними случаями)
Если вы явно указываете позиционирование элементам (и их детям), то такие элементы будут перекрывать собой элементы без явно заданного свойства позиционирования. (Говоря «явно указываете позиционирование» – я имею ввиду любое значение, кроме статического, например: абсолютное, или относительное).
И наконец, случай, когда z-index задан. Для начала, вполне естественно предполагать, что элементы с большим z-index будут находиться выше элементов с меньшим z-index, а любой элемент с установленным z-index будет находится выше элемента без установленного z-index, но это не так. Во первых, z-index учитывается только на явно позиционированных элементах. Если вы попробуете установить z-index на не позиционированный элемент, то ничего не произойдет. Во вторых, значения z-index могут создавать контексты наложения. Хм, всё стало намного сложнее, не так ли?
Контекст наложения
Элементы с общими родителями, перемещающиеся на передний или задний план вместе известны как контекст наложения. Понимание контекста наложения является ключом к пониманию z-index и порядка наложения элементов.Каждый контекст наложения имеет свой корневой элемент в HTML структуре. В момент формирования нового контекста на элементе, все дочерние элементы так же попадают в этот контекст и занимают своё место в порядке наложения. Если элемент располагается в самом низу одного контекста наложения, то никаким мыслимым и немыслимым образом не получится отобразить его над другим элементом в соседнем контексте наложения, располагающимся выше по иерархии, даже с установленным z-index равным миллиону.
Новый контекст может быть сформирован в следующих случаях:
- Если элемент – корневой элемент документа (элемент)
Если элемент позиционирован не статически и его значение z-index не равно auto
Если элемент имеет прозрачность менее 1
Большинство CSS-свойств довольно просты в использовании. Зачастую, применение CSS-свойства к элементу в разметке дает мгновенный результат – как только вы обновите страницу, набор значений свойства применится, и вы сразу же увидите результат. Другие CSS-свойства, однако, более комплексные и будут работать только после задания определенного набора условий.
Свойство z-index принадлежит к последней группе свойств. Это свойство так часто вызывало всеобщую путаницу и разочарование, как ни одно, из существующих CSS-свойств. По иронии судьбы, однако, когда вы поближе познакомитесь с z-index , вы поймете, что это свойство очень простое, и предлагает эффективный метод решения многих проблем верстки.
В этой статье вы узнаете, что представляет собой z-index, как он может быть неправильно истолкован, а также некоторые примеры его использования. Кроме того, вы узнаете некоторые различия в поведении браузеров при обработке свойства z-index, это касается в основном предыдущих версий Internet Explorer и Firefox. Этот подробный обзор z-index предоставит разработчикам отличную основу для использования этого свойства уверенно и эффективно.
Что это такое?
Свойство z-index определяет уровень стека HTML-элемента. «Уровень стека» обозначает позицию элемента на оси Z (направленно перпендикулярно оси X, или оси Y). Элемент, которому назначено самое большое значение z-index, будет расположен в самом верху стека слоев. Этот стек слоев, располагается перпендикулярно к экрану, или области просмотра.
3-д представление оси Z:
Для того, чтобы продемонстрировать как работает z-index , картинка, представленная выше, немного увеличивает отображение элементов стека по отношению к области просмотра.
Обычный порядок стека
На HTML-странице, обычный порядок стека (то есть порядок элементов на оси Z), определяет ряд факторов. Далее представлен список, отображающий порядок, в котором элементы укладываются в стек, начиная снизу. В этом списке нет элементов, с назначенным свойством z-index:
- Фон и рамка элемента, создающие контекст стека
- Элементы с отрицательным контекстом стека, в порядке появления
- Не позиционированные, не плавающие, блочные элементы, в порядке появления
- Не позиционированные, плавающие элементы, в порядке появления
- Строчные элементы, в порядке появления
- Позиционированные элементы, в порядке появления
Когда свойство z-index используется правильно, оно может изменить обычный порядок стека.
Конечно, порядок элементов в стеке не является таким наглядным, пока элементы позиционируются, перекрывая друг друга. Поэтому, чтобы увидеть обычный порядок стека, можно использовать отрицательные поля, как показано ниже:
Серый блок
Синий блок
Коричневый блок
Блокам, показанным выше, назначен разный фоновый цвет и цвет рамки, а последним двум блокам, специально назначены отрицательные верхние отступы, чтобы проиллюстрировать обычный порядок стека. Серый блок появляется первым в разметке, синий блок вторым и коричневый блок третьим. Назначенные отрицательные поля отлично демонстрируют этот факт. Этим элементам не назначены значения z-index , они располагаются на странице в обычном порядке, или по умолчанию. Они накладываются друг на друга, благодаря отрицательным полям.
Почему появляется путаница?
Несмотря на то, что z-index не сложное для понимания свойство, при ошибочном толковании, оно может привести в заблуждение начинающих разработчиков. Это заблуждение появляется потому, что свойство z-index будет работать только с тем элементом, у которого свойство position установлено в одно из трех значений: absolute , fixed или relative .
Чтобы продемонстрировать, что z-index, работает только с позиционированными элементами, вот те же самые три блока, вместе с примененными значениями z-index, для изменения обычного порядка слоев:
Серый блок
Синий блок
Коричневый блок
Серому блоку, установлено значение z-index, равное “9999” ; синему блоку, установлено значение z-index, равное “500” ; и коричневому блоку, установлено значение z-index, равное “1” . Логично было бы предположить, что порядок, в котором уложены блоки, должен изменится. Но этого не случилось в данном примере, потому что, не одному из этих элементов, не назначено свойство position .
Вот те же самые блоки, но только с добавленным свойством position: relative , к каждому из них, и ранее назначенные свойства z-index:
Серый блок
Синий блок
Коричневый блок
Вот теперь, мы получили желаемый результат: Порядок элементов изменился; серый блок перекрывает синий, а синий, в свою очередь, перекрывает коричневый.
Синтаксис
Свойство z-index может влиять на порядок слоев, как у блочных, так и у строчных элементов, и устанавливается назначением положительного или отрицательного, целого значения, или значения auto. Значение auto , определяет элементу такой же порядок слоев, как у родительского элемента.
Вот так выглядит CSS-код третьего примера, где свойство z-index применяется правильно:
#grey_box { width: 200px; height: 200px; border: solid 1px #ccc; background: #ddd; position: relative; z-index: 9999; } #blue_box { width: 200px; height: 200px; border: solid 1px #4a7497; background: #8daac3; position: relative; z-index: 500; } #gold_box { width: 200px; height: 200px; border: solid 1px #8b6125; background: #ba945d; position: relative; z-index: 1; }
Опять же, не будет лишним еще раз напомнить, особенно начинающим разработчикам, что свойство z-index не будет работать до тех пор, пока вы не примените позиционирование к элементу.
Использование JavaScript
Если вы хотите динамически изменить значение z-index у элемента, с помощью JavaScript, то это довольно просто. Синтаксис используется такой же, как и для доступа к большинству CSS-свойств, просто замените, записанные через дефис CSS-свойства, на код, как показано ниже:
Var myElement = document.getElementById("gold_box"); myElement.style.position = "relative"; myElement.style.zIndex = "9999";
Как показано в примере, CSS-свойство « z-index », записывается как « zIndex ». Точно так же, « background-color » становится « backgroundColor », « font-weight » становится « fontWeight », и так далее.
Также, с помощью вышеуказанного кода, изменяется свойство position , потому что, z-index будет работать только с позиционированным элементом.
Неправильная обработка в IE и Firefox
При определенных обстоятельствах, в некоторых браузерах, свойство z-index может обрабатываться по-разному, это касается браузера Internet Explorer, версии 6 и 7, а также Firefox версии 2.
Элементы
В Internet Explorer 6, элемент
Элемент
– Выберите год – 2009 2010 2011
Коричневый блок
Если вы посмотрите на этот пример, с помощью браузера IE6, вы увидите, что элемент
Этот баг в IE6 создает проблемы с выпадающим меню, которое не может перекрыть элементы
Позиционирование Родительских элементов в IE6/7
Internet Explorer версии 6 и 7, неправильно сбрасывает контекст стека, по отношению к ближайшим, позиционированным, дочерним элементам. Для того чтобы продемонстрировать эту, чуть более сложную проблему, давайте снова отобразим два блока, но в этот раз, мы заключим первый блок, в позиционированный элемент.
Серый блок
Синий блок
Серому блоку, назначено свойство z-index, равное «9999» , синему блоку назначен z-index, равный «1» , и оба элемента позиционированы. Следовательно, при правильной обработке, серый блок, должен быть расположен поверх синего блока.
Опять же, если вы посмотрите на этот пример в браузере IE6, или IE7, вы увидите, как синий блок перекрывает серый блок. Эти браузеры неправильно «сбрасывают» контекст стека, по отношению к позиционированному родителю, но так быть не должно. Серому блоку назначено самое высокое значение z-index, и он должен быть расположен поверх синего блока. Все другие браузеры обрабатывают этот пример правильно.
Отрицательные значения в Firefox 2
В Firefox версии 2, отрицательное значение z-index, позиционирует элемент позади порядка слоев, вместо того, чтобы расположить его поверх фона и рамок элемента, которые устанавливают контекст стека. Ниже представлена картинка, иллюстрирующая этот баг в Firefox 2:
Ниже представлена HTML-версия этой картинки, так что, если вы посмотрите на страницу в Firefox 3 или в другом, современном браузере, вы увидите правильную обработку: Фон серого блока (который является элементом, устанавливающим контекст стека) появляется в самом низу, и текст, расположенный в сером блоке, появляется поверх синего блока, который соблюдает правила «обычного порядка слоев», как говорилось выше.
Серый блок
Синий блок
Примеры использования
Применение свойства z-index к различным элементам на странице, может предоставить быстрое решение для различных задач макета, и позволяет дизайнерам создавать более творческие проекты. Некоторые, интересные примеры использования z-index, на практике, приведены ниже.
CSS-Тултипы
Свойство z-index может быть использовано в качестве части тултипа, основанного на CSS, как показано в примере ниже, от trentrichardson.com :
Фото-галерея
Polaroid Photo Gallery , использует некоторые возможности CSS3 вместе с z-index, для создания фото-галереи, с забавным эффектом наведения.
Fancy Thumbnail Hover Effect – здесь, значение z-index изменяется с помощью JQuery-скрипта.
LightBox
Существует огромное количество качественных скриптов light box, для бесплатного использования, например плагин к JQuery FancyBox . Большинство, если не все они, используют свойство z-index:
Скрипты Light box используют полупрозрачное PNG-изображение, для затемнения фона, в то время как новый элемент, похожий на окно
Розовый квадрат имеет значение z-index, отличное от auto, что создает новый контекст наложения. Появление контекста наложения влияет на то, как отображаются дочерние элементы.
Можно изменить порядок наложения дочерних элементов розового квадрата. Однако их z-индекс имеет смысл только в контексте наложения . Это означает, что мы не сможем расположить оранжевый квадрат перед синим, потому что они находятся в разных контекстах наложения.
Если мы хотим, чтобы синий и оранжевый квадраты были частью одного и того же контекста наложения, мы можем сделать синий квадрат дочерним элементом розового квадрата. Это переместит синий квадрат за оранжевый.
https://codepen.io/ivhed/pen/erGoJE
Контекст наложения формируется не только при применении свойства z-index. Существует несколько других свойств , которые заставляют элементы создавать контексты наложения. Некоторые примеры: filter (фильтр), opacity (непрозрачность), and transform (трансформация).
Вернемся к нашему предыдущему примеру. Синий квадрат снова связан с розовым. На этот раз вместо добавления свойства z-index розовому квадрату мы применим к нему фильтр .
Blue, .pink, .orange {
position: absolute;
}
.pink {
filter: hue-rotate(20deg);
}
.blue {
z-index: 2;
}
.orange {
z-index: 3;
}
.green {
z-index: 100;
}
Оранжевый квадрат по-прежнему имеет более высокий z-индекс, чем синий, но по-прежнему отображается позади него. Это связано с тем, что значение фильтра заставило розовый квадрат создать новый контекст наложения.
Резюме
Используя z-индекс для позиционируемых элементов, мы можем изменить порядок наложения элементов, заданный по умолчанию.
При применении определенных CSS-свойств элемент может формировать контекст наложения. Значения z-индекса имеют смысл только в одинаковом контексте наложения.
Для получения дополнительной информации о принципе работы свойства z-index, рекомендую вам ознакомиться с этой статьей . Именно она вдохновляла меня в процессе работы над этой публикацией.
На самом деле элементы внутри HTML-документа генерируются в трех измерениях. Кроме привязки к осям X и Y их также можно размещать по оси Z . Для этого для элемента должно быть установлено CSS position relative или другие значения данного свойства:
Такие свойства, как margin , float и offset отвечают за то, где элемент будет располагаться на осях х и y , в то время как за расположение на оси z отвечает свойство z-index .
Свойство z-index
Это свойство позволяет определить:
- Расположение текущего элемента в стеке;
- Определяет ли текущий элемент новый контекст наложения (stacking level ).
Это свойство применимо исключительно к элементам с установленным позиционированием. То есть, свойство position элемента должно быть установлено как relative , absolute или fixed . У свойства z-index имеется три значения:
Пример кода
z-index: auto |
Уровень стека (очередность отображения элементов)
Это значение определяет, где именно на оси Z находится элемент. Чем больше число, тем выше элемент будет в стеке и к «поверхности » экрана:
Если свойство z-index не указано, то уровень элемента в стеке будет установлен в соответствии с порядком его размещения в древе документа. Элементы, которые указываются в коде позже, будут по умолчанию иметь более высокую позицию в стеке.
Вычисляем позицию в стеке
Кроме свойства z-index на position relative CSS элемента в стеке также влияет несколько факторов. Элементы располагаются в стеке в следующем порядке:
Позиция | Описание | CSS-код |
1 (bottom) | Элемент формирует контекст наложения. | z-index: |
2 | Дочерние элементы с отрицательным уровнем стека. | z-index: |
3 | Дочерние элементы со стилизацией In-flow, non-inline или без установленного позиционирования. | display: /* not inline */
position: static |
4 | Плавающие дочерние элементы без установленного позиционирования. | float: left | right
position: static |
5 | Дочерние элементы со стилизацией In-flow inline или без выставленного позиционирования. | display: /* inline */
position: static |
6 | Дочерние элементы с 0 уровнем стека. | z-index: auto | 0
position: relative | absolute | fixed |
7 (top) | Дочерние элементы с положительным уровнем стека. | z-index: position: relative | absolute | fixed |
Контекст наложения (stacking context)
При указании CSS position relative z index мы не всегда определяем ее относительно всех остальных элементов на странице. Уровень элемента в стеке отражает лишь его позицию в рамках отдельного контекста наложения.
Это может привести к ситуации, когда элемент с более высоким значением z-index не будет находиться «поверх » элемента с более низким значением.
Контекст наложения можно объяснить следующими правилами:
1. Исходный контекст наложения заключен в корневом элементе
Исходный контекст наложения в любом HTML-документе заключен в корневом элементе . До тех пор, пока не создано новых контекстов, уровень элемента в стеке будет по умолчанию относиться ко всем элементам на странице.
2. Создание новых контекстов с указанным свойством z-index
Мы создаем новый контекст наложения с помощью установки любого целого числа в свойстве z-index для элемента. Это дает возможность указать уровень текущего элемента в стеке целым числом, а также создать новый контекст наложения.
Впоследствии новый контекст будет применяться ко всем дочерним элементам данного элемента. Их уровень теперь указывается только в рамках данного контекста, и не относится к корневому элементу.
В приведенном ниже примере .foo относится к контексту наложения 1, а .bar – к контексту наложения 2:
3. Элементы нельзя располагать выше или ниже уровня родительского
Если у родительского элемента имеется установленный CSS position relative z index , то все дочерние элементы не могут располагаться над или под этим уровнем (в рамках контекста наложения родительского элемента ). В приведенном ниже примере, несмотря на то, что у .bar значение z-index выше, чем у .baz , этот элемент все равно расположен “под ” ним. Так происходит потому, что в контексте 1 .bar не может располагаться выше или ниже уровня 1.
CSS
.foo { z-index: 1; }
.bar { z-index: 1000; }
.baz { z-index: 2; }
Перевод статьи “How z-index Works ” был подготовлен дружной командой проекта .
Хорошо Плохо