How does z-index
actually work?
Does it function on elements with no specified position
?
Does it favor elements (i.e. make them on top) that have a specified position
?
Do the numbers have to be negative like this?
<div style='z-index:-2;'>below</div>
<div style='z-index:-1;'>less below</div>
<div style='z-index:0;'>on top</div>
? Or not? Would all positive numbers (in increasing value) end up with the last being on the top, the middle in the middle, and the first on the bottom?
I'm learning from W3Schools, and their lesson on this is so confusing! :(
Thanks a lot in advance!
The only exception to the rule that children are rendered above parents is when the children have a negative z-index. When a negative z-index is given, it places itself below a parent element.
This is just the link you are looking for! He really explains it well. Basically, all its is the higher the number, the higher up on the stack. So 1 is on top of 0 and -1 is under the z-index of 0, however they should be kept positive, as their is no reason to use negatives and is considered bad practice. The browser interprets in when it renders the page, like any other CSS or HTML code.
Hope this helps you!
The css property
z-index
only works on positioned elements, meaning elements must be position absolute, fixed or relative in order for thez-index
property to take effect.The higher the z-index the closer to the front it will appear. The values specified for the
z-index
property can be positive or negative. A positioned element with az-index
value of 4 will appear above a positioned element with az-index
value of 3.Both negative and positive integers are allowed.
The position must be set on the element.
Before I get into those details, though, let me explain
z-index
from the ground up.Every webpage is made up of what are called stacking contexts. You can think of these as, quite literally, a stack of elements. The z-index property determines the order of items in each stack, with higher z-index being placed further up.
All pages begin with a root stacking context, which builds from the root element (as you'd expect). But more stacking contexts can be created in a number of ways. One way is an absolutely positioned div; its children will be in a new stacking context.
The specs lists all of the instances that create a new stacking context. As others have stated, this includes explicitly positioned elements and will soon include elements that aren't completely opaque.
As I said before,
z-index
only takes effect if you explicitly set the position of the element. This means setting it to befixed
,absolute
, orrelative
. This is best shown through example, I think.In this example, we'd expect the blue div to be on top of the grey one given its z-index, right? But, as you can see, it's on the bottom. This is, of course, because we haven't set its position. Once we do that it displays as we'd expect. Again, you must set the position.
The specs also tell us that negative values are fine. With that said, you don't need to use negative values. It's perfectly fine to use positive integers, too. The default
z-index
value for an element is 0.For the record, w3schools is a notoriously unreliable source for learning. While it can be a quick and convenient resource, there are lots of gaps in their information, and at times even wrong information. I recommend you to use more reliable sources like the Mozilla Developer Network, and also the specs themselves.
Before I start explaining, let me note that
z-index
only has an affect if the element has rendered value ofposition:relative
,position:absolute
, orposition:fixed
(NOTstatic
) because each of these make it have its own stacking context. That means that values likeinitial
orinherit
may or may not work either depending on the situation.Also note that in this post I'll be using the format 1.1.1 to signify that I am selecting the first element's first child's first child. 2.1.1 would be the second element's first child's first child and so on.
I think
z-index
is best explained with an analogy using sub lists. Let's start with the simplest example:We can represent this in terms of a list like so:
Now by default the ones further down the list will render on top of the ones before it. So in this case 2 will be positioned on top of 1.
What z-index allows us to do is essentially reorder this list (within some bounds). The higher the z-index, the further down the list our element is.
I'll use inline CSS here to make showing it easy but you should definitely avoid inline CSS in production code.
This now changes our sub listing to look like this:
Great! Now the first element in our HTML will render on top of our second.
Where this gets more tricky is when we're dealing with children (nested) elements.
An easier way to think about this situation is to think that when an element starts being rendered it will render all children of the element before moving onto any siblings.
Also keep in mind that sub-lists cannot change levels, meaning they cannot be on the same level of their parent or their children elements.
That means that if we have the following:
Our rendering sub lists will look like the following:
Thus, we look our top level and see which one is at the bottom of the list. In this case, 2.0 is, so it will be on top of 1.0. Then we look and see if it has any sub lists (children). It doesn't, so we go to 1.0.
1.0 has a child, 1.1, which will be visually above 1.0 (just like it would be if we didn't give it a z-index), but it will still be below 2.0 because 1.0 is below 2.0.
Thus the z-index here doesn't help us out because 1.1 doesn't have any siblings.
Let's take a slightly more complex example:
What's the sub listing for this example?
I'll give it to you, but it's good to try and do by yourself.
Thus, in terms of what the order is visually from top to bottom, the order goes 2.1, 2.0, 1.3, 1.2. 1.1, 1.0.
That's not so bad, is it?
This behavior is true no matter how far deep or how many siblings are there.
The only exception to the rule that children are rendered above parents is when the children have a negative
z-index
. When a negative z-index is given, it places itself below a parent element.Thus if we have the following:
The sub list tree would look like this:
And the top to bottom layering would be 2.0, 1.0, 1.1.
A slightly more complex example:
List representation:
But you should avoid negative
z-index
es. If you think you need them it is likely that your HTML is structured improperly.That's about it! If you're still interested in learning more, reading the specs is always good.
Keep in mind that other properties, including but not limited to
opacity
,transform
, andwill-change
, create their own stacking context and may have an affect on the rendering order of elements.opacity
works similarly to z-index - a child can only be as opaque as its parent - but it can't have negative values.