Skip to main content

Z-Index

The z-index scale that keeps sticky bars, modals, drawers and tooltips predictable.

The z-index scale assigns every layer a purpose. Components reach for the token that matches their role — a dropdown never guesses z-index: 9999 to win a stacking war.

Components reach for the token that matches their role — a dropdown never guesses z-index: 9999 to win a stacking war.

The stacking ladder

0
--ep-z-base

Page content, static elements, default stacking.

30
--ep-z-dropdown

Dropdown menus, select popovers, autocomplete results.

40
--ep-z-sticky

Sticky headers, sticky sidebars, persistent toolbars.

50
--ep-z-overlay

Full-screen scrim backdrops, dimmed overlays.

60
--ep-z-modal

Modal dialogs, drawers, command palettes.

65
--ep-z-popover

Tooltips, contextual popovers, floating notifications. Body-portaled components (createPortal to document.body) MUST use this tier (65) — the dropdown tier (30) loses to sticky chrome (40) in the root stacking context.

70
--ep-z-toast

Toast notifications — sits above popovers so banners stay visible during context menus.

100
--ep-z-skip-link

Skip-link bypass for keyboard users — must sit above every layer.

Rules of the ladder

  • Never use arbitrary values like z-9999.
  • Skip-links bypass everything (100) — accessibility wins over stacking wars.
  • Toasts sit above popovers (70 vs 65) — banner notifications stay visible while context menus are open.
  • Modals sit above overlays (60 vs 50).
  • Sticky headers beat inline dropdowns (40 vs 30). A dropdown that opens inside a sticky header inherits the header's stacking context and renders correctly — UNLESS it is portaled, in which case it becomes a page-scope floating layer and loses to the sticky tier.
  • Portal pattern: any ReactDOM.createPortal(..., document.body) must use the popover tier (65). Inline dropdown tier (30) is only valid for non-portaled, in-place dropdowns anchored within their host's stacking context. (Source: foundation-integrity Phase 1, 2026-08-24 — Sign-out menu was clipped under the sticky dashboard topbar at tier 30.)

Stacking contexts

A z-index token only works inside the correct stacking context. Creating a new context (via transform, opacity, filter, or will-change) traps descendants — their z-index values are relative to the context, not the page.

What to avoid

  • Escalating z-index values to "win" stacking.
  • Using z-index: -1 to push content behind the page.
  • Setting z-index on elements that are the only child of their parent.
Design System v4.1.0 | ePassLive