Modal
Accessible modal/dialog component with focus trapping and keyboard navigation
Same BEM classes and behavior as Astro, Svelte, and React.
Add this component
The command below includes <strong>Modal</strong>—run it in your project directory to install this component (and the CSS if needed). No prompts.
Choose your package manager — click a tab to select, then copy the command.
pnpm dlx rizzo-css add Modal
Live examples
Usage
Usage
Full example for each framework (Astro, Vanilla, Svelte, Vue, React). Switch framework via View as or by clicking a Usage tab—both stay in sync.
Astro Vanilla Svelte Vue React ---
import Modal from '../components/astro/Modal.astro';
---
<Modal id="demo-modal" title="Modal title" triggerLabel="Open modal" client:load>
<p>Modal content.</p>
</Modal>
<!-- Use .modal-root so overlay stacks behind the modal. Overlay id: <modalId>-overlay. -->
<div class="modal-root">
<div class="modal__overlay" id="my-modal-overlay" aria-hidden="true"></div>
<div class="modal modal--md" id="my-modal" role="dialog" aria-modal="true" aria-labelledby="my-modal-title" aria-hidden="true">
<div class="modal__header">
<h2 id="my-modal-title" class="modal__title">Title</h2>
<button type="button" class="modal__close" data-modal-close aria-label="Close">×</button>
</div>
<div class="modal__body">Content</div>
<div class="modal__footer"><button type="button" class="btn" data-modal-close>Close</button></div>
</div>
</div>
<button type="button" class="btn" data-modal-open="my-modal">Open</button>
<script>
import { Modal, Button } from '$lib/rizzo';
let open = $state(false);
</script>
<Button onclick={() => (open = true)}>Open modal</Button>
<Modal bind:open title="Modal title">
<p>Modal content.</p>
</Modal>
<script setup>
import { ref } from 'vue';
import Modal from '@/components/rizzo/Modal.vue';
import Button from '@/components/rizzo/Button.vue';
</script>
<template>
<Button @click="open = true">Open modal</Button>
<Modal v-model:open="open" title="Modal title">
<p>Modal content.</p>
</Modal>
</template>
import { useState } from 'react';
import { Modal, Button } from './components/react';
const [open, setOpen] = useState(false);
<Button onClick={() => setOpen(true)}>Open modal</Button>
<Modal open={open} onOpenChange={setOpen} title="Modal title">
<p>Modal content.</p>
</Modal>
Other frameworks: Astro · Vanilla · Svelte · React