От автора: Z-index — это свойство CSS, которое позволяет размещать элементы в слоях друг над другом. Это супер полезно, и, честно говоря, очень важно знать, как использовать в CSS этот инструмент. К сожалению, z-index является одним из тех свойств, которые не всегда ведут себя интуитивно. Сначала это кажется простым — более высокий номер z-индекса означает, что элемент будет поверх элементов с более низкими номерами z-index.
Но есть некоторые дополнительные правила, которые усложняют ситуацию. И вы не всегда можете исправить положение, установив z-index 999999! В этой статье подробно объясняются четыре наиболее распространенных причины, по которым z-index CSS не работает, и как именно вы можете это исправить.
Мы рассмотрим некоторые примеры кода. Прочитав эту статью, вы сможете избегать этих распространенных ошибок с z-index! Давайте рассмотрим первую причину, по которой не срабатывает свойство:
1. Элементы в том же контексте стека будут отображаться в порядке их указания, причем последние элементы будут располагаться поверх предыдущих
В первом примере у нас есть относительно простой макет, который включает в себя 3 основных элемента:
Изображение кота
Белый блок с текстом
Еще одно изображение того же кота
Вот HTML-разметка:
<div class="cat-top"></div> <div class="content__block"> Meow meow meow... </div> <div class="cat-bottom"></div>
В этом макете в идеале нам нужно, чтобы белый блок текста был поверх обоих котов. Чтобы попытаться достичь этого, мы добавили в CSS некоторые отрицательные поля для обоих изображений кошек, чтобы они немного перекрывали белый блок:
.cat-top { margin-bottom: -110px; } .cat-bottom { float: right; margin-top: -120px; }
Тем не менее, это выглядит так:
Первый кот действительно расположен под белым блоком контента, как мы и хотим. Но второе изображение кота расположено поверх текста!
Почему это происходит? Причиной такого поведения является естественный порядок размещения на веб-странице. Эти рекомендации определяют, какие элементы будут сверху, а какие снизу. Даже если для элементов не установлен z-индекс, есть и причина, по которой они будут размещаться поверх друг друга.
В нашем случае ни один из элементов не имеет значения z-index. Таким образом, их порядок наложения определяется их порядком указания. Согласно этому правилу, элементы, которые указываются в разметке позже, будут на размещены поверх элементов, которые идут перед ними.
В нашем примере с кошками и белым блоком они подчиняются этому правилу. Вот почему первый кот находится под элементом белого блока, а белый блок под вторым котом.
Хорошо, с порядком размещения мы разобрались, но как нам исправить CSS, чтобы второй кот находился под белым блоком? Давайте рассмотрим вторую причину:
2. Для элемента не задана позиция
Одно из указаний, определяющих порядок наложения, заключается в том, установлена ли позиция для элемента или нет. Чтобы установить позицию для элемента, добавьте свойство CSS position с каким-либо значением, кроме static, например, relative или absolute.
Согласно этому правилу позиционируемые элементы будут отображаться поверх непозиционированных элементов. Таким образом, установив для белого блока position: relative, и оставив два элемента котов не позиционированными, вы поместите белый блок поверх котов в порядке расположения. Вот как это будет выглядеть — вы также можете поэкспериментировать с Codepen выше.
Юху! Теперь, следующее, что мы хотим сделать, это повернуть нижнюю кошку вверх ногами, используя свойство transform. Таким образом, обе кошки окажутся под белым блоком, с торчащими из-под него головами. Но это может вызвать еще большую путаницу с z-index. Мы рассмотрим проблему и решение в следующей части.
3. Установка некоторых свойств CSS, таких как opacity или transform, помещает элемент в новый контекст стека
Как мы только что упомянули, мы хотим перевернуть нижнюю кошку вверх ногами. Для этого мы добавим transform: rotate(180deg).
.cat-bottom { float: right; margin-top: -120px; transform: rotate(180deg); }
Но это заставляет нижнюю кошку снова отображаться поверх белого блока!
Возможно, вы не часто сталкиваетесь с этой проблемой, но другой аспект порядка размещения заключается в том, что некоторые свойства CSS, такие как transform или opacity помещают элемент в его собственный, новый контекст позиционирования.
Это означает, что добавление transform к элементу .cat-bottom приводит к тому, что он ведет себя так, как если бы он имел значение z-index — 0. Даже если для него не установлено position или z-index вообще!
Помните, мы не добавляли значение z-index для белого блока, только position: relative. Этого было достаточно, чтобы расположить белый блок поверх котов, которые непозиционированы.
Но так как элемент .bottom-cat действует так, как если бы он был относительно позиционирован с помощью z-index: 0, преобразование поместило его поверх белого блока.
Решение этой проблемы состоит в том, чтобы установить position: relative и явно установить z-index, как минимум, для белого блока. Вы можете сделать еще один шаг и установить position: relative и опустить z-index для элементов котов, просто чтобы еще больше обезопасить себя.
.content__block { position: relative; z-index: 2; } .cat-top, .cat-bottom { position: relative; z-index: 1; }
На мой взгляд, это решит большинство, если не все основные проблемы с z-index. Теперь давайте перейдем к последней причине, почему z-index может не работать. Это немного сложнее, потому что связано с родительскими и дочерними элементами.
4. Элемент находится в нижнем контексте стека из-за уровня z-индекса его родителя
Давайте рассмотрим такой пример кода:
Вот что у нас есть: простая веб-страница с обычным контентом и розовая боковая вкладка с надписью «Отправить отзыв», расположенная поверх контента.
Затем, когда вы нажимаете на фотографию кота, открывается модальное окно с прозрачным серым фоном. Однако, даже когда модальное окно открыто, боковая вкладка все еще находится поверх серого фона. Мы хотим, чтобы фон отображался поверх всего, включая боковую вкладку. Давайте посмотрим на CSS для данных элементов:
.content { position: relative; z-index: 1; } .modal { position: fixed; z-index: 100; } .side-tab { position: fixed; z-index: 5; }
vВсе элементы позиционированы, а боковая вкладка имеет значение z-index: 5, что позиционирует ее поверх элемента контента, который имеет z-index: 1.
Модал имеет z-index: 100, что должно установить его поверх боковой вкладки с z-index: 5. Но вместо этого модал находится под боковой вкладкой. Почему это происходит?
Ранее мы рассмотрели некоторые факторы, которые входят в контекст стека, например, если элемент имеет позицию, а также его порядок в разметке.
Но еще один аспект контекста стека заключается в том, что дочерний элемент ограничен контекстом стека его родителя.
Давайте подробнее рассмотрим три элемента, о которых идет речь. Вот разметка, которая у нас есть:
<section class="content"> <div class="modal"></div> </section> <div class="side-tab"></div>
Глядя на разметку, мы видим, что элементы контента и боковой вкладки являются одноуровневыми элементами. То есть они существуют на одном уровне в разметке (это отличается от уровня z-index). А модал является дочерним для элемента контента.
Поскольку модал находится внутри элемента контента, его значение z-index:100 влияет только на его родительский элемент контента. Например, если бы существовали другие дочерние элементы, являющиеся одноуровневыми элементами для модала, их значения z-index поместили бы их поверх или ниже друг друга.
Но значение z-index этих дочерних элементов элемента контент ничего не значит вне родительского элемента, и он имеет значение z-index: 1.
Так что его потомки, в том числе модал, не могут вырваться из этого уровня z-index. (Вы можете представить это с помощью печальной метафоры: ребенок ограничен родителями и не может освободиться от них.)
Есть несколько решений этой проблемы:
Решение. Переместите модал за пределы родительского элемента контента в основной контекст стека страницы.
Исправленная разметка будет выглядеть следующим образом:
<section class="content"></section> <div class="modal"></div> <div class="side-tab"></div>
Теперь элемент модала является одноуровневых элементом для двух других. Это помещает все три элемента в один и тот же контекст стека, так что каждый из их уровней z-index теперь будет влиять друг на друга. В этом новом контексте стека элементы будут отображаться в следующем порядке сверху вниз:
модал ( z-index: 100)
боковая вкладка ( z-index: 5)
контент ( z-index: 1)
Альтернативное решение: удалите позиционирование для контента, чтобы оно не ограничивало z-index модала. Если вы не хотите или не можете изменить разметку, тогда вы можете исправить эту проблему, удалив параметр position для элемента контента:
.content { // position не задано } .modal { position: absolute; z-index: 100; } .side-tab { position: absolute; z-index: 5; }
Поскольку элемент контента теперь не позиционирован, он больше не будет ограничивать значение z-index модала . Таким образом, открытый модал будет располагаться поверх элемента боковой вкладки, так как он имеет z-index:100.
Хотя это работает, я лично выбрал бы первое решение.
Потому что, если по какой-то причине в будущем вам придется позиционировать элемент контента, он снова ограничит порядок модала в контексте стека.
Заключение
Я надеюсь, что вы нашли это руководство полезным! Подводя итог, большинство проблем с z-index могут быть решены с помощью следующих двух рекомендаций:
Убедитесь, что для элементов задано позиционирование и правильное значение z-индекса.
Убедитесь, что у вас нет родительских элементов, ограничивающих уровень z-index их дочерних элементов.
Источник: https://www.freecodecamp.org
Редакция: Команда webformyself.