design token

Layers & Opacity

Semantic z-index layers for page-level stacking, and the few opacities reserved for non-text treatments.

Layers (z-index)

Things that must stack across the whole page use a semantic zIndex token rather than a hand-picked number. The layers go from bottom to top, 100 apart, so an app can put its own layer between two of them.

tokens · zIndex
tokenvaluedescription
hide-1—
base0—
raised1—
dropdown1000—
sticky1100—
banner1200—
overlay1300—
modal1400—
popover1500—
toast1700—
tooltip1800—
max2147483647—
// A full-screen overlay above the Topbar, below dialogs, popovers and toasts
<div className={css({ position: "fixed", inset: "0", zIndex: "overlay" })} />

// Your own layer between two tokens
<header className={css({ zIndex: "calc(token(zIndex.sticky) + 1)" })} />

The browser top layer

A <dialog> opened with showModal() (a modal Dialog or Drawer, the ToastCenter drawer) and an element shown with the popover attribute (Tooltip) render in the browser top layer. The top layer paints above every z-index, whatever its value, and orders its elements by when they opened. These tokens can’t order those elements. The modal, popover and tooltip values apply only where an element stays out of the top layer: non-modal dialogs, popovers and menus opened with <dialog>.show(), and browsers without the Popover API. To get an element above a modal dialog, open it in the top layer too (or inside the dialog). A bigger z-index won’t do it.

Local stacking

Stacking inside a single component, like a hit-target input over its label or a selected node over its siblings, keeps small literal values (0–20). Those values only compete inside that component’s own stacking context, so they never need a page layer. A preset test fails if a recipe uses a raw global-sized number.

Opacity

Opacity tokens cover non-text treatments only:

tokens · opacity
tokenvaluedescription
disabled0.6—
subtle0.5—
css({ _disabled: { opacity: "token(opacity.disabled)" } });

Don’t use opacity to make readable text or a meaningful icon look secondary. Opacity blends the element into whatever is behind it, so the contrast becomes unpredictable. On coloured or dark surfaces it often drops below WCAG. Use the solved *.text.muted tokens instead (neutral.text.muted, or panel.text.muted on coloured surfaces). Backdrops and scrims tint with a colour alpha (neutral.surface.ground/60) rather than element opacity.