Z-Index & Stacking
How Tamagui automatically stacks overlays and floating content
Tamagui includes an automatic stacking system that ensures overlays like dialogs, popovers, sheets, and tooltips layer correctly without manual z-index management.
How It Works
When you open overlay components, Tamagui automatically assigns z-index values so that:
- Later-opened content appears above earlier content - Open two dialogs? The second one stacks above the first.
- Nested content appears above its parent - A tooltip inside a dialog automatically renders above the dialog.
- Closing restores order - When content closes, z-index values are reclaimed.
This means you typically don’t need to think about z-index at all.
When to Set zIndex
Only set zIndex when you need to override the automatic stacking. Common cases:
- Fixed headers/footers - If you have a sticky header at
z-index: 100, overlays need to appear above it (they do by default). - Third-party libraries - If integrating with libraries that use high z-index values.
- Custom stacking requirements - When you need specific layering that differs from open-order.
// Only if you need to override automatic stacking<Dialog zIndex={200000}>...</Dialog>
Component Defaults
All overlay components use the automatic stacking system. Here’s where to set zIndex if needed:
| Component | Where to set zIndex |
|---|---|
| Dialog | <Dialog zIndex={...}> |
| AlertDialog | <AlertDialog zIndex={...}> |
| Sheet | <Sheet zIndex={...}> |
| Select | <Select zIndex={...}> |
| Popover | <Popover zIndex={...}> |
| Tooltip | <Tooltip zIndex={...}> |
| Menu | <Menu.Portal zIndex={...}> |
| ContextMenu | <ContextMenu.Portal zIndex={...}> |
| Toast | Via ToastViewport |
Stacking Hierarchy
By default, components stack in this order (lowest to highest):
- Popover, Tooltip, Menu - Pure auto-stacking, starts around z-index 5001
- Dialog, AlertDialog, Select, Sheet - Use a higher base (100000+) to ensure they appear above most UI
Within each category, mount order determines stacking - open a popover, then another, the second is on top.
Nested Stacking
Nested floating elements automatically stack above their parent:
<Dialog><Dialog.Content>{/* This tooltip will appear above the dialog */}<Tooltip><Tooltip.Trigger><Button>Hover me</Button></Tooltip.Trigger><Tooltip.Content>I appear above the dialog!</Tooltip.Content></Tooltip></Dialog.Content></Dialog>
The system tracks parent-child relationships through React context, so nested portals always stack correctly.
Technical Details
The stacking system uses two mechanisms:
Horizontal Stacking (Siblings)
When multiple overlays open at the same level, each gets an incrementing z-index:
- First dialog: 105001
- Second dialog: 105002
- Third dialog: 105003
Vertical Stacking (Nested)
When content opens inside another portal, it reads the parent’s z-index from context and adds 1:
- Dialog opens at 105001
- Popover inside dialog: 105002
- Tooltip inside that popover: 105003
This ensures nested content is always visible above its parent, but sibling content opened later can still stack above.
Portal Component
The Portal component powers this stacking system. If building custom overlay components, you can use Portal’s stackZIndex prop:
import { Portal } from 'tamagui'// Enable automatic stacking<Portal stackZIndex>{/* content */}</Portal>// Or use a high base value (like Dialog does)<Portal stackZIndex={100000}>{/* content */}</Portal>
See the Portal documentation for more details.