A Detailed Look at the z-index CSS Property | Impressive Webs
Most CSS properties that a web developer deals with regularly are instantaneous in their application to elements on the page. For example, when you add the
background-color
or font-size
property to an element on your page, in most cases you will see the results immediately upon page refresh. But other CSS properties are not quite as “plug and play” as we would like.The
z-index
property is one example of the latter. I would venture to guess that z-index
is probably the CSS property that is more speedily abandoned than any other. Very often — when I previously didn’t understand z-index
— I would try to apply it to an element, hoping that the element would automatically “jump” to the top in the page’s stacking order. But that didn’t happen, so I would abandon that method and try some other way to solve the problem. Maybe you’ve had the same experience. Hopefully this article will clear up some misunderstandings regarding z-index
.
What Exactly Does It Do?
Basically, the z-index
property sets the stack order of an element. An element with greater stack order is always in front of another element with lower stack order. That over-simplified definition is exactly why beginning CSS developers often use z-index
incorrectly.The natural stacking order of a web page’s elements is decided by the order in which the elements appear in the page’s markup. Let’s provide a simple example that we can use to explain stacking order and how
z-index
can be used correctly (and incorrectly):- <div id="header">
- <p>This is the header</p>
- </div>
- <div id="article">
- <p>This is an article</p>
- </div>
- <div id="footer">
- <p>This is the footer.</p>
- </div>
Used When Elements Overlap One Another
In the above markup, we have three <div>
elements (header, article, and footer), one after another. Let’s say our page design required that the header overlapped the top portion of the article by 10 pixels, and the article element overlapped the footer element by 10 pixels.To see what I’m talking about, here is an example page with the markup above, and a background colour and 3px coloured border applied to each of the elements, so they can be easily distinguished from one another:
3 elements displayed normally
Now, let’s look at the same page, with a negative top margin applied to all three elements:
The same 3 elements with a negative top margin
Since we’ve applied the negative margin, we can now physically see the default stacking order in action. The “article” element overlaps the “header” element for the simple reason that the “article” appears after the “header” in the markup. And the same applies for the “footer”, and why it overlaps the “article”.
Resolving a Stacking Order Problem Without Z-Index
That example shows us that z-index
is not the only solution to a “stacking order” problem. Sometimes, you can resolve such an issue by simply changing the order of elements in your HTML, then positioning them accordingly.Attempting to Implement Z-Index
But let’s say we want those 3 elements to remain exactly where they are, and, for one reason or another, could not rearrange the elements in the markup. But we needed the overlap to be reversed: we want the header to overlap the article, and the article to overlap the footer. In our CSS, let’s apply z-index
values to the elements and see what happens:The CSS now looks like this:
- #header {
- background: blue;
- border: solid 3px pink;
- z-index: 3;
- }
- #article {
- background: red;
- border: solid 3px purple;
- z-index: 2;
- }
- #footer {
- background: green;
- border: solid 3px yellow;
- z-index: 1;
- }
3 overlapping elements with z-index
Do you notice a difference? If you do, then you need to look again. There are no visual differences between that example and the previous one. View the source of the page, and you’ll see that, even though we’ve added a z-index value to each element, and ensured that the values represent a reverse stack order, it didn’t have any effect. Why not?
Why Doesn’t It Work?
The previously-referenced W3schools page provides the explanation. It says: “Z-index only works on elements that have been positioned (eg position:absolute;).”In the example we’re using we can apply
position: relative
to our <div>
selector (which will apply to all 3 elements), and the stacking order specified by our z-index
values will instantly take effect. Here is the corrected demo page:3 elements with z-index applied properly
The overlap is now reversed, because the
z-index
values have been used properly.A Real-World, Practical Example
For an example of a good practical use for thez-index
property, here is a site I coded that uses transparent PNGs for the tabbed navigation. First, each tab is inside of a list item with negative margins to make the tabs overlap. Next, each tab is given a specific z-index
value, to reverse the natural stacking order. Then, a high z-index
is applied to the “selected” tab to ensure that the stacking order is graphically visible. The CSS for those tabs would look something like this:- ul#navigation li {
- position: relative;
- margin-left: -24px;
- }
- ul#navigation li.one {
- z-index: 5;
- }
- ul#navigation li.two {
- z-index: 4;
- }
- ul#navigation li.three {
- z-index: 3;
- }
- ul#navigation li.four {
- z-index: 2;
- }
- ul#navigation li.five {
- z-index: 1;
- }
- ul#navigation li.selected {
- z-index: 100;
- }
z-index
for that tab is given a higher value than the rest. In this example I’ve used 100
which ensures that the “selected” item will still be on top even if more tabs are added later.Some Notes to Keep in Mind About Z-Index
The z-index
property affects the position of an element on the Z-axis, which refers to how an item is stacked perpendicular to the display (instead of Y-Axis and X-Axis which refer to elements positioned parallel to the display). The higher the z-index
, the closer the element will be to the user.In IE6,
select
elements always appear on top of all page elements, no matter what the z-index
value of any element on the page. The best way to deal with select
elements appearing over top of drop down menus and other elements, is to actually make the select element invisible using display: none
via JavaScript when the overlapping element appears.The
z-index
property generally takes an integer as a value, but can also accept values of inherit
and auto
, although those values do not work properly in all browsers.In Internet Explorer versions 6 and 7, the stacking order of z-indexed elements is essentially “reset” for any elements that are contained by a positioned element, regardless of wether or not the container (or parent) has a
z-index
value set. In other words, an element with a z-index
value of 100
will appear underneath an element with a z-index
value of 1
if the former element is contained by a positioned parent, and the latter is not. This is an incorrrect implementation of the z-index
property that has evidently been corrected in IE8.To change the
z-index
value of an element with JavaScript, you would use the usual “camel casing minus the hyphen”, which is generally the norm for accessing CSS properties with JavaScript (e.g. myElement.style.zIndex = "100";
).Summary
In short, thez-index
property can be a powerful tool when used correctly, and can offer a very easy solution to many layout issues in graphically complex designs. As long as you remember that it only applies to elements that have a value set for the position
property, you will have no trouble using this interesting CSS property.