Markdown:
Components

Modal

An overlay dialog that appears on top of the main content to focus user attention.

Hello!!

Usage

Use standalone.

Svelte
<Modal {...props}>Content</Modal>

Anatomy

The class attribute values represent part names. Other attributes represent their corresponding props.

Svelte
<dialog class="whole" {...rest} aria-label>
  {children}
</dialog>

Props

NameTypeDefaultDescription
children*Snippet-Modal content; receives the variant as its argument
openbooleanfalseBindable open state
closablebooleantrueWhether light dismiss is enabled; false blocks both backdrop-click and Escape
durationnumber200Open/close animation timing in ms, published as the --svs-duration custom property
cssvarRecord-Renames the published animation-timing custom property; cssvar.duration makes the Modal read --svs-duration from a caller-named token
ariaLabelstring-Accessible label for the dialog
elementHTMLDialogElement-Bindable root element
stylingSVSClass-Styling override
variantSVSVariantNEUTRALModal variant

* required. Other HTMLDialogAttributes are passed to <dialog> via rest props; class is merged onto the root.

Modal is a native modal <dialog> opened with showModal(): focus is trapped and background content is inert while open, and page scroll is locked with :root:has(dialog[open]).

Styling

Content renders directly inside the <dialog> (whole part), so background and padding belong on whole. To learn more, see Styling.

Variant Management

No automatic switching.

Default Class Name

svs-modal

Behavior

Open/close animation timing is published as --svs-duration for caller CSS; cssvar.duration renames it (caller then owns reduced-motion for that token).

Accessibility

ARIA Roles and Attributes

The component applies these automatically:

  • Dialog (whole <dialog>): aria-label from the ariaLabel prop.

Provide an accessible name yourself because there is no built-in visible label. Pass ariaLabel, or pass aria-labelledby through the rest props. The managed aria-label attribute is omitted from ModalProps and cannot be passed as aria-label.

Standards Basis

Modal is built on a native <dialog> opened with showModal(), so keyboard and assistive-technology support follows the browser standard for modal dialogs. See the Concepts standards-first guidance for the library's approach. When closable is false, the component prevents the native Escape light-dismiss; note that a modal dialog that cannot be dismissed with Escape runs contrary to the WAI-ARIA authoring-practices recommendation for dialogs, so use it deliberately.

Exports

Types

TypeScript
interface ModalProps extends Omit<HTMLDialogAttributes, "children" | "style" | "aria-label"> {
  children: Snippet<[string]>; // Snippet<[variant]>
  open?: boolean; // bindable (false)
  closable?: boolean; // (true)
  duration?: number; // (200)
  cssvar?: Partial<Record<ModalCssVar, string>>;
  ariaLabel?: string;
  element?: HTMLDialogElement; // bindable
  styling?: SVSClass;
  variant?: SVSVariant; // (VARIANT.NEUTRAL)
  // other HTMLDialogAttributes are passed to <dialog> via ...rest; `class` is merged onto root
  // style is component-owned (omitted)
}
type ModalReqdProps = "children";
type ModalBindProps = "open" | "element";
type ModalCssVar = "duration";

Others

No additional exports are available.

Examples

The example code uses Tailwind CSS along with SVSClass.

Basic

Hello!!

With Interactive Variant

Preset for Demo
Enter variant as you like
Notifications

New features are available!