Что делает z-index
Когда элементы перекрываются, z-index решает, какой из них рисуется спереди. Побеждает большее число. Он действует на позиционированные элементы (любой position, кроме static) и на flex- и grid-элементы:
Без z-index более поздние элементы в HTML рисуются поверх более ранних, поэтому C закрыл бы B, а B закрыл бы A. Значения z-index меняют это: A спереди, затем C, затем B.
Значения
| Значение | Смысл |
|---|---|
auto (по умолчанию) | На уровне 0 вместе с соседями, контекст наложения не создает |
0 | Уровень 0, но создает контекст наложения |
| Положительное целое | Перед меньшими значениями |
| Отрицательное целое | За уровнем 0 и за содержимым родителя, если родитель образует контекст наложения |
Допустимы только целые числа: z-index: 1.5 игнорируется.
Почему z-index 9999 может проиграть: контексты наложения
Значения z-index не сравниваются по всей странице. Элементы группируются в контексты наложения, и z-index упорядочивает только элементы внутри одного контекста. Сам контекст затем размещается как один слой по z-index элемента, который его создал.
Ниже у синего выпадающего меню z-index: 9999, но оно находится внутри шапки с z-index: 1. У зеленого баннера, соседа этой шапки, z-index: 2. Весь слой шапки, вместе с меню, оказывается под баннером:
Нажмите кнопку. С z-index: auto шапка больше не образует контекст наложения, поэтому 9999 меню сравнивается с 2 баннера напрямую, и меню выходит вперед. Поднять меню до 99999 не помогло бы никогда.
Что создает контекст наложения
Любое из этого превращает элемент в собственный контекст наложения и запирает z-index всего, что внутри:
| Свойство | Условие |
|---|---|
position: relative или absolute | С z-index, отличным от auto |
position: fixed или sticky | Всегда |
| Flex- или grid-элемент | С z-index, отличным от auto |
opacity | Меньше 1 |
transform, scale, rotate, translate | Любое значение, кроме none |
filter, backdrop-filter | Любое значение, кроме none |
isolation | isolate |
mix-blend-mode | Любое значение, кроме normal |
will-change | С указанием любого из свойств выше |
contain | layout или paint (а также strict, content) |
Неожиданнее всего opacity и transform: если добавить родителю затухание или анимацию при наведении, его выпадающее меню вдруг может оказаться под следующей секцией.
z-index: 10 у подсказки должен ставить ее над следующей колонкой. Но opacity: 0.99 делает первую колонку контекстом наложения с z-index auto (уровень 0), а вторая колонка идет в HTML позже на том же уровне, поэтому она рисуется поверх всей первой колонки вместе с подсказкой. Удалите строку с opacity, и подсказка снова впереди.
Отрицательный z-index
Отрицательный z-index ставит элемент за его соседей. Если родитель не образует контекст наложения, элемент может уйти даже за фон родителя, и это частый сюрприз. isolation: isolate у родителя создает контекст без других визуальных эффектов и удерживает отрицательный дочерний элемент внутри:
Без isolation янтарная рамка уходит за собственный серый фон кнопки, и виден только ее край. С isolation: isolate рамка остается внутри контекста наложения кнопки: над ее фоном, под ее текстом.
Шкала z-index
Выберите для всего сайта несколько именованных слоев вместо гонки чисел:
:root {
--z-dropdown: 10;
--z-sticky: 20;
--z-overlay: 30;
--z-modal: 40;
--z-toast: 50;
}
.modal { position: fixed; z-index: var(--z-modal); }
Большинство ошибок наложения это ошибки контекстов, а не чисел, поэтому небольшая шкала плюс isolation: isolate у компонентов, которые используют z-index внутри себя, решает многое. z-index нужно позиционирование; оно разобрано на странице про position.
Частые ошибки
- z-index у статичного элемента. Добавьте
position: relative(или сделайте его flex- или grid-элементом). - Гонка до 9999. Если родитель образует контекст ниже конкурента, никакое значение у дочернего элемента не победит. Найдите этот контекст.
- Новые
opacity,transformилиfilterу родителя, которые вдруг запирают его выпадающее меню. - Дробные значения.
z-index: 1.5невалидно. - Ожидание, что
z-index: 0иautoведут себя одинаково.0создает контекст наложения,autoнет. - Модальные окна внутри глубоко вложенных компонентов. Отрисовывайте их ближе к концу
<body>(или используйте верхний слой элемента<dialog>), чтобы их не запер контекст ни одного предка.
Часто задаваемые вопросы
Что делает z-index?
Задает порядок наложения перекрывающихся элементов: большее значение рисуется перед меньшим в пределах одного контекста наложения. По умолчанию auto, а значения это целые числа, в том числе отрицательные.
Почему не работает z-index?
Либо элемент не позиционирован (z-index нужен position, отличный от static, или элемент должен быть flex- или grid-потомком), либо он находится внутри родителя, который образует контекст наложения с более низким порядком. Дочерний элемент никогда не поднимется над элементом, ниже которого стоит его контекст наложения, каким бы ни был его собственный z-index.
Что такое контекст наложения?
Группа элементов, которые накладываются вместе как один слой. Внутри нее дочерние элементы упорядочены по своему z-index; снаружи всю группу размещает z-index элемента, который ее создал.
Что создает контекст наложения?
Среди прочего: корневой элемент, позиционированный элемент с z-index, отличным от auto, position: fixed или sticky, flex- или grid-потомок с z-index, opacity меньше 1, transform, filter, isolation: isolate и will-change для этих свойств.
Работает ли z-index без position?
У обычных блочных и строчных элементов нет: position: static его игнорирует. У flex- и grid-элементов он работает без всякого position.