The modal component provides a solid foundation for creating dialogs, popovers, lightboxes, or whatever else.
The component renders its children
node in front of a backdrop component.
The Modal
offers important features:
The term āmodalā is sometimes used to mean ādialogā, but this is a misnomer. A modal window describes parts of a UI. An element is considered modal if it blocks interaction with the rest of the application.
If you are creating a modal dialog, you probably want to use the Dialog component rather than directly using Modal. Modal is a lower-level construct that is leveraged by the following components:
{{ādemoā: āBasicModal.jsā}}
Notice that you can disable the outline (often blue or gold) with the outline: 0
CSS property.
Modals can be nested, for example a select within a dialog, but stacking of more than two modals, or any two modals with a backdrop is discouraged.
{{ādemoā: āNestedModal.jsā}}
The open/close state of the modal can be animated with a transition component. This component should respect the following conditions:
in
prop. This corresponds to the open/close state.onEnter
callback prop when the enter transition starts.onExited
callback prop when the exit transition is completed.
These two callbacks allow the modal to unmount the child content when closed and fully transitioned.Modal has built-in support for react-transition-group.
{{ādemoā: āTransitionsModal.jsā}}
Alternatively, you can use react-spring.
{{ādemoā: āSpringModal.jsā}}
The content of modal is unmounted when closed.
If you need to make the content available to search engines or render expensive component trees inside your modal while optimizing for interaction responsiveness
it might be a good idea to change this default behavior by enabling the keepMounted
prop:
<Modal keepMounted />
import * as React from 'react';
import Box from '@mui/material/Box';
import Modal from '@mui/material/Modal';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
export default function KeepMountedModal() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (
<div>
<Button onClick={handleOpen}>Open modal</Button>
<Modal
keepMounted
open={open}
onClose={handleClose}
aria-labelledby="keep-mounted-modal-title"
aria-describedby="keep-mounted-modal-description"
>
<Box sx={style}>
<Typography id="keep-mounted-modal-title" variant="h6" component="h2">
Text in a modal
</Typography>
<Typography id="keep-mounted-modal-description" sx={{ mt: 2 }}>
Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
</Typography>
</Box>
</Modal>
</div>
);
}
As with any performance optimization, this is not a silver bullet. Be sure to identify bottlenecks first, and then try out these optimization strategies.
React doesnāt support the createPortal()
API on the server.
In order to display the modal, you need to disable the portal feature with the disablePortal
prop:
{{ādemoā: āServerModal.jsā}}
The modal moves the focus back to the body of the component if the focus tries to escape it.
This is done for accessibility purposes. However, it might create issues. In the event the users need to interact with another part of the page, for example with a chatbot window, you can disable the behavior:
<Modal disableEnforceFocus />
(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
Be sure to add aria-labelledby="id..."
, referencing the modal title, to the Modal
.
Additionally, you may give a description of your modal with the aria-describedby="id..."
prop on the Modal
.
<Modal aria-labelledby="modal-title" aria-describedby="modal-description">
<h2 id="modal-title">My Title</h2>
<p id="modal-description">My Description</p>
</Modal>
The WAI-ARIA Authoring Practices can help you set the initial focus on the most relevant element, based on your modal content.
Keep in mind that a āmodal windowā overlays on either the primary window or another modal window. Windows under a modal are inert. That is, users cannot interact with content outside an active modal window. This might create conflicting behaviors.