What Is a z-index Layer System?
When UI elements overlap, z-index determines which one appears on top. Higher values render in front, but only within the same stacking context. Without a structured scale, codebases end up littered with arbitrary values like z-index: 9999, causing hard-to-debug layering conflicts.
A 100-unit scale (0, 100, 200…) leaves room for intermediate layers while keeping the hierarchy readable at a glance. Every team member knows that anything above 500 is modal territory, above 800 is notification territory, and so on.
Design Principles
Always separate the overlay backdrop (400) from the modal itself (500) so the dim layer sits below the dialog. Toasts (800) must exceed modals (500) so notifications remain visible even when a modal is open. Place full-screen loaders (900) above everything except the most critical banners (1000).
Stacking Context Gotchas
Properties like transform, opacity < 1, filter, and will-change create new stacking contexts. A child's z-index cannot escape its parent's context. Render modals and overlays as direct children of <body> (e.g., via React Portal) to avoid this trap.
Frequently Asked Questions
Toasts should be higher. Notifications need to appear above modals, so toasts (800) should always exceed modals (500).
Not on statically positioned elements. z-index only applies when position is relative, absolute, fixed, or sticky. Flexbox and Grid direct children are an exception.
It works but creates maintenance problems. Without a defined scale, developers keep adding higher values, leading to conflicts. A structured scale prevents this.