CSS Z-Index Not Working! Send Help!
“Help!! CSS z-index not working!!! WTF!!!!”
Is this you (but without the cursing)? Don’t worry – I feel your pain. No matter how many pop-ups or fixed navigation systems I make, I always seem to forget the golden rule with the CSS z-index selector: they only work on specifically positioned elements.
Gets me every single time.
TL;DR: the most common cause for z-index not working is not explicitly declaring a CSS position value (i.e. position: relative, absolute, fixed or stick) on the element.
But if this hasn’t solved your z-index issue or just want to get a little more information about the CSS property, then let’s go a little deeper.
What’s a CSS z-index ?
I think the W3Schools definition of the z-index property sums it up the best:
“The z-index property specifies the stack order of an element.”
W3Schools –
https://www.w3schools.com/cssref/pr_pos_z-index.asp
This basically means you can use this CSS property to stack items on top of each other.
Another good way I like to look at it is: it’s basically the concept of layers for websites.
If you’ve ever used any kind of decent image editing/creation software like Photoshop, GIMP or maybe even Canva, then will no doubt have come across the concept of layers: the ability place images, shapes, text and anything else you might use on top of each other to create a stunning effect or display.
That’s what the CSS z-index property can do for your website design.
I’ve set the positioning, but my CSS z-index is not working!
Okay, you’ve read the section above and have a pretty good grip on the concept of the z-index property. You’ve also set a CSS position value on the element, but your CSS z-index is still not working.
What now?
Well, the next thing to investigate is the order of your HTML elements and how you’ve applied your z-index property to them.
Here’s a pretty good example how the CSS z-index works in a real-world scenario that might just fix your problem.
How does the CSS z-index Property Work?
The CSS z-index property works by assigning the property with a numeric value to any element.
The property can take large numeric values, as well as minus values should you want to position elements further back in the stack.
An element without a z-index specifically assigned to it, automatically inherits in the z-index of its parent and if the parent element doesn’t have a value set, then the default z-index is 0.
Here’s a visual demonstration of how it works:
See the Pen Help! My z-index isn't working! The Web Developer Guide by Kris Barton (@TheWebDeveloperGuide) on CodePen.
As you can see from the example above, we’re trying to position both layer 1 and layer 2 to the top left of the base layer. To do this we’re using the absolute positioning CSS property along with the z-index property.
As you can see, the orange layer (layer 2) is the layer on top. This is because we’ve set the z-index for the layer to 2. The blue layer (layer 1) is set to a z-index of 1, so layer 2 will be displayed on top.
But what if we set layer 2 to have a z-index of 1? You might think that layer 1 would take precedence and layer 2 would be hidden behind it, but that’s not what happens.
Because layer 2 uses absolute positioning and its HTML element is underneath layer 1, it takes precedence. This can be tested by moving layer 1’s element underneath layer 2.
Now, if we alter the layer 2 z-index to have a value of 2 rather than 1, layer 2 takes precedence again because we’ve explicitly stated it should be place higher than layer 1 in the CSS.
Very interesting stuff (at least, it is for geek like me).
What can you do with a z-index?
Okay, so there’s the basic functionality of the z-index CSS property so let’s take a look at some real world examples.
Let’s say we want to create a fixed navigation menu that hovers over the main page content. Then, whenever an option is clicked a sub menu is displayed over the top of the floating navigation menu and the main content. This is a scenario where the z-index CSS property becomes essential.
To do this, we’ll be using HTML5, CSS and Javascript – click here to jump to the codepen (a codepen embed can’t do this bad boy justice).
Z-Index: Get Your Layers Right!
As you can see from the code demo, I’m setting the z-index in 2 places:
- I’m setting the main navigation panel to have a z-index of 1.
- I’m setting the sub navigation panels to have a z-index of 2.
I want the layering of my elements to be the sub navigation links on the top, then the navigation and finally the content behind them. This could’ve been achieved a little easier than I’ve done it in this example, but I wanted to demonstrate the z-index element hierarchy in action.
I’ve included the HTML elements in this order:
- Sub navigation links.
- Navigation panel.
- Content.
Because I’ve added the sub navigation links first, I have to specifically assign them a higher z-index than the navigation panel. This is because if the second element has the same z-index, it will take precedence over the first and will overlap it.
In our example, it would mean the sub navigation links would be hidden behind the navigation panel.
Conversely, if I move the sub navigation below the navigation panel and changed its z-index to 1, then the sub navigation items would still overlap the navigation panel.
Pretty interesting stuff once you break it down and examine it. Feel free to fork my codepen and have a play around with the elements yourself.
Top Tip: Think About Your z-index Elements In Advance When Planning Your Website
When creating a website, you might find yourself with a number of different elements that will need to be layered and overlap on the same page, sometimes at the same time.
Start Planning
It’s worth planning in advance the order in which your z-index elements should take precedence. For example, should your popup box be able to overlap your navigation element? Or should it be the other way around.
I say this because a lot of developers will automatically set the z-index of an element to a high number (something like 999) and this okay because it’s definitely going to overlap the page with such a high value, but doesn’t take into account scenarios where you have two or more overlapping elements action and open at the same time.
Let me hammer home that point in meme form:
This might not ever be a scenario you need to worry about, but if you think it might be then it’s a good idea to come up with a more sensible z-index valuation system.
For example, you can always image the base layer of your website to have a z-index value of 0. Set the next value you’d like to overlap to have a z-index value of 1. If then you decide you need another element to overlap and it’s more important to the user to display it over the top of the previous overlapping element, then set it to 2 and so on.
This way, you can always guaranteed the right overlay will be displayed to the user.
Further Reading:
- https://www.w3schools.com/cssref/pr_pos_z-index.asp
- https://css-tricks.com/almanac/properties/z/z-index/
- https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
- https://webdesign.tutsplus.com/articles/what-you-may-not-know-about-the-z-index-property–webdesign-16892