4 причини, через які ваш z-індекс не працює (і як це виправити) - Coder Coder

Ця публікація була спочатку опублікована на Coder-Coder.com.

Z-index - це властивість CSS, яка дозволяє розміщувати елементи шарами один над одним. Це надзвичайно корисний і, чесно кажучи, дуже важливий інструмент, щоб знати, як використовувати в CSS.

На жаль, z-індекс - це одна з тих властивостей, яка не завжди поводиться інтуїтивно. Спочатку здається простим - більше число z-індексу означає, що елемент буде поверх елементів з нижчими числами z-індексу. Але є деякі додаткові правила, які ускладнюють ситуацію. І ви не завжди можете виправити ситуацію, встановивши z-індекс на 999999! ?

У цій статті буде детально описано чотири найпоширеніші причини того, що z-index не працює для вас, а також те, як ви можете це виправити.

Ми розглянемо деякі фактичні приклади коду та їх вирішення. Прочитавши цю статтю, ви зможете зрозуміти та уникнути тих загальних підводних каменів z-index!

Давайте перевіримо першу причину:

1. Елементи в тому ж контексті укладання відображатимуться в порядку зовнішнього вигляду, а останні елементи будуть поверх попередніх елементів.

У нашому першому прикладі ми маємо порівняно простий макет, який включає 3 основні елементи:

  • Образ кота
  • Білий блок з текстом
  • Ще одне зображення того ж кота

Ось розмітка HTML для цього:

 Meow meow meow... 

У цьому макеті ми ідеально хочемо, щоб білий блок тексту знаходився поверх обох котів.

Щоб спробувати досягти цього, ми додали деякі негативні поля до CSS для обох зображень котів, щоб вони трохи перекривали білий блок:

.cat-top { margin-bottom: -110px; } .cat-bottom { float: right; margin-top: -120px; }

Однак це виглядає так:

Перший кіт справді розміщений під білим блоком вмісту, як ми хочемо. Але друге зображення кота розташоване вгорі блоку!

Чому це відбувається?

Причиною такої поведінки є природний порядок укладання на веб-сторінці. Ці рекомендації в основному визначають, які елементи будуть зверху, а які знизу.

Навіть якщо елементи не мають набору z-індексу, існує рима і причина, з яких вони будуть зверху.

У нашому випадку жоден з елементів не має значення z-індексу. Тож порядок їх укладання визначається порядком їх появи. Згідно з цим правилом, елементи, які приходять пізніше у розмітці, будуть знаходитись над елементами, які стоять перед ними.

(Докладніші вказівки щодо порядку укладання ви можете прочитати в мережі розробників Mozilla тут.)

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

Гаразд, порядок укладання - це добре, але як нам виправити CSS, щоб другий кіт знаходився під білим блоком?

Давайте розглянемо другу причину:

2. Елемент не має встановленого положення

Одне з інших вказівок, яке визначає порядок укладання, полягає в тому, якщо елемент має встановлене положення чи ні.

Щоб встановити позицію для елемента, додайте positionвластивість CSS до будь-чого іншого, крім static, наприклад, relativeабо absolute. (Ви можете прочитати більше про це в цій статті, яку я написав.)

Відповідно до цього правила, позиціоновані елементи відображатимуться поверх непозиціонованих елементів.

Тож, встановивши білий блок як такий position: relative, і залишивши два елементи кота нерозміщеними, білий блок буде розміщений у верхній частині котів у порядку укладання.

Ось як це буде виглядати - ви також можете пограти з Codepen вище.

Вуху!

Тепер наступне, що ми хочемо зробити, - це повернути нижню кішку догори дном, використовуючи transformвластивість. Таким чином, обидві кішки будуть знаходитися під білим блоком, і лише голови стирчать.

Але це може спричинити більш z-indexпов'язану плутанину. Ми розглянемо проблему та рішення у наступній частині.

3. Встановлення деяких властивостей CSS, таких як непрозорість або перетворення, помістить елемент у новий контекст стекування.

Як ми щойно згадали, ми хочемо перевернути нижнього кота догори дном. Для цього ми додамо 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встановлено! (W3.org має деяку інформативну, але досить щільну документацію про те, як це працює з opacityвластивістю)

Пам'ятайте, ми ніколи не додавали z-indexзначення лише для білого блоку position: relative. Цього було достатньо, щоб розташувати білий блок на верхніх частинах нерозташованих котів.

But since the .bottom-cat element is acting as though it is relatively positioned with z-index: 0, transforming it has positioned it on top of the white block.

The solution to this is to set position: relative and explicitly set z-index on at least the white block. You could go one step further and set position: relative and a lower z-index on the cat elements, just to be extra safe.

.content__block { position: relative; z-index: 2; } .cat-top, .cat-bottom { position: relative; z-index: 1; }

In my opinion, doing this will solve most, if not all of the more basic z-index issues.

Now, let’s move on to our last reason that your z-index isn't working. This one is a bit more complex, because it involves parent and child elements.

4. The element is in a lower stacking context due to its parent’s z-index level

Let’s check out our code example for this:

Here’s what we have: a simple webpage with regular content, and a pink side tab that says “Send Feedback” that is positioned on top of the content.

Then, when you click on the photo of the cat, a modal window with a transparent gray background overlay opens up.

However, even when the modal window is open, the side tab is still on top of the gray overlay. We want the overlay to be displayed over everything, including the side tab.

Let’s take a look at the CSS for the elements in question:

.content { position: relative; z-index: 1; } .modal { position: fixed; z-index: 100; } .side-tab { position: fixed; z-index: 5; }

All the elements have their position set, and the side tab has a z-index of 5, which positions it on top of the content element, which is at z-index: 1.

Then, the modal has z-index: 100 which should put it on top of the side tab at z-index: 5. But instead, the modal overlay is underneath the side tab.

Why is this happening?

Previously, we addressed some factors that go into the stacking context, such as if the element has its position set, as well as its order in the markup.

But yet another aspect of stacking context is that a child element is limited to the stacking context of its parent.

Let’s take a closer look at the three elements in question.

Here’s the markup we have:

Looking at the markup, we can see that the content and side tab elements are siblings. That is, they exist at the same level in the markup (this is different from z-index level). And the modal is a child element of the content element.

Because the modal is inside the content element, its z-index of 100 only has an effect inside its parent, the content element. For example, if there were other child elements that were siblings to the modal, their z-index values would put them on top of or underneath each other.

But the z-index value of those child elements doesn't mean anything outside the parent, because the parent content element has its z-index set to 1.

So its children, including the modal, can’t break out of that z-index level.

(You can remember it with this slightly depressing metaphor: a child can be limited by its parents, and can’t break free of them.)

There are a couple of solutions to this problem:

Solution: Move the modal outside of the content parent, and into the main stacking context of the page.

The corrected markup would then look like this:

Now, the modal element is a sibling element to the two others. This puts all three elements in the same stacking context as them, so each of their z-index levels will now affect one another.

In this new stacking context, the elements will display in the following order, from top to bottom:

  • modal (z-index: 100)
  • side tab (z-index: 5)
  • content (z-index: 1)

Alternative Solution: Remove positioning from the content, so it won’t limit the modal’s z-index.

If you don’t want to or can’t change the markup, you can fix this problem by removing the position setting from the content element:

.content { // No position set } .modal { position: absolute; z-index: 100; } .side-tab { position: absolute; z-index: 5; }

Since the content element is now unpositioned, it will no longer limit the modal’s z-index value. So the open modal will be positioned on top of the side tab element, due to its higher z-index of 100.

While this does work, I personally would go for the first solution.

Because if for some reason in the future you have to position the content element, it will again limit the modal’s order in the stacking context.

In Summary

I hope that you’ve found this tutorial helpful! To sum up, most issues with z-index can be solved by following these two guidelines:

  1. Check that the elements have their position set and z-index numbers in the correct order.
  2. Make sure that you don’t have parent elements limiting the z-index level of their children.

Want more?

I'm creating a course in responsive design! Sign up here to get emailed when it's published.

I write web development tutorials on my blog coder-coder.com, post mini-tips on Instagram and coding tutorials on YouTube.