Jordan Scales explores the computer science concept of topological sorting, and what it might look like if applied to the concept of z-index
in CSS. So, you don’t express what the z-index
should be directly; instead, you say exactly what other element you want to be on top of.
I think it’s more of a proof-of-concept, but it’s fun to look at anyway:
const resolver = new ZIndexResolver(); // A nav with dropdowns
resolver.above(".nav", "main");
resolver.above(".dropdown", ".nav");
resolver.above(".submenu", ".dropdown"); // Tooltips in the document
resolver.above(".tooltip", "main"); // Modals should go above everything
resolver.above(".modal", ".nav");
resolver.above(".modal", ".submenu");
resolver.above(".modal", ".tooltip"); console.log(resolver.resolve());
That produces an array in the right order:
[ '.modal', '.tooltip', '.submenu', '.dropdown', '.nav', 'main' ]
…which you can skoosh into CSS:
main { z-index: 0; }
.nav { z-index: 1; }
.dropdown { z-index: 2; }
.submenu { z-index: 3; }
.tooltip { z-index: 4; }
.modal { z-index: 5; }
The problem I see here is that it doesn’t account for stacking contexts. And if there is a bug with z-index
, it’s always the stacking context. There is no possible z-index
value that will raise up an item in a lower stacking order above any other items that are in a higher stacking context. So, to make something like this work effectively, I think it would have to know what (possibly nested) stacking context each item is in, then either attempt to jostle the stacking context themselves, or warn you that what you are asking for won’t work.