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 по-горе.

Woohoo!

Следващото нещо, което искаме да направим, е да завъртим долната котка с главата надолу, като използваме 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.