VaneUI

VaneUI

Overlay Components

Overlay

A fullscreen backdrop overlay for creating modal backgrounds, loading screens, and lightbox effects. Renders via portal with click-to-close and optional blur.

SourceEdit this page

Overlay ships its own layout defaults: fixed, flex, itemsCenter, justifyCenter. It covers the viewport via inset-0 and reads its z-index from a managed stacking context so nested overlays layer correctly. Modal provides its own backdrop layer using the same layout defaults.

Basic usage

A fullscreen semi-transparent backdrop. Click the overlay background to dismiss.

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Overlay</Button>
<Overlay open={open} onClose={() => setOpen(false)}>
<Text>Click the background to close</Text>
</Overlay>
</>
);

Overlay with content

Place content inside the overlay. Click handlers on the overlay only fire when the event target is the overlay itself, so children receive their own clicks without dismissing the overlay.

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Overlay</Button>
<Overlay open={open} onClose={() => setOpen(false)}>
<Card>
<Text>Overlay content here</Text>
<Button onClick={() => setOpen(false)}>Close</Button>
</Card>
</Overlay>
</>
);

Blur effect

Add backdropBlur for a backdrop-filter blur behind the overlay. Blur intensity follows the --overlay-blur CSS variable.

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Blur Overlay</Button>
<Overlay open={open} onClose={() => setOpen(false)} backdropBlur>
<Card>
<Text>Blurred background</Text>
</Card>
</Overlay>
</>
);

Custom backdrop color

The backdrop paints the --overlay-bg scrim by default. Pass a className with a background utility to override it, or transparent to drop the scrim entirely.

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Tinted Overlay</Button>
<Overlay open={open} onClose={() => setOpen(false)} className="bg-red-500/40">
<Card>
<Text>Tinted overlay</Text>
</Card>
</Overlay>
</>
);

Use className for gradients or backgrounds the appearance system doesn't cover:

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Gradient Overlay</Button>
<Overlay
open={open}
onClose={() => setOpen(false)}
className="bg-gradient-to-br from-black/80 to-transparent"
>
<Card>
<Text>Custom gradient backdrop</Text>
</Card>
</Overlay>
</>
);

Non-dismissible Overlay

Use pointerEventsNone for loading states where the overlay should pass clicks through and never close on its own. Useful for full-screen spinners that sit above the page.

react-icon
const [loading, setLoading] = useState(false);
return (
<>
<Button onClick={() => setLoading(!loading)}>Toggle Loading</Button>
<Overlay open={loading} pointerEventsNone>
<Text>Loading...</Text>
</Overlay>
</>
);

Transparent Overlay

Use transparent to create an invisible backdrop that still captures clicks. Useful for click-away dismissal without visually dimming the page.

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Transparent Overlay</Button>
<Overlay open={open} onClose={() => setOpen(false)} transparent>
<Card>
<Text>Content on a transparent overlay</Text>
<Button onClick={() => setOpen(false)}>Close</Button>
</Card>
</Overlay>
</>
);

Foundation for Modal

Modal layers a dialog surface over its own portal-rendered backdrop, which handles portaling, backdrop click, and stacking (the same mechanics as Overlay). For accessible dialogs with focus trap, scroll lock, and ARIA wiring, prefer Modal. Reach for Overlay directly when you need a custom backdrop layer (lightbox, loading shade, drawer scrim) without dialog semantics.

react-icon
{/* High-level: use Modal for dialogs */}
<Modal open={open} onClose={() => setOpen(false)}>
<Text>Accessible dialog with focus trap</Text>
</Modal>
{/* Low-level: use Overlay for custom backdrops */}
<Overlay open={open} onClose={() => setOpen(false)} backdropBlur>
<Img src="/photo.jpg" className="max-h-[90vh]" />
</Overlay>

Portal target

Overlay renders into document.body by default via React portal. Set portal={false} to render in-place, useful when the overlay must be scoped to a positioned ancestor (e.g., scrim over a single card instead of the whole viewport).

Parent card

react-icon
const [open, setOpen] = useState(false);
return (
<Card relative className="h-64">
<Text>Parent card</Text>
<Button onClick={() => setOpen(true)}>Show scoped overlay</Button>
<Overlay open={open} onClose={() => setOpen(false)} portal={false} absolute>
<Text>Scoped to this card</Text>
</Overlay>
</Card>
);

When portal={false} and absolute is set, the overlay anchors to the nearest relative/absolute ancestor instead of the viewport.

Z-index / stacking

Overlay reads its z-index from a managed stacking context (--z-index), so multiple overlays stack in mount order automatically. Override per instance by setting the variable with an arbitrary-property class ([--z-index:9999]) when you need to layer above a specific element (toasts, page chrome).

react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Overlay</Button>
<Overlay
open={open}
onClose={() => setOpen(false)}
className="[--z-index:9999]"
>
<Card>
<Text>Above everything</Text>
</Card>
</Overlay>
</>
);

Custom animation duration

Control how the overlay transitions in and out. Use transitionDuration to set a custom duration in milliseconds (default 200), or noAnimation to disable transitions entirely for an instant open/close.

react-icon
const [openSlow, setOpenSlow] = useState(false);
const [openInstant, setOpenInstant] = useState(false);
return (
<>
<Row>
<Button onClick={() => setOpenSlow(true)}>Slow fade (500ms)</Button>
<Button onClick={() => setOpenInstant(true)}>Instant</Button>
</Row>
{/* Slow fade - 500ms */}
<Overlay open={openSlow} onClose={() => setOpenSlow(false)} transitionDuration={500}>
<Card>Slow transition content</Card>
</Overlay>
{/* Instant - no animation */}
<Overlay open={openInstant} onClose={() => setOpenInstant(false)} noAnimation>
<Card>Instant content</Card>
</Overlay>
</>
);

Lifecycle and mounting

PropDefaultDescription
opentrueWhether the overlay is visible
onClose-Called when the overlay is dismissed (backdrop click or Escape)
portaltrueRender into document.body via React portal
keepMountedfalseKeep DOM mounted when closed (useful for transition state preservation)
noAnimationfalseDisable enter/exit transitions
transitionDuration200Animation duration in ms
onEnterComplete-Called when enter transition completes
onExitComplete-Called when exit transition completes
react-icon
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Show Overlay</Button>
<Overlay
open={open}
onClose={() => setOpen(false)}
keepMounted
transitionDuration={300}
onExitComplete={() => console.log('overlay closed')}
>
<Card>Persistent DOM, custom timing</Card>
</Overlay>
</>
);

Overlay Props

PropCategoryDefaultDescription
lg

Size

Large size

md

Size

Medium size (default)

sm

Size

Small size

xl

Size

Extra large size

xs

Size

Extra small size

Layout & utility props (gap, padding, hide, items, justify, ...) — documented on Common Props
PropCategoryDefaultDescription
backdropBlur

Blur

Enable backdrop blur effect — emits backdrop-blur

noBackdropBlur

Blur

Disable backdrop blur effect

block

Display

Block display - takes full width, new line

contents

Display

Contents display - element's box is removed, children display as if parent didn't exist

flex

Display

✓

Flex display - flexbox container

grid

Display

Grid display - CSS grid container

hidden

Display

Hidden display - element is not visible

inline

Display

Inline display - flows with text

inlineBlock

Display

Inline-block display - inline but with block properties

inlineFlex

Display

Inline-flex display - inline flexbox container

inlineGrid

Display

Inline-grid display - inline grid container

table

Display

Table display - behaves like table element

tableCell

Display

Table-cell display - behaves like td element

hAuto

Height

Set height to auto

hFit

Height

Set height to fit-content

hFull

Height

Set height to 100%

hScreen

Height

Set height to 100vh (viewport height), removes max-height constraint

desktopHide

Hide

Hide element on desktop devices and below (max-desktop: 80rem)

mobileHide

Hide

Hide element on mobile devices and below (max-mobile: 48rem)

tabletHide

Hide

Hide element on tablet devices and below (max-tablet: 64rem)

itemsBaseline

Items

Align items to baseline

itemsCenter

Items

✓

Align items to center

itemsEnd

Items

Align items to end (bottom/right)

itemsStart

Items

Align items to start (top/left)

itemsStretch

Items

Stretch items to fill container

justifyAround

Justify

Distribute items with space around them

justifyBaseline

Justify

Align items along their baseline on main axis

justifyBetween

Justify

Distribute items with space between them

justifyCenter

Justify

✓

Center items along the main axis

justifyEnd

Justify

Pack items toward the end of the main axis

justifyEvenly

Justify

Distribute items with equal space around them

justifyStart

Justify

Pack items toward the start of the main axis

justifyStretch

Justify

Stretch items to fill the main axis

overflowAuto

Overflow

Auto overflow - show scrollbars if needed

overflowClip

Overflow

Clip overflow - hard clip without scrollbars

overflowHidden

Overflow

Hidden overflow - clip content without scrollbars

overflowScroll

Overflow

Scroll overflow - always show scrollbars

overflowVisible

Overflow

Visible overflow - content extends beyond bounds

overflowXAuto

Overflow

Auto overflow on X-axis only

overflowXClip

Overflow

Clip overflow on X-axis only

overflowXHidden

Overflow

Hidden overflow on X-axis only

overflowXScroll

Overflow

Scroll overflow on X-axis only

overflowXVisible

Overflow

Visible overflow on X-axis only

overflowYAuto

Overflow

Auto overflow on Y-axis only

overflowYClip

Overflow

Clip overflow on Y-axis only

overflowYHidden

Overflow

Hidden overflow on Y-axis only

overflowYScroll

Overflow

Scroll overflow on Y-axis only

overflowYVisible

Overflow

Visible overflow on Y-axis only

pointerEventsAuto

Pointer Events

Enable pointer events (default browser behavior)

pointerEventsNone

Pointer Events

Disable pointer events - clicks pass through the element

absolute

Position

Absolute positioning

fixed

Position

✓

Fixed positioning

relative

Position

Relative positioning

static

Position

Static positioning

sticky

Position

Sticky positioning

responsiveSizing

Responsive Sizing

Enable responsive sizing - uses breakpoint-specific classes for font size, padding, and gap

transparent

Transparent

Disable background color - makes component background transparent

wAuto

Width

Set width to auto

wFit

Width

Set width to fit-content

wFull

Width

Set width to 100%

wScreen

Width

Set width to 100vw (viewport width), removes max-width constraint

More in Overlay Components