Z-index
Z-index utilities provide a semantic scale for controlling stacking order. Use the custom properties or utility classes to keep z-index values consistent and predictable across your application.
Tokens
Section titled “Tokens”| Token | Value | Purpose |
|---|---|---|
--z-behind | -1 | Place an element behind its siblings |
--z-base | 0 | Explicit stacking reset |
--z-dropdown | 1000 | Dropdown menus |
--z-sticky | 2000 | Sticky headers, navigation bars |
--z-overlay | 3000 | Backdrops, overlays, modals |
--z-toast | 4000 | Toast and snackbar notifications |
--z-tooltip | 5000 | Tooltips and popovers |
Utility classes
Section titled “Utility classes”Each token has a matching utility class that sets z-index to the token value.
| Class | Sets |
|---|---|
.z-behind | z-index: var(--z-behind) |
.z-base | z-index: var(--z-base) |
.z-dropdown | z-index: var(--z-dropdown) |
.z-sticky | z-index: var(--z-sticky) |
.z-overlay | z-index: var(--z-overlay) |
.z-toast | z-index: var(--z-toast) |
.z-tooltip | z-index: var(--z-tooltip) |
The classes only set z-index — compose them with position utilities like .p-fixed or .p-absolute as needed.
<!-- Sticky header --><header class="z-sticky" style="position: sticky; top: 0;">…</header>
<!-- Custom overlay without <dialog> --><div class="tng-backdrop"></div><div class="p-fixed at-center z-overlay">…</div>Components with built-in z-index
Section titled “Components with built-in z-index”Several components ship with a default z-index so they stack correctly out of the box. Utility classes can still override these values because the utilities layer has higher specificity in the cascade.
| Component | Default z-index |
|---|---|
.tng-backdrop | var(--z-overlay) |
.tng-dropdown | var(--z-dropdown) |
.tng-modal | var(--z-overlay) |
.tng-popover | var(--z-overlay) |
When using .tng-popover as a tooltip, add the .z-tooltip utility class to ensure it stacks above other overlays.
Stacking contexts
Section titled “Stacking contexts”A stacking context is a self-contained layer in which child elements are stacked relative to each other, not to elements outside the context. Understanding stacking contexts is essential for working with z-index.
What creates a stacking context?
Section titled “What creates a stacking context?”Any of these properties on an element creates a new stacking context:
position: relative | absolute | fixedcombined with az-indexvalue other thanautoisolation: isolateopacityless than1transform,filter,backdrop-filter,perspectivewill-changetargeting one of the above propertiescontain: layout | paint
Why it matters
Section titled “Why it matters”A z-index: 9999 inside one stacking context cannot escape and overlap elements in a sibling stacking context with a higher or equal stacking level. This is why arbitrarily large z-index values don’t solve layering problems — they only work within their own context.
root stacking context├── header (z-index: 2000) ← its own stacking context│ └── dropdown (z-index: 1000) ← stacks within header, not the page└── main (z-index: 0) └── tooltip (z-index: 5000) ← stacks within main, not the pageIn this example the tooltip at 5000 still renders below the header at 2000, because each is confined to its parent’s stacking context.
The design system root
Section titled “The design system root”.tng-root applies isolation: isolate, creating a single top-level stacking context for the entire design system. This prevents internal z-index values from leaking into the host page and vice versa.
The top layer
Section titled “The top layer”The browser’s top layer is separate from the z-index stacking model entirely. Elements promoted to the top layer — via <dialog>.showModal() or the Popover API — render above everything regardless of z-index. Prefer these native APIs for modals, popovers, and tooltips whenever possible.
Best practices
Section titled “Best practices”- Use the tokens — avoid hard-coded z-index numbers. The scale gives every layer a clear semantic name and consistent spacing.
- Prefer the top layer — use
<dialog>and[popover]for overlay patterns. They bypass z-index complexity entirely. - Keep stacking contexts small — the fewer nested contexts you create, the easier z-index is to reason about.
- Don’t inflate values — if
z-index: 9999seems necessary, the real fix is usually restructuring the stacking context hierarchy.