Ви коли-небудь встановлювали z-index: 99999 для елемента у вашому CSS, і він не відображався поверх інших елементів? Таке велике значення може легко розмістити цей елемент візуально над будь-чим іншим, припускаючи, що для всіх різних елементів встановлено нижче значення або не встановлено взагалі. Веб-сторінка зазвичай представлена ​​у двовимірному просторі; однак, застосовуючи специфічні властивості CSS, для передачі глибини вводиться уявна площина осі z. Ця площина перпендикулярна екрану, і з неї користувач сприймає порядок елементів, один над іншим. Ідея, що лежить в основі уявної осі z, сприйняття користувачем елементів стека, полягає в тому, що властивості CSS, які її створюють, поєднуються, щоб утворити те, що ми називаємо контекстом стека. Ми збираємося поговорити про те, як елементи «розташовуються» на веб-сторінці, що контролює порядок укладання, а також практичні підходи до «вилучення» елементів у разі потреби. Про контексти стекування Уявіть свою веб-сторінку як стіл. Додаючи HTML-елементи, ви кладете аркуші паперу один за одним на стіл. Останній розміщений аркуш паперу еквівалентний останньому доданому елементу HTML і розташовується поверх усіх інших паперів, розміщених перед ним. Це нормальний потік документів, навіть для вкладених елементів. Сам стіл представляє кореневий контекст стекування, сформований елементом , який містить усі інші папки. Тепер у гру вступають конкретні властивості CSS. Такі властивості, як положення (із z-індексом), непрозорість, перетворення та вміст), діють як папка. Ця папка приймає елемент і всі його дочірні елементи, витягує їх із основного стеку та групує в окремий підстек, створюючи те, що ми називаємо контекстом стеку. Для позиціонованих елементів це відбувається, коли ми оголошуємо значення z-індексу, відмінне від auto. Для таких властивостей, як непрозорість, трансформація та фільтр, контекст стекування створюється автоматично, коли застосовуються певні значення.

Спробуйте зрозуміти це: якщо аркуш паперу (тобто дочірній елемент) опиниться в папці (тобто в контексті стекування батьківського елемента), він ніколи не зможе вийти з цієї папки або поміститися між паперами в іншій папці. Його z-індекс тепер релевантний лише у власній папці.

На малюнку нижче папір B тепер знаходиться в контексті стекування папки B, і його можна замовити лише разом з іншими паперами в папці.

Уявіть, якщо хочете, що у вас на столі є дві папки:

Папка А
Папка B

.folder-a { z-індекс: 1; } .folder-b { z-індекс: 2; }

Давайте трохи оновимо розмітку. Всередині папки A — це спеціальна сторінка, z-індекс: 9999. Всередині папки B — звичайна сторінка, z-індекс: 5.

Спеціальна сторінка

Звичайна сторінка

.special-page { z-index: 9999; } .plain-page { z-index: 5; }

Яка сторінка зверху? Це .plain-сторінка в папці B. Браузер ігнорує дочірні документи та спочатку укладає дві папки. Він бачить папку B (z-індекс: 2) і розміщує її поверх папки A (z-індекс: 1), оскільки ми знаємо, що два більше, ніж одиниця. Тим часом сторінка .special-page, для якої встановлено значення z-index: 9999, знаходиться в нижній частині стека, навіть якщо її z-index має найвище можливе значення. Контексти стекування також можуть бути вкладеними (папки всередині папок), створюючи «генеалогічне дерево». Застосовується той самий принцип: дитина ніколи не зможе уникнути папки батьків. Тепер, коли ви розумієте, як контексти стекування поводяться як папки, які групують і змінюють порядок шарів, варто запитати: чому певні властивості, як-от transform і opacity, створюють нові контексти стекування? Ось у чому річ: ці властивості не створюють контексти стекування через те, як вони виглядають; вони роблять це через те, як браузер працює під капотом. Коли ви застосовуєте трансформацію, непрозорість, фільтр чи перспективу, ви повідомляєте браузеру: «Гей, цей елемент може рухатися, обертатися чи зникати, тому будьте готові!»

Коли ви використовуєте ці властивості, браузер створює новий контекст стекування для більш ефективного керування відтворенням. Це дозволяє браузеру самостійно обробляти анімацію, трансформації та візуальні ефекти, зменшуючи необхідність перераховувати, як ці елементи взаємодіють з рештою сторінки. Подумайте про це як про те, що веб-переглядач каже: «Я оброблятиму цю папку окремо, щоб мені не довелося переставляти весь стіл кожного разу, коли на ньому щось змінюється». Але єпобічний ефект. Коли браузер піднімає елемент у власний шар, він повинен «зрівняти» все в ньому, створюючи новий контекст стекування. Це як взяти папку зі столу, щоб обробляти її окремо; все всередині цієї папки групується, і браузер тепер розглядає це як єдине ціле, коли вирішує, що знаходиться поверх чого. Таким чином, хоча властивості трансформації та непрозорості можуть не впливати на візуальне укладання елементів, вони впливають, і це для оптимізації продуктивності. Кілька інших властивостей CSS також можуть створювати контексти стекування з подібних причин. MDN надає повний список, якщо ви хочете копнути глибше. Їх досить багато, що лише ілюструє, наскільки легко ненавмисно створити контекст стекування, не знаючи про це. Проблема «розпакування». Проблеми зі штабелюванням можуть виникати з багатьох причин, але деякі зустрічаються частіше, ніж інші. Модальні компоненти є класичним шаблоном, оскільки вони вимагають перемикання компонента в положення «відкритий» на верхньому шарі над усіма іншими елементами, а потім видалення його з верхнього шару, коли він «закривається». Я майже впевнений, що всі ми стикалися з ситуацією, коли ми відкриваємо модальний файл, але з будь-якої причини він не з’являється. Справа не в тому, що він не відкрився належним чином, а в тому, що його не видно на нижньому рівні контексту стекування. Це залишає вас задатися питанням "як так?" оскільки ви встановили:

.overlay { положення: фіксоване; /* створює контекст стекування */ z-індекс: 1; /* розміщує елемент на шарі над усім іншим */ вставка: 0; ширина: 100%; висота: 100vh; перелив: прихований; колір фону: #00000080; }

Це виглядає правильно, але якщо батьківський елемент, що містить модальний тригер, є дочірнім елементом в іншому батьківському елементі, який також має значення z-індекс: 1, це технічно розміщує модальний елемент у підрівні, закритому основною папкою. Давайте розглянемо цей конкретний сценарій і пару інших поширених пасток у контексті стекування. Я думаю, ви побачите не лише те, як легко ненавмисно створювати контексти стекування, але й те, як невдало ними керувати. Крім того, спосіб повернення до керованого стану залежить від ситуації. Сценарій 1: Модаль у пастці

Ви можете відразу побачити свій модальний блок у низькорівневому шарі та ідентифікувати батьківський. Розширення браузера Розумні розробники створили розширення, щоб допомогти. Такі інструменти, як це розширення Chrome «Інспектор стекуючого контексту CSS», додають до ваших DevTools додаткову вкладку z-індексу, щоб показувати інформацію про елементи, які створюють контекст стекування.

Розширення IDE Ви навіть можете виявити проблеми під час розробки за допомогою такого розширення для VS Code, яке висвітлює потенційні проблеми контексту стекування безпосередньо у вашому редакторі.

Розбирання та відновлення контролю Після того як ми визначили першопричину, наступним кроком буде боротися з нею. Є кілька підходів, які ви можете використати для вирішення цієї проблеми, і я перелічу їх по порядку. Ви можете вибрати будь-кого на будь-якому рівні; ніхто не може скаржитися чи перешкоджати іншому. Змініть структуру HTML Це вважається оптимальним виправленням. Щоб ви зіткнулися з проблемою контексту стекування, ви повинні розмістити деякі елементи в смішних позиціях у своєму HTML. Реструктуризація сторінки допоможе вам змінити форму DOM і усунути проблему контексту стекування. Знайдіть проблемний елемент і видаліть його з елемента захоплення в розмітці HTML. Наприклад, ми можемо вирішити перший сценарій, «The Trapped Modal», перемістивши .modal-container із заголовка та помістивши його в елемент .

Заголовок

Основний вміст

Цей вміст має z-індекс 2 і все одно не охоплює модаль.

Коли ви натискаєте кнопку «Відкрити модаль», модаль розташовується перед усім іншим, як і має бути. Див. Сценарій Pen 1: The Trapped Modal (Solution) [forked] by Shoyombo Gabriel Ayomide. НалаштуйтеБатьківський контекст стекування в CSS Що робити, якщо елемент не можна перемістити, не порушивши макета? Краще вирішити проблему: батько встановлює контекст. Знайдіть властивість (або властивості) CSS, відповідальну за запуск контексту, і видаліть її. Якщо він має певну мету і не може бути видалений, дайте батьківському індексу більше значення z-індексу, ніж його однорідним елементам, щоб підняти весь контейнер. З вищим значенням z-індексу батьківський контейнер переміщується вгору, а його дочірні елементи виглядають ближче до користувача. Виходячи з того, що ми дізналися зі сценарію «The Submerged Dropdown», ми не можемо перемістити спадне меню з навігаційної панелі; це не мало б сенсу. Однак ми можемо збільшити значення z-індексу контейнера .navbar, щоб воно було більше, ніж значення z-індексу елемента .content. .navbar { фон: #333; /* z-індекс: 1; */ z-індекс: 3; положення: відносне; }

Завдяки цій зміні .dropdown-меню тепер з’являється перед вмістом без проблем. Дивіться Сценарій Pen 2: The Submerged Dropdown (Solution) [forked] by Shoyombo Gabriel Ayomide. Спробуйте портали, якщо використовуєте фреймворк У таких фреймворках, як React або Vue, портал — це функція, яка дозволяє відтворювати компонент поза його звичайною батьківською ієрархією в DOM. Портали схожі на пристрій для телепортації ваших компонентів. Вони дозволяють відтворювати HTML компонента будь-де в документі (зазвичай прямо в document.body), зберігаючи його логічно пов’язаним із вихідним батьківським компонентом для атрибутів, стану та подій. Це ідеально підходить для уникнення перехоплень контексту стекування, оскільки відтворений результат буквально з’являється за межами проблемного батьківського контейнера. ReactDOM.createPortal( , документ.тіло );

Це гарантує, що ваш спадний вміст не буде приховано за його батьківським, навіть якщо у батьківського є переповнення: прихований або нижчий z-індекс. У сценарії «Обрізана підказка», який ми розглядали раніше, я використав портал, щоб врятувати підказку від переповнення: прихований кліп, розмістивши його в тілі документа та розташувавши над тригером у контейнері. Див. Сценарій Pen 3: Обрізана підказка (Рішення) [форк] Шойомбо Габріеля Айоміде. Представляємо контекст стекування без побічних ефектів Усі підходи, описані в попередньому розділі, спрямовані на «вилучення» елементів із проблемних контекстів стекування, але є деякі ситуації, коли вам справді знадобиться або захочеться створити контекст стекування. Створити новий контекст стекування легко, але всі підходи мають побічний ефект. Тобто, за винятком використання ізоляції: isolate. При застосуванні до елемента контекст стекування дочірніх елементів цього елемента визначається відносно кожного дочірнього елемента та в цьому контексті, а не під впливом елементів поза ним. Класичним прикладом є присвоєння цьому елементу від’ємного значення, наприклад z-index: -1. Уявіть, що у вас є компонент .card. Ви хочете додати декоративну фігуру, яка буде розташована позаду тексту .card, але поверх фону картки. Без контексту стекування на картці z-index: -1 надсилає фігуру в нижню частину кореневого контексту стекування (усю сторінку). Це змусить його зникнути за білим фоном .card: Див. Pen Negative z-index (проблема) [розгалужена] Шойомбо Габріеля Айоміде. Щоб вирішити цю проблему, ми оголошуємо isolate: isolate на батьківській .card: Дивіться Pen Negative z-index (рішення) [форк] від Shoyombo Gabriel Ayomide. Тепер сам елемент .card стає контекстом стекування. Коли його дочірній елемент — декоративна форма, створена на псевдоелементі :before — має z-індекс: -1, він переходить до самого низу батьківського контексту стекування. Він ідеально розташовується позаду тексту та поверх фону листівки, як і задумано. Висновок Пам’ятайте: наступного разу, коли ваш z-індекс виходить з-під контролю, це буде захоплений контекст стекування. Список літератури

Контекст стекування (MDN) Z-індекс і контексти стекування (web.dev) «Як створити новий контекст стекування за допомогою властивості Isolation у CSS», Наталі Піна «Що за біса, z-індекс?», Джош Комо

Додаткова інформація про SmashingMag

«Керування Z-індексом CSS у великих проектах», Стівен Фрісон «Липкі заголовки та елементи повної висоти: хитра комбінація», Філіп Браунен «Керування Z-індексом у компонентному веб-додатку», Павло Померанцев «Властивість Z-індексу CSS: комплексний погляд», Луї Лазаріс

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free