Modal overlay with portal, backdrop, and focus management.
Introduction
Modal is a lower-level overlay primitive. It renders children in front of a backdrop, locks page scroll by default, and manages focus while open.
Use Modal when you need a custom content shell (often with Card). Prefer useDialogAction for confirm/cancel flows with a standard footer.
Modal vs blocking dialog behavior: Modal itself is a generic overlay—it does not require user input to dismiss unless you configure it that way. For blocking dialogs that demand an explicit decision (confirm delete, accept terms), combine Modal with Card for structured title and actions, and set persistent so Escape and backdrop clicks do not close the overlay until the user chooses a footer action. For non-blocking overlays or drawers, leave persistent false so users can dismiss quickly.
Unlike Snackbar, Modal interrupts interaction with the page below through backdrop and focus trapping.
Import
import { Modal } from "@bridge-ui/vue/Components/Modal";import { Modal } from "@bridge-ui/react/Components/Modal";Basic usage
Pair a trigger such as a Button with a controlled Modal. Place content such as a Card inside the dialog panel.
Sizes
Use the size prop on Modal to set max width from the sm breakpoint up. Available sizes: sm, md (default), lg, xl, and full.
Persistent
When persistent is true, Escape and backdrop clicks do not close the modal. Provide an explicit close action inside the content.
Card composition
Combine Modal with Card for structured dialogs. Use Card slots for title, body, and footer actions. Additional Modal props such as blur, size, and transition customize the overlay experience.
Align
Use the align prop to position the panel on all breakpoints. Available values include middle-center (default), top-start, bottom-end, and others.
align now applies on every viewport. Mobile no longer forces a bottom sheet. Use useBreakpoint to restore bottom-sheet-on-mobile behavior.
Responsive align
Combine Modal with useBreakpoint when you want a different align per viewport—for example a bottom sheet on mobile and a centered dialog on larger screens.
Transitions and blur
Set transition to control enter/leave animation (fade, scale, slide-up, slide-down, or none). Combine with blur on the backdrop for depth.
Nested modals
Place a second Modal inside the first. Each layer gets its own overlay and a higher z-index. Escape closes only the topmost modal.
Scroll lock
While open, Modal locks body scroll and adds padding-right on document.body so page content does not shift when the scrollbar disappears. Fixed or sticky UI outside the document flow is not covered by that padding. Bridge UI sets --bridge-scrollbar-compensation on :root with the scrollbar width for the duration of the lock (and clears it when the last locking layer closes):
.my-fixed-header {
padding-inline-end: var(--bridge-scrollbar-compensation, 0px);
}Set disableScrollLock if the page should keep scrolling behind the overlay.
Related components
Card, Button, Drawer, useBreakpoint
Accessibility
- Content under an active modal is inert—users cannot interact with the page behind the overlay.
- Focus is trapped inside the modal by default (disableEnforceFocus disables this).
- Focus returns to the trigger on close unless disableRestoreFocus is set.
- Escape closes the modal when closeOnEscape is true and persistent is false.
- When using Card inside Modal, ensure the card title is referenced for context. Pass aria-labelledby and aria-describedby on Modal via root attributes or customProps pointing to title and description element IDs.
- Enable autoFocus to move focus to the first focusable element when the modal opens.
Anatomy
<div> <!-- Modal root (portaled) -->
<div> <!-- overlay / backdrop -->
<div> <!-- paper panel -->
<!-- children: Card, form, or custom content -->
</div>
</div>Target overlay and panel styling with the classes prop. align applies on all breakpoints; size still sets max width from the sm breakpoint up.
API
| Prop | Type | Default | Description |
|---|---|---|---|
| v-model | boolean | — | Two-way binding for overlay visibility. |
| @close | — | — | Fired when the user dismisses (Escape or click-away). Not fired when the parent sets v-model={false} directly. |
| @show-change | (show: boolean) => void | — | Equivalent to onShowChange when you prefer events over a callback prop. |
| Prop | Type | Default | Description |
|---|---|---|---|
| show | boolean | — | Whether the overlay is visible. Use with onShowChange for controlled state. |
| onShowChange | (show: boolean) => void | — | Called when visibility changes. |
| onClose | () => void | — | Fired when the user dismisses (Escape or click-away). Not fired when the parent sets show={false} directly. |
| Prop | Type | Default | Description |
|---|---|---|---|
| size | ModalSize | "md" | Max width from the sm breakpoint up. |
| align | ModalAlign | "middle-center" | Panel position on all breakpoints. Use useBreakpoint for per-viewport align. |
| transition | ModalTransition | "fade" | Enter/leave animation for overlay and panel. |
| blur | ModalBlur | "none" | Backdrop blur on the overlay. |
| persistent | boolean | false | When true, Escape and overlay clicks do not close the modal. |
| closeOnEscape | boolean | true | Whether the modal closes on Escape. |
| closeOnOverlay | boolean | true | Whether the modal closes on overlay click. |
| hideBackdrop | boolean | false | When true, the backdrop overlay is not rendered. |
| scroll | ModalScroll | "body" | Where scroll happens: page (body) or panel (paper). |
| autoFocus | boolean | false | Focus the first focusable element on open. |
| disableEnforceFocus | boolean | false | When true, focus is not trapped inside the modal. |
| disableRestoreFocus | boolean | false | When true, focus is not restored on close. |
| disableScrollLock | boolean | false | When true, body scroll is not locked while open. |
| keepMounted | boolean | false | When true, the modal stays mounted after closing (hidden). |
| teleportTo | string | false | "body" | Portal target. Pass false to render in place. |
| classes | ModalClasses | — | Class overrides for modal parts. |
| customProps | ModalCustomProps | — | Props forwarded to each modal part. |