Пошук уроків, статей та іншого контенту
Керуватимете перекриттям позиціонованих елементів за допомогою z-index і контекстів накладання.
Коли елементи перекриваються, браузер визначає, який із них буде ближчим до користувача. Цей порядок називають порядком накладання або порядком по осі z.
елемент із більшим значенням z-index зазвичай відображається поверх елемента з меншим значенням;
елемент із z-index: 0 розташований вище за елементи з від’ємним z-index;
якщо значення однакові, перевагу зазвичай має елемент, який пізніше розташований у HTML;
z-index порівнюється не завжди глобально — важливу роль відіграють контексти накладання.
.card {
position: relative;
z-index: 2;
}z-index приймає цілі числові значення:
.element {
z-index: -1;
}
.element {
z-index: 0;
}
.element {
z-index: 10;
}Число не є одиницею вимірювання. z-index: 1000 не означає «на тисячу пікселів ближче». Воно лише визначає порядок порівняно з іншими елементами в тому самому контексті накладання.
z-indexНайчастіше z-index застосовують до позиціонованих елементів:
.element {
position: relative;
z-index: 2;
}Позиціонованими вважаються елементи з такими значеннями position:
relative;
absolute;
fixed;
sticky.
У сучасному CSS z-index також працює для дочірніх елементів flex-контейнерів і grid-контейнерів, навіть якщо для них не задано position.
.container {
display: flex;
}
.item {
z-index: 2;
}Для звичайних непозиціонованих блоків поза flex або grid-контейнером одного z-index може бути недостатньо.
У наступному прикладі два блоки перекриваються. Блок із більшим z-index відображається поверх іншого.
<!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>z-index</title>
<style>
.scene {
position: relative;
width: 420px;
height: 260px;
margin: 40px auto;
border: 2px solid #334155;
background: #f8fafc;
}
.box {
position: absolute;
width: 180px;
height: 130px;
padding: 16px;
box-sizing: border-box;
color: white;
font: 600 18px sans-serif;
border-radius: 12px;
}
.box--blue {
top: 35px;
left: 35px;
z-index: 1;
background: #2563eb;
}
.box--red {
top: 90px;
left: 150px;
z-index: 2;
background: #dc2626;
}
</style>
</head>
<body>
<div class="scene">
<div class="box box--blue">z-index: 1</div>
<div class="box box--red">z-index: 2</div>
</div>
</body>
</html>Червоний блок перекриває синій у спільній області, оскільки його z-index більший.
Якщо поміняти значення місцями:
.box--blue {
z-index: 3;
}
.box--red {
z-index: 2;
}синій блок буде поверх червоного.
z-indexЯкщо елементи мають однаковий порядок накладання, браузер використовує порядок їхнього малювання. Для елементів на одному рівні зазвичай поверх буде той, який розташований пізніше в HTML.
<div class="box box--first"></div>
<div class="box box--second"></div>.box {
position: absolute;
width: 100px;
height: 100px;
z-index: 1;
}
.box--first {
background: royalblue;
}
.box--second {
margin-left: 40px;
margin-top: 40px;
background: tomato;
}Обидва елементи мають z-index: 1, тому в зоні перекриття другий елемент буде поверх першого.
Це можна змінити, явно задавши різні значення z-index:
.box--first {
z-index: 2;
}
.box--second {
z-index: 1;
}Контекст накладання — це окрема система координат для порівняння елементів по осі z.
Дочірні елементи порівнюються спочатку всередині свого контексту. Увесь батьківський контекст потім порівнюється з іншими контекстами як єдиний рівень.
Це означає, що велике значення z-index дочірнього елемента не обов’язково дозволить йому перекрити елемент з іншого контексту.
Наприклад:
<div class="layout">
<div class="panel panel--left">
Ліва панель
</div>
<div class="panel panel--right">
<div class="tooltip">
Підказка
</div>
</div>
</div>.layout {
position: relative;
width: 500px;
height: 260px;
border: 2px solid #334155;
}
.panel {
position: absolute;
width: 260px;
height: 160px;
padding: 20px;
box-sizing: border-box;
}
.panel--left {
top: 50px;
left: 40px;
z-index: 2;
background: #2563eb;
}
.panel--right {
top: 90px;
left: 200px;
z-index: 1;
background: #16a34a;
}
.tooltip {
position: absolute;
top: 20px;
left: 150px;
z-index: 9999;
width: 180px;
padding: 12px;
color: white;
background: #111827;
}tooltip має z-index: 9999, але він усе одно не зможе перекрити panel--left.
Причина:
panel--right створює власний контекст із z-index: 1;
tooltip має велике значення лише всередині цього контексту;
увесь контекст panel--right має рівень 1;
panel--left належить до рівня 2 і тому відображається поверх усього контексту правої панелі.
Умовно браузер порівнює не 9999 з 2, а:
контекст panel--right: 1
контекст panel--left: 2Щоб підказка могла конкурувати з лівою панеллю, потрібно змінити рівень батьківського контексту:
.panel--right {
z-index: 3;
}Тепер уся права панель, разом із підказкою, буде поверх лівої.
Контекст накладання може створювати не лише z-index. Найпоширеніші випадки:
кореневий елемент документа;
позиціонований елемент зі значенням z-index, відмінним від auto;
елемент із position: fixed;
елемент із position: sticky;
flex- або grid-елемент зі значенням z-index, відмінним від auto;
елемент із opacity, меншою за 1;
елемент із transform, відмінним від none;
елемент із filter, відмінним від none;
елемент із isolation: isolate.
Наприклад, прозорість створює новий контекст:
.card {
opacity: 0.99;
}Навіть значення 0.99, яке майже не помітне візуально, може вплинути на порядок накладання.
Так само контекст створює трансформація:
.card {
transform: translateZ(0);
}Тому не варто додавати transform, opacity або z-index без потреби, якщо важлива взаємодія елемента з іншими шарами.
Для компонентів інтерфейсу зручно заздалегідь визначити кілька рівнів:
:root {
--layer-base: 0;
--layer-content: 10;
--layer-dropdown: 100;
--layer-modal: 1000;
--layer-notification: 1100;
}Потім використовувати їх послідовно:
.page-content {
position: relative;
z-index: var(--layer-content);
}
.dropdown {
position: absolute;
z-index: var(--layer-dropdown);
}
.modal {
position: fixed;
z-index: var(--layer-modal);
}
.notification {
position: fixed;
z-index: var(--layer-notification);
}Такий підхід зрозуміліший, ніж випадкові значення z-index: 999, z-index: 9999 і z-index: 99999.
Великі числа не розв’язують проблему контекстів. Якщо елемент перебуває в батьківському контексті з нижчим рівнем, його z-index все одно обмежений цим контекстом.
z-indexВід’ємні значення дають змогу розмістити елемент позаду інших елементів:
.background-shape {
position: absolute;
z-index: -1;
}Це часто використовують для декоративних фігур:
.card {
position: relative;
isolation: isolate;
padding: 24px;
background: white;
}
.card::before {
content: "";
position: absolute;
inset: 8px -8px -8px 8px;
z-index: -1;
border-radius: 16px;
background: #bfdbfe;
}У цьому прикладі isolation: isolate створює окремий контекст накладання для картки. Завдяки цьому декоративний псевдоелемент не опиняється несподівано позаду елементів, які розташовані за межами картки.
З від’ємним z-index потрібно бути обережним: елемент може опинитися позаду фону свого батьківського елемента або стати непомітним.
z-index і overflowz-index змінює порядок накладання, але не скасовує обрізання вмісту.
.container {
position: relative;
width: 200px;
height: 100px;
overflow: hidden;
}
.tooltip {
position: absolute;
top: 80px;
z-index: 100;
}Якщо підказка виходить за межі .container, overflow: hidden може її обрізати. Навіть z-index: 100 не зробить обрізану частину видимою.
Якщо обрізання не потрібне, можна використати:
.container {
overflow: visible;
}Але змінювати overflow потрібно лише тоді, коли це відповідає поведінці компонента.
z-indexЯкщо елемент не відображається поверх іншого, перевірте:
Чи перекриваються елементи фізично. z-index не змінює координати та розміри.
Чи створює батьківський елемент окремий контекст накладання.
Який z-index має батьківський контекст, а не лише сам проблемний елемент.
Чи не обрізає елемент властивість overflow.
Чи не створюють transform, opacity, filter або isolation неочікуваний контекст.
Чи застосовується правило CSS і чи не перекривається іншим правилом.
Чи не знаходяться елементи в різних частинах структури, де їхні z-index не можна порівняти безпосередньо.
У DevTools браузера корисно перевірити стилі самого елемента та всіх його батьків. Особливу увагу слід звернути на position, z-index, transform, opacity, filter, isolation і overflow.
z-index завжди допоможе.tooltip {
position: absolute;
z-index: 999999;
}Велике число не допоможе, якщо tooltip знаходиться в контексті, який розташований нижче за інший контекст. Спочатку потрібно перевірити батьківські елементи.
z-index без правильного типу елементаДля звичайного блоку z-index поза flex або grid-контейнером може не дати очікуваного результату. Перевірте position або структуру контейнера.
Значення 999, 9999 і 99999 не формують зрозумілої системи. Краще створити кілька логічних рівнів і використовувати їх послідовно.
overflowЕлемент може мати правильний z-index, але залишатися невидимим через обрізання батьківським контейнером.
transform, opacity, filter та isolation можуть змінити поведінку шарів. Якщо порядок накладання став несподіваним, перевірте ці властивості на батьківських елементах.
z-index без перевірки фонуЕлемент із від’ємним z-index може опинитися позаду фону батьківського елемента. Для декоративних шарів часто безпечніше створити окремий контекст за допомогою isolation: isolate.
z-index визначає порядок накладання елементів по осі z.
Більше значення зазвичай означає розташування ближче до користувача.
Для звичайних блоків найчастіше потрібен position, а flex- і grid-елементи можуть використовувати z-index без нього.
Елементи порівнюються в межах одного контексту накладання.
Дочірній елемент не може вийти за межі порядку свого батьківського контексту лише завдяки великому z-index.
position, z-index, transform, opacity, filter та isolation можуть створювати контексти накладання.
z-index не скасовує обрізання через overflow.
Для складного інтерфейсу краще використовувати невелику, зрозумілу систему рівнів шарів.