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

Наконец я решила, что прошла уже достаточно длинный путь проб и ошибок и что пора наконец основательно изучить этот вопрос. Я надеюсь, что эта статья поможет и вам разобраться, почему свойство z-index может работать не так, как ожидается.

Положение элементов по умолчанию

Для начала давайте разберемся с тем, как браузер по умолчанию позиционирует элементы, когда не указаны значения z-index:

  1. Корневой элемент (элемент <html>)
  2. Непозиционируемые элементы в том порядке, в котором они определены
  3. Позиционированные элементы в том порядке, в котором они определены

Непозиционируемый элемент — это элемент со значением position: static по умолчанию. Позиционируемый элемент представляет собой элемент с любым другим значением свойства position. Примерами других значений являются: absolute (абсолютное), relative (относительное), sticky(приклеенное) или fixed (фиксированное).

HTML:

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”green”></div>

CSS:

/* Это только CSS, который подходит для примера. Для отображения полного CSS воспользуйтесь ссылками под изображениями. */

.blue, .pink, .orange {
position: absolute;
}
https://codepen.io/ivhed/pen/QrdEBB

Мы определили зеленый квадрат в конце документа. Тем не менее, он появляется не впереди, а позади всех остальных элементов, потому что у него не задано позиционирование.

Позиционирование с применением z-index

Если теперь мы хотим изменить порядок расположения элементов, мы можем использовать CSS-свойство z-index. Элемент с более высоким z-индексом будет отображаться перед элементом с более низким z-индексом. Следует отметить, что z-индекс работает только с позиционируемыми элементами.

.blue, .pink, .orange {
  position: absolute;
}

.blue {
z-index: 2;
}

.orange {
z-index: 3;
}

.green {
z-index: 100; // has no effect since the green box is non- positioned
}
https://codepen.io/ivhed/pen/xjqmpV

Перед синим квадратом отображается оранжевый квадрат, потому что он имеет более высокий z-index.

Контекст наложения (stacking order)

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

HTML:

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”purple”></div>
<div class=”green”></div>

CSS:

.blue, .pink, .orange, .purple {
  position: absolute;
}

.purple {
z-index: 0;
}

.pink {
z-index: 1;
}

.blue {
z-index: 2;
}

.orange {
z-index: 3;
}

.green {
z-index: 100;
}
https://codepen.io/ivhed/pen/YLZdjx

Наш розовый квадрат отображается перед фиолетовым, как и ожидалось, но что же случилось с оранжевым квадратом? Почему он внезапно оказался за синим, хотя у него более высокий z-индекс? Это связано с тем, что добавление значения z-индекс в элемент формирует то, что называется контекстом наложения.

Розовый квадрат имеет значение z-index, отличное от auto, что создает новый контекст наложения. Появление контекста наложения влияет на то, как отображаются дочерние элементы.

Можно изменить порядок наложения дочерних элементов розового квадрата. Однако их z-индекс имеет смысл только в контексте наложения. Это означает, что мы не сможем расположить оранжевый квадрат перед синим, потому что они находятся в разных контекстах наложения.

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

<div class=”pink”>
  <div class=”orange”></div>
  <div class=”blue”></div>
</div>
<div class=”purple”></div>
<div class=”green”></div>
https://codepen.io/ivhed/pen/erGoJE

Контекст наложения формируется не только при применении свойства z-index. Существует несколько других свойств, которые заставляют элементы создавать контексты наложения. Некоторые примеры: filter (фильтр), opacity (непрозрачность), and transform (трансформация).

Вернемся к нашему предыдущему примеру. Синий квадрат снова связан с розовым. На этот раз вместо добавления свойства z-index розовому квадрату мы применим к нему фильтр.

HTML:

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”green”></div>

CSS:

.blue, .pink, .orange {
  position: absolute;
}

.pink {
filter: hue-rotate(20deg);
}

.blue {
z-index: 2;
}

.orange {
z-index: 3;
}

.green {
z-index: 100;
}
https://codepen.io/ivhed/pen/LmWMQb

Оранжевый квадрат по-прежнему имеет более высокий z-индекс, чем синий, но по-прежнему отображается позади него. Это связано с тем, что значение фильтра заставило розовый квадрат создать новый контекст наложения.

Резюме

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

При применении определенных CSS-свойств элемент может формировать контекст наложения. Значения z-индекса имеют смысл только в одинаковом контексте наложения.

Перевод статьи Veronika Ivhed: “Z-Index Explained: How to Stack Elements Using CSS

Предыдущая статьяОтладка Node.js с помощью Google Chrome
Следующая статьяНеужели комментировать код — это плохо?