4 reasons your z-index isn't working (and how to fix it) - Coder Coder (2024)

What is z-index? Z-index is a CSS property that allows you to position HTML elements in layers on top of one another. It seems simple at first, but it’s deceptively simple.

There are some weird, non-intuitive rules that can make it not behave the way you want– even if you set z-index to 999999!

This article will explain in detail four of the most common reasons that z-index isn’t working for you. You’ll learn how to use CSS to bring elements to the front, or back behind other elements.

1. Elements in the same stacking context will display in order of appearance, with latter elements on top of former elements.

In our first example, we have a relatively simple layout that includes 3 main elements:

  • An image of a cat
  • A white block with text
  • Another image of the same cat

Here’s the HTML markup for that:

<div class="cat-top"></div> <div class="content__block"> Meow meow meow...</div> <div class="cat-bottom"></div>

In this layout, we ideally want the white block of text to be on top of both cats.

To try to achieve this, we’ve added some negative margins to the CSS for both cat images, so that they overlap the white block a bit:

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

However, it looks like this:

See the Pen Z-index: #1: set position, #2: natural stacking order, #3: CSS properties by Jessica (@thecodercoder) on CodePen.

The first cat is indeed positioned underneath the white content block, just like we want. But the second cat image is positioned on top of the block!

Why is this happening?

The reason for this behavior is due to thenatural stacking orderon the webpage. These guidelines basically determine which elements will be on top and which will be on the bottom.

Even if elements don’t have their z-index set, there is a rhyme and reason to which ones will be on top.

In our case, none of the elements have a z-index value. So their stacking order is determined by their order of appearance. According to this rule, elements that come later in the markup will be on top of elements that come before them.

(You can read more of the stacking order guidelines at Mozilla Developer Networkhere.)

In our example with the cats and the white block, they are obeying this rule. That’s why the first cat is underneath the white block element, and the white block is underneath the second cat.

Ok, stacking order is all well and good, but how do we fix the CSS so the second cat is underneath the white block?

Let’s look at the second reason:

2. The element doesn’t have its position set

One of the other guidelines that determine stacking order is if an element has its position set or not.

To set position for an element, add the CSSposition property to anything other thanstatic, likerelativeorabsolute. (You can read more about it in this article that I wrote.)

According to this rule, positioned elements will display on top of unpositioned elements.

So setting the white block to beposition: relative, and leaving the two cat elements unpositioned will put the white block on the top of the cats in the stacking order.

This is how it will look– you can also play around with the Codepen above.

4 reasons your z-index isn't working (and how to fix it) - Coder Coder (1)

Woohoo!

Now, the next thing we want to do is rotate the bottom cat upside down, using the transformproperty. That way, both cats will be underneath the white block, with only their heads sticking out.

But doing so can cause morez-index-related confusion. We’ll address the problem and the solution in the next part.

3. Setting some CSS properties like opacity or transform will put the element in a new stacking context.

As we just mentioned, we want to turn the bottom cat upside down. To accomplish this, we’ll addtransform: rotate(180deg).

.cat-bottom { float: right; margin-top: -120px; transform: rotate(180deg);}

But this causes the bottom cat to be displayed on top of the white block again!

4 reasons your z-index isn't working (and how to fix it) - Coder Coder (2)

What the heck is going on here??

You may not run into this issue often, but another aspect of stacking order is that some CSS properties liketransformoropacitywill put the element into its own, newstacking context.

What this means is that adding thetransformto the.cat-bottomelement makes it behave as if it had az-indexof 0. Even though it doesn’t have itspositionorz-index set at all! (W3.org has some informative but rather dense documentationon how this works with theopacityproperty)

Remember, we never added az-indexvalue to the white block, onlyposition: relative. This was enough to position the white block on top of the unpositioned cats.

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

The solution to this is to setposition: relativeand explicitly setz-indexon at least the white block. You could go one step further and setposition: relativeand a lowerz-indexon 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 yourz-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:

See the Pen Z-index: #4 different stacking contexts by Jessica (@thecodercoder) on CodePen.

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 az-indexof 5, which positions it on top of the content element, which is atz-index: 1.

Then, the modal hasz-index: 100whichshouldput it on top of the side tab atz-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:

<section class="content"> <div class="modal"></div></section><div class="side-tab"></div>

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, itsz-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-indexvalues would put them on top of or underneath each other.

But thez-indexvalue of those child elements doesn’t mean anything outside the parent, because the parent content element has itsz-indexset to 1.

So its children, including the modal, can’t break out of thatz-indexlevel.

(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:

<section class="content"></section><div class="modal"></div><div class="side-tab"></div>

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’sz-indexvalue. So the open modal will be positioned on top of the side tab element, due to its higherz-indexof 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 thez-indexlevel of their children.

Resources:

4 reasons your z-index isn't working (and how to fix it) - Coder Coder (2024)
Top Articles
Latest Posts
Article information

Author: Saturnina Altenwerth DVM

Last Updated:

Views: 5452

Rating: 4.3 / 5 (64 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Saturnina Altenwerth DVM

Birthday: 1992-08-21

Address: Apt. 237 662 Haag Mills, East Verenaport, MO 57071-5493

Phone: +331850833384

Job: District Real-Estate Architect

Hobby: Skateboarding, Taxidermy, Air sports, Painting, Knife making, Letterboxing, Inline skating

Introduction: My name is Saturnina Altenwerth DVM, I am a witty, perfect, combative, beautiful, determined, fancy, determined person who loves writing and wants to share my knowledge and understanding with you.