Managing z-index without loosing your hair

I’ve run into issues time and time again managing z-index. Sure, most of the time, z-index related issues are far from complex.

However, I’ve come to a passionate dislike of magic values and numbers. What is 58 or 3000 after all? It’s an arbitrary number. Wouldn’t it be a lot nicer to have layers in CSS, just like in Photoshop or Illustrator ?

And sure enough, a quick search revealed multiple articles around z-index management.

CSS Layers instead of Z-Index

After years of using Sass daily, I’ve switched over to Stylus (that probably deserves an article of it’s own), and sure enough – a quick search search revealed an already made Stylus mixin in a Github gist.

I’m using a slightly modified version of that.


Configure the layers.

The configuration file contains all the layers and their z-index. I’m not using dots or hashes in names, so I can avoid adding quotes as well. This makes it just a little bit tidier for my taste.


The z-index manager mixin

I’ve modified the mixin in a few ways:

  1. I’m calling it layer. Easier to type than z_index, and it makes sense to me.
  2. I’ve added unused_z_layers, which is going to help with debugging ( see below )
  3. I’ve also added adjust option to the mixin.



The adjust option comes in really handy when dealing with local changes, without having to create a new layer for absolutely everything.

For example, if you have a layer for the menu, and you want to place a second div just under the menu, instead of having to create Menu: 500, Thing_Under_Menu: 490, I just use layer(Menu, -10).

So the usage looks something like this:

The Debug

Having a lot of  layers sometimes results in unused layers that are defined. This helps me keep track of that. In case

Stylus will already throw an error if I try to use layer(Mooooo) if Moooo doesn’t exist. That’s good.

However, what about the inverse? When Moooo is defined, but is unused? That’s where the debug comes in:

That’s going to throw a console warning when an unused layer is found.

I always include this after everything else, and on each compile it’s going to check for unused layers.

That’s it.

It’s a really simple approach, but has helped me keep my sanity when managing z-index in complex layouts.