A decade of Canvas at your command — powered by our custom AI engineStart Building →
Glossary

What Is z-index?

z-index is a CSS property that controls the vertical stacking order of overlapping HTML elements on a page. It only works on positioned elements (those with position set to relative, absolute, fixed, or sticky). Higher z-index values bring elements closer to the viewer, causing them to render on top of elements with lower values. Understanding z-index also requires understanding stacking contexts—isolated layers that scope how child z-index values are resolved.

How z-index works

By default, HTML elements stack in source order—later elements paint on top of earlier ones. The z-index property overrides this default within a stacking context. A positive z-index (e.g. z-index: 10) places the element above siblings with lower or no z-index values; a negative z-index (e.g. z-index: -1) pushes it behind its parent's background. The property accepts any integer value. Crucially, z-index only applies to elements whose position property is set to something other than static (the default). Setting z-index on a statically positioned element has no effect.

Stacking contexts explained

A stacking context is an isolated layering scope. Within a stacking context, child z-index values are resolved relative to each other—not to elements outside the context. A new stacking context is created whenever an element has: position + z-index (not auto), opacity less than 1, transform/filter/perspective set to any value, will-change targeting opacity or transform, or isolation: isolate. This means an element with z-index: 9999 inside a stacking context with z-index: 1 will still appear behind a sibling element with z-index: 2. Understanding this hierarchy is the key to debugging z-index issues.

Common z-index bugs and fixes

The most common z-index bug is 'z-index not working'—almost always caused by the element having position: static. Fix: add position: relative. The second most common issue is stacking context isolation: a child's high z-index is trapped inside a parent's low stacking context. Fix: restructure the DOM or adjust the parent's z-index. Third, z-index wars—teams escalating values to 99999—indicate missing architectural conventions. Fix: adopt a z-index scale (e.g. 1 = base, 100 = dropdowns, 200 = modals, 300 = tooltips, 400 = toasts). Finally, negative z-index can push elements behind their parent's background, making them invisible. Fix: apply position: relative to the parent without a z-index to avoid creating a new stacking context.

z-index in Bootstrap 5 and Canvas

Bootstrap 5 ships with a well-defined z-index scale documented in its Sass variables: $zindex-dropdown (1000), $zindex-sticky (1020), $zindex-fixed (1030), $zindex-offcanvas (1045), $zindex-modal-backdrop (1050), $zindex-modal (1055), $zindex-popover (1070), $zindex-tooltip (1080), and $zindex-toast (1090). Canvas Builder templates follow this same scale, ensuring that generated navbars, modals, dropdowns, and toasts layer correctly without conflicts. When customising Canvas-generated pages, stay within these documented tiers to avoid stacking issues.

z-index & Canvas Builder

Canvas Builder templates follow Bootstrap 5's z-index scale for all layered components—modals, dropdowns, sticky navbars, and toasts stack correctly out of the box. Custom sections use conservative z-index values to avoid conflicts with framework components.

Try Canvas Builder →

Frequently Asked Questions

Why is my z-index not working?
The most common reason is that the element has position: static (the default). z-index only applies to positioned elements—add position: relative, absolute, fixed, or sticky. If the element is already positioned, the issue is likely a stacking context: a parent element is creating an isolated layer (via opacity, transform, or its own z-index), and your element's z-index is being resolved within that confined scope rather than the page-level scope.
What is the maximum z-index value?
The CSS specification defines z-index as an integer, and browsers typically support values up to 2,147,483,647 (the maximum 32-bit signed integer). However, using extremely high values like 999999 is a code smell. Instead, adopt a layered scale—for example, 1 for base content, 100 for dropdowns, 200 for fixed headers, 300 for modals, 400 for tooltips—so the codebase stays manageable.
Does z-index work with flexbox and grid layouts?
Yes. Flex items and grid items are positioned in a flex/grid formatting context, and z-index works on them even without explicitly setting position. This is a special rule in the CSS spec: flex and grid children accept z-index regardless of their position value. This makes layering overlapping grid cells or flex items straightforward.
How does Bootstrap 5 handle z-index for components?
Bootstrap 5 defines a tiered z-index scale in its Sass variables: dropdowns at 1000, sticky elements at 1020, fixed navbars at 1030, offcanvas at 1045, modal backdrops at 1050, modals at 1055, popovers at 1070, tooltips at 1080, and toasts at 1090. This ensures components layer correctly when multiple are visible. Canvas Builder templates follow the same scale to maintain compatibility.