Isolate, don't raise z-index
isolation: isolate keeps a card's z-index from fighting the page.
Josh W. Comeaujoshwcomeau.comWhen we apply this declaration to an element, it does precisely 1 thing: it creates a new stacking context.
Josh W. Comeaujoshwcomeau.comMore and more, I'm starting to believe that z-index is an escape hatch , similar to !important .
1 · A badge over the menu
Open the menu, then raise z-index values and watch who wins.
Badge leaks outBad
.card { position: relative }Card isolatesGood
.card { isolation: isolate }.card { isolation: isolate; } /* badge's z-index: 2 stays inside the card */
.badge { position: absolute; z-index: 2; }
.header { position: relative; z-index: 1; } /* no 999 needed */
Why it matters, pros and cons
Why it matters
z-index only ranks siblings in one stacking context. A new context stops a badge's 2 from beating the header's 1.
Pros
- One declaration on the component replaces every z-index: 999 on the page.
- Inner layers keep their own small numbers and stay in order inside the card.
- Nothing leaks, so a new teammate's z-index: 9999 can't break your component.
Cons
- Anything that must escape the card, like a tooltip, gets clipped to its layer.
- Other properties, like transform and opacity, also create contexts by accident.
- You have to know which ancestor to isolate, and that takes a bit of DevTools.