z-index for Dropdown Menus and Popovers
How to properly layer dropdown menus, select boxes, and popovers so they appear above surrounding content without z-index conflicts.
Common Patterns
Detailed Explanation
Dropdown Menu z-index Strategy
Dropdown menus need to appear above the surrounding page content but below higher-priority layers like modals, toasts, and tooltips. Getting this right requires a well-defined z-index scale.
Typical Layer Hierarchy
:root {
--z-dropdown: 1000;
--z-sticky: 1020;
--z-modal-backdrop: 1040;
--z-modal: 1050;
--z-popover: 1060;
--z-tooltip: 1070;
}
Implementation
/* Basic dropdown */
.dropdown-menu {
position: absolute;
z-index: var(--z-dropdown);
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* Dropdown inside a sticky header */
.sticky-header {
position: sticky;
top: 0;
z-index: var(--z-sticky);
}
.sticky-header .dropdown-menu {
z-index: var(--z-sticky); /* inherits parent's context */
}
Common Issues and Fixes
Problem 1: Dropdown clipped by overflow:hidden parent
/* Bad: dropdown gets clipped */
.card { overflow: hidden; }
.card .dropdown-menu { z-index: 1000; } /* clipped! */
/* Fix: use a portal or position:fixed */
.dropdown-menu--portal {
position: fixed;
z-index: var(--z-dropdown);
}
Problem 2: Dropdown appears behind sibling elements
/* The trigger needs a stacking context */
.dropdown-trigger {
position: relative;
z-index: 1; /* creates stacking context */
}
Problem 3: Multiple dropdowns competing
/* Close other dropdowns when one opens, or increment z-index */
.dropdown-menu--active {
z-index: calc(var(--z-dropdown) + 1);
}
Best Practices
- Always use
position: absoluteorposition: fixedfor dropdown menus - Consider using a portal (React Portal, Vue Teleport) for dropdowns in complex layouts
- Use a consistent z-index variable, not hardcoded numbers
- Test dropdowns inside modals, sticky headers, and overflow containers
Use Case
When building navigation menus, autocomplete dropdowns, or context menus that need to appear above page content but still respect the overall z-index hierarchy of modals and toasts.