Skip to content

Modal

Introduction

The Modal component provides a dialog window that appears on top of the main content. It uses the native HTML <dialog> element for built-in accessibility features and includes smooth transitions, focus management, and keyboard interactions.

When to use

The Modal component is perfect for situations where you need to capture user attention:

  • Confirmation dialogs
  • Important notifications
  • Form submissions
  • Image galleries
  • Terms and conditions
  • Cookie consent notices
  • User feedback prompts

Usage

Learn how to implement the Modal component in your project, from basic usage to advanced configurations.

Basic

---
import { Modal } from 'accessible-astro-components'
---
<button id="modal-trigger">Open Modal</button>
<Modal
triggerId="modal-trigger"
title="Welcome!"
>
<p>This is the modal content.</p>
</Modal>

With custom close action

<Modal
triggerId="modal-action"
title="Confirm action"
closeText="Cancel"
>
<p>Are you sure you want to continue?</p>
<button onclick="closeModal()">Confirm</button>
</Modal>

Props

Configure the Modal component using these available props to customize its behavior and appearance.

PropTypeDefaultDescription
triggerIdstring-ID of the button that triggers the modal
titlestring-Title text for the modal header
closeTextstring'Close'Text for the close button
closeIconbooleantrueShow/hide the close icon
classstring''Additional CSS classes to apply

Accessibility

Accessibility isn’t an afterthought - it’s built into the core of this component through native HTML elements and careful consideration of user interactions. The Modal component is built with accessibility in mind:

  • Native <dialog> element with built-in accessibility
  • Focus management
    • Focus trapped inside modal
    • Returns focus to trigger on close
  • Keyboard support
    • Escape to close
    • Tab/Shift+Tab navigation
  • ARIA attributes and semantic structure
  • Smooth transitions with reduced-motion support

Styling

Make the Modal component your own with custom styling while maintaining its accessibility features.

/* Option 1: Using :global() in your style block */
<style>
:global(.modal) {
border-radius: 0.5rem;
border: 1px solid light-dark(hsl(204 20% 88%), hsl(215 25% 27%));
background: light-dark(hsl(0 0% 100%), hsl(215 25% 15%));
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
box-shadow: 0 4px 6px -1px hsl(0 0% 0% / 0.1);
}
:global(.modal-inner) {
padding: 1.5rem;
}
:global(.modal h3) {
margin-block-start: 0;
font-size: 1.25rem;
}
:global(.modal-close button) {
padding: 0.5rem;
color: light-dark(hsl(215 8% 45%), hsl(215 8% 65%));
}
:global(.modal-close button:hover) {
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
}
@media (prefers-reduced-motion: no-preference) {
:global(.modal[open]) {
animation: fade-in 0.2s ease-out;
}
}
</style>
/* Option 2: Using is:global on the style tag */
<style is:global>
.modal {
border-radius: 0.5rem;
border: 1px solid light-dark(hsl(204 20% 88%), hsl(215 25% 27%));
background: light-dark(hsl(0 0% 100%), hsl(215 25% 15%));
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
box-shadow: 0 4px 6px -1px hsl(0 0% 0% / 0.1);
}
.modal-inner {
padding: 1.5rem;
}
.modal h3 {
margin-block-start: 0;
font-size: 1.25rem;
}
.modal-close button {
padding: 0.5rem;
color: light-dark(hsl(215 8% 45%), hsl(215 8% 65%));
}
.modal-close button:hover {
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
}
@media (prefers-reduced-motion: no-preference) {
.modal[open] {
animation: fade-in 0.2s ease-out;
}
}
</style>

Interactive examples

See the Modal component in action with these practical examples.

Default modal

With custom close action