Topological Sort Reimagines CSS z-index

Jordan Scales has built a proof-of-concept that applies topological sorting to CSS z-index. Instead of assigning explicit stacking values, you declare which element should sit above which other element.

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 generates an ordered array, which then gets converted into CSS:

[ '.modal', '.tooltip', '.submenu', '.dropdown', '.nav', 'main' ]
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 approach isn't without its limits. It sidesteps stacking contexts entirely, and as CSS-Tricks notes, stacking context bugs are pervasive. No z-index value can elevate an element from a lower stacking context above one in a higher context. For this to work in practice, the system would need to track each element's possibly nested stacking context, then either reorder the contexts themselves or flag when the requested order is impossible.

Direct Link →