Have you always found the concept of z-index tricky? Did you give a z-index value of 99999 to a HTML element hoping it will be placed in front of everything in a page and it still didn’t work? If your answer is yes, you’ve come to the right place.
Below, I'll explain everything you need to know about z-index and have shared a nifty visualization tool that will help you change z-indexes of elements, re-order them using the drag and drop feature, and show you the changes in real-time.
Let’s quickly go over the basics. The default position value of any HTML element is static. Any element with the default value of static is a non-positioned element.
An element is a positioned element if it's position value is one of the following - relative, absolute, sticky, or fixed.
Every HTML element in a page can be either in front of (or) behind another element. This is known as the stacking order. For example - a pop-up is in front of the content behind it.
Let's see how that will look -
pop-up #1(position: absolute)
pop-up #2(position: absolute)
How do you determine the stacking order among positioned and non-positioned elements? This is where z-index helps us.
z-index takes care of the stacking order among the positioned elements themselves.
A z-index can be any positive (or) negative number including zero. It has no effect on a non-positioned element — position value of static.
Make note of two key points:
Here comes the fun part. Play with the div elements in the visualization tool below. Change the stacking order either by reordering the elements using the drag handle or by changing the z-index. Use the Reset link at any time to revert to the default configuration. The absolute positioned element won't change its position since it's anchored to its parent.
Let’s say you have the below HTML with positioned elements.
<body> <div id='div1' style='position:relative; z-index:10' /> <div id='div2' style='position:relative; z-index:5'> <div id='div3' style='position:absolute; z-index:100' /> </div> </body>
Will the div3 element be placed in front of the div1 element since it has the higher z-index? The answer is no. This may seem surprising at first but it all comes down to how the HTML elements are grouped.
Note that div1 is a single element and it forms a group of one. div2 forms a group with div2 as the parent and div3 as the child. A positioned element forms a stacking context. The positioned element can be either a single element (or) a parent element with child elements.
Here is the key part - a child’s z-index has no effect outside its group. div3’s z-index determines its position in the stacking order only among its siblings and has no effect outside its group. This is the reason setting even a large value like 99999 to div3 won't place it in front of div1.
Look at the code below. Here, div3 and div4 are siblings, and div3 will be placed in front of div4 since it has a higher z-index.
<body> <div id='div1' style='position:relative; z-index:10' /> <div id='div2' style='position:relative; z-index:5'> <div id='div3' style='position:absolute; z-index:100' /> <div id='div4' style='position:absolute; z-index:50' /> </div> </body>
The child elements in a stacking context are ordered as follows —
Play with the visualization tool below that has multiple elements and stacking contexts. Note that div4, div5, and div6 are children of div3.
Do only positioned elements create a stacking context? Not really. There are other scenarios in which an element can create one. An element that has opacity less than 1 (or) properties like transform, filter can create a stacking context. But, no worries. They behave the same way positioned elements do.
Have any more questions about z-indexes? Any other concepts you've always struggled with? Write me a tweet and I will get back to you.