mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
118 lines
4.1 KiB
Plaintext
118 lines
4.1 KiB
Plaintext
---
|
|
title: Z-Index & Stacking
|
|
description: How Gui automatically stacks overlays and floating content
|
|
name: z-index
|
|
---
|
|
|
|
Gui 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, Gui 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.
|
|
|
|
```tsx
|
|
// 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](/ui/dialog) | `<Dialog zIndex={...}>` |
|
|
| [AlertDialog](/ui/alert-dialog) | `<AlertDialog zIndex={...}>` |
|
|
| [Sheet](/ui/sheet) | `<Sheet zIndex={...}>` |
|
|
| [Select](/ui/select) | `<Select zIndex={...}>` |
|
|
| [Popover](/ui/popover) | `<Popover zIndex={...}>` |
|
|
| [Tooltip](/ui/tooltip) | `<Tooltip zIndex={...}>` |
|
|
| [Menu](/ui/menu) | `<Menu.Portal zIndex={...}>` |
|
|
| [ContextMenu](/ui/context-menu) | `<ContextMenu.Portal zIndex={...}>` |
|
|
| [Toast](/ui/toast) | Via `ToastViewport` |
|
|
|
|
## Stacking Hierarchy
|
|
|
|
By default, components stack in this order (lowest to highest):
|
|
|
|
1. **Popover, Tooltip, Menu** - Pure auto-stacking, starts around z-index 5001
|
|
2. **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:
|
|
|
|
```tsx
|
|
<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](/ui/portal) component powers this stacking system. If building custom overlay components, you can use Portal's `stackZIndex` prop:
|
|
|
|
```tsx
|
|
import { Portal } from '@hanzo/gui'
|
|
|
|
// 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](/ui/portal) for more details.
|