DEV Community

Michael Di Prisco
Michael Di Prisco

Posted on

The unsolvable z-index auto-increment.

The idea.

If you wrote my previous series CSS Only: to the infinity and beyond you know I like to play with CSS to explore its limits, and today I woke up with a strange, but simple idea: Auto-incremental z-indexes.

The development is pretty simple and straightforward: Being able to have a container div with many .layer divs inside of it, each one with an incremental z-index, auto-calculated via CSS.

I did many tries and I'll try to explain them in a simple and quick way.

TL;DR: It doesn't work. Or, at least, I didn't find a way to.

Let's go!

The HTML

The HTML part is the easiest one as it's exactly the one explained above:

<div class="main">
  <div class="layer">
    1
  </div>
  <div class="layer">
    2
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

The CSS - Part 1

I wanted to use some modern CSS and went for Custom Properties aka CSS Variables.

.main {
  --z-index: 0;
}

.layer {
  z-index: var(--z-index);
}

.layer + .layer {
  --z-index: var(--z-index) + 1;
}
Enter fullscreen mode Exit fullscreen mode

As soon as I wrote that, I remembered you can't do calcs like that in CSS. So I went for the calc() function.

The CSS - Part 2

.main {
  --z-index: 0;
}

.layer {
  z-index: var(--z-index);
}

.layer + .layer {
  --z-index: calc(var(--z-index) + 1);
}
Enter fullscreen mode Exit fullscreen mode

Buuuuut, it doesn't work either.
You can't calc things like that in CSS, so I had to find another way.

Eureka!

Have you ever read about CSS Lists And Counters? I did in the past, but I've never used them as I never had a chance to, so, I though, "Maybe I could give it a try!"

The CSS - Part 3

Let's go full counters then!

.main {
  counter-reset: section;
}

.layer {
  z-index: counter(section);
}

.layer + .layer {
  counter-increment: section;
}
Enter fullscreen mode Exit fullscreen mode

I started with a counter-reset and then counter-incremented it at every subsequent selector.

But the CSS counter() function returns a <string> and the z-index property is looking for an <integer>, so well.. It doesn't work.

Conclusion

I guess my dream will stay a dream for a little as I don't know any other possible CSS-only solution for this.

That's why I'm asking you to think about it and let me know if you can find a way to achieve my goal.

Can we do it with the current CSS specs? Will we ever be able to?

Let's #discuss it in the comments.

Wanna give it a try? Here's a Codepen you can fork.

Top comments (4)

Collapse
 
hylander profile image
Hylan

I track all DIVs intended to be moved, and manually adjust the zIndex value via JS. Focusing a DIV decrements all other higher zIndexes by 1, and sets the focused DIV zIndex to the list size minus 1. 'mousedown' will focus the DIV, 'mousemove' implements moving ops, and 'mouseup' finishes the 'mousemove' or, lacking that, activates the appropriate element. It seems very zippy and stable.

Collapse
 
merri profile image
Vesa Piittinen

The layout elements are already autoincremental in z-index. z-index is an escape hatch when you have no other means to fix paint priority.

Collapse
 
cadienvan profile image
Michael Di Prisco

I know, it was just a test to try to deliberately separate layers in your layout. It was just a cool experiment :)