Skip to main content

Search rules

Search all UI Guides rules by name, category, or source

layoutWeb Platform

z-index Only Works Inside Its Stacking Context

SHOULD

SHOULD: z-index is compared only within a stacking context, not globally. transform, opacity<1, filter, will-change, position:fixed/sticky, isolation, and flex/grid children with z-index all create one — trapping descendants no matter how high their z-index. Do not fix overlap with a bigger number; remove the accidental context or lift the overlay out of the trapping ancestor.

A parent with transform, opacity, or filter makes a new stacking context that traps its children's z-index — the fix is not a bigger number

/* z-index:9999 inside a transformed parent can't beat a later sibling. */
.card { transform: none; } /* or move the overlay to a portal / higher context */

Bad

Good

Why it matters

The recurring bug: a dropdown set to `z-index: 9999` still renders under the next section and nobody can explain why the number does not win. z-index is not global — it is compared only among siblings inside the same STACKING CONTEXT, and a long list of ordinary CSS silently creates one: `transform`, `opacity` below 1, `filter`, `backdrop-filter`, `will-change`, `position: fixed`/`sticky`, `isolation: isolate`, and being a flex/grid child that has a z-index.

Once a parent forms a context, its descendants' z-index are resolved only against each other and the whole subtree is clamped to the parent's own place in the stack — so a `9999` inside a `transform`ed card can never climb above a sibling card that comes later in the DOM. Raising the number is the wrong fix and starts the arms race that layout-ibelick-z-index-scale exists to prevent.

The right fixes: remove the accidental context (drop the stray `transform`/`opacity`), or lift the overlay out of the trapping ancestor entirely — the same escape move layout-impeccable-clipped-overflow prescribes for a popover trapped in an `overflow` ancestor.

Built by Gleb Stroganov, design engineer at Evil Martians.

The rules come from other people's skills and guidelines — Vercel, Rauno Freiberg, @Ibelick, impeccable, Emil Kowalski, Tailwind, RAMS — each one credited on the Sources page. The work here is extraction and wiring: every rule is pulled into one corpus, given a good and a bad example you can operate, a MUST/SHOULD/NEVER rule an agent can paste, and a link back to where it came from.