Skip to content
+

Modal

The Modal component lets you create dialogs, popovers, lightboxes, and other elements that force the user to take action before continuing.

Introduction

Modal is a utility component that renders its children in front of a backdrop. This lets you create an element that your users must interact with before continuing in the parent application.

Modal is a lower-level construct that is used in the following Material UI components:

Component

import { Modal } from '@mui/base/Modal';

The following demo shows how to create and style a basic modal. Click Open modal to see how it behaves:

Customization

Nested modal

The following demo shows how to nest one Modal within another:

Transitions

You can animate the open and close states of a Modal using a transition component, as long as that component fulfills the following requirements:

  • Is a direct child descendant of the Modal
  • Has an in prop—this corresponds to the open/close state
  • Calls the onEnter callback prop when the enter transition starts
  • Calls the onExited callback prop when the exit transition is completed

Modal has built-in support for react-transition-group:

You can also use react-spring with Modal, but it will require additional custom configuration:

Performance

The Modal's content is unmounted when it's not open. This means that it will need to be re-mounted each time it's opened.

If you're rendering expensive component trees inside your Modal, and you want to optimize for interaction responsiveness, you can change this default behavior by enabling the keepMounted prop.

You can also use the keepMounted prop if you want to make the content of the Modal available to search engines (even when the Modal is closed).

The following demo shows how to apply this prop to keep the Modal mounted:

As with any performance optimization, the keepMounted prop won't necessarily solve all of your problems. Explore other possible bottlenecks in performance where you could make more considerable improvements before implementing this prop.

Server-side modal

React doesn't support the createPortal() API on the server.

In order to display a Modal rendered on the server, you need to disable the portal feature with the disablePortal prop, as shown in the following demo:

Limitations

Overflow layout shift

The Modal disables the page scrolling while open by setting overflow: hidden as inline-style on the relevant scroll container, this hides the scrollbar and hence impacts the page layout. To compensate for this offset and avoid a layout shift, the Modal also set a padding property on the scroll container (~15px under normal conditions).

This can create a layout shift with position: fixed and position: sticky elements. You need to add the .mui-fixed class name on these elements so the Modal can add a CSS padding property when the scroll is disabled.

<Box sx={{ position: 'sticky', right: 0, top: 0, left: 0 }} className="mui-fixed">

Focus trap

Modal moves the focus back to the body of the component if the focus tries to escape it.

This is done for accessibility purposes, but it can potentially create issues for your users.

If the user needs to interact with another part of the page—for example, to interact with a chatbot window while a Modal is open in the parent app—you can disable the default behavior with the disableEnforceFocus prop.

Hook

import useModal from '@mui/base/unstable_useModal';

The useModal hook lets you apply the functionality of a Modal to a fully custom component. It returns props to be placed on the custom component, along with fields representing the component's internal state.

Hooks do not support slot props, but they do support customization props.

The following demo shows how to build the same Modal as the one found in the Component section above, but with the useModal hook:

Press Enter to start editing

If you use a ref to store a reference to the root element, pass it to the useModal's ref parameter, as shown in the demo above. It will get merged with a ref used internally in the hook.

Accessibility

See the WAI-ARIA guide on the Dialog (Modal) pattern for complete details on accessibility best practices.

  • All interactive elements must have an accessible name. Use the aria-labelledby="id..." to give your Modal component an accessible name. You can also use aria-describedby="id..." to provide a description of 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>
    
  • Follow the WAI-ARIA authoring practices to help you set the initial focus on the most relevant element based on the content of the Modal.