Introduction
React Modal is the community-standard modal dialog component maintained under the reactjs GitHub organization. It focuses on accessibility by implementing focus trapping, ARIA attributes, and keyboard interactions out of the box. The component renders its content into a portal and manages body scroll locking automatically.
What React Modal Does
- Renders modal content into a React portal outside the main DOM tree
- Traps focus inside the modal when open and restores it when closed
- Applies ARIA role, label, and description attributes for screen readers
- Locks body scroll while the modal is visible
- Closes on Escape key press or overlay click by default
Architecture Overview
React Modal creates a portal element appended to the document body (or a custom parent). When isOpen transitions to true, the component mounts its content inside this portal, applies an overlay backdrop, and moves focus to the first focusable element within the modal. A focus sentinel pattern ensures Tab and Shift+Tab cycle within the modal boundary. The setAppElement call hides the main content from screen readers via aria-hidden when a modal is active.
Installation & Configuration
- Install via npm:
npm install react-modal - Call Modal.setAppElement with your root DOM element ID for accessibility
- Control visibility with the isOpen boolean prop
- Handle close via onRequestClose, which fires on Escape and overlay click
- Customize overlay and content styles via the style prop or className
Key Features
- Focus trapping and restoration for full keyboard accessibility
- Automatic aria-hidden management on the application root element
- Portal rendering to avoid z-index and overflow clipping issues
- Body scroll lock while the modal is open
- shouldCloseOnOverlayClick and shouldCloseOnEsc props for close behavior control
Comparison with Similar Tools
- Radix Dialog — headless primitive with more composable API; no default styling
- Headless UI Dialog — Tailwind Labs headless dialog; requires Tailwind for styling
- Chakra UI Modal — feature-rich but requires the Chakra ecosystem
- MUI Dialog — Material Design styled; tied to MUI dependency
- native HTML dialog — browser-built-in element; limited styling and focus management
FAQ
Q: Why do I need to call Modal.setAppElement? A: It tells the library which DOM node is your main app content so it can set aria-hidden on it while the modal is open, preventing screen readers from reading background content.
Q: Can I render multiple modals at once? A: Yes. Each Modal instance manages its own portal. Nested or stacked modals work, though focus management applies to the topmost open modal.
Q: How do I style the modal and overlay? A: Pass a style prop with overlay and content keys, or use className and overlayClassName for CSS class-based styling.
Q: Does it work with animations? A: Yes. Use the closeTimeoutMS prop along with CSS transitions on the overlay and content classes to animate open and close.