z-index Pattern for Modals and Overlays
Best practices for layering modal dialogs, backdrop overlays, and their content using a structured z-index approach.
Detailed Explanation
Modal and Overlay z-index Pattern
Modals are one of the most common z-index challenges. A typical modal system needs at least three layers: the backdrop/overlay, the modal dialog itself, and any elements that should appear above the modal (like toasts or tooltips).
Recommended Layer Structure
:root {
--z-overlay: 1040;
--z-modal: 1050;
--z-modal-close: 1; /* relative within modal's stacking context */
--z-toast: 1080;
--z-tooltip: 1090;
}
Implementation
/* Backdrop covers entire viewport */
.modal-backdrop {
position: fixed;
inset: 0;
z-index: var(--z-overlay);
background: rgba(0, 0, 0, 0.5);
}
/* Modal dialog sits above backdrop */
.modal {
position: fixed;
z-index: var(--z-modal);
isolation: isolate; /* scope internal z-index */
}
/* Close button is relative within modal's context */
.modal-close {
position: absolute;
z-index: var(--z-modal-close);
top: 1rem;
right: 1rem;
}
/* Toasts appear above modals */
.toast-container {
position: fixed;
z-index: var(--z-toast);
}
Key Considerations
Backdrop and modal should be siblings, not parent-child. If the backdrop is a parent of the modal, the modal's z-index is relative to the backdrop's stacking context.
Use
isolation: isolateon the modal to create a clean stacking context for internal elements like close buttons, dropdown menus within the modal, etc.Portal rendering: In React, Vue, or Angular, render modals via a portal to the document body. This ensures they are not trapped inside a parent's stacking context.
Multiple modals: If your app supports stacking modals, increment z-index dynamically. Each new modal gets the base value plus an offset (e.g., 1050, 1051, 1052).
Anti-patterns
- Putting the modal inside a container with
overflow: hiddenortransform - Using
z-index: 999999instead of a deliberate scale - Nesting the backdrop inside the modal instead of making them siblings
Use Case
When building a modal system for a web application that needs to handle backdrop overlays, nested modals, tooltips appearing above modals, and toast notifications that are always visible.