Modal dialogs can be implemented as both controlled and non-controlled components (the dialog controls its own closed state), but it is more commonly used as controlled components.
Since the modal dialog component does not contain that many elements, we can keep things simple and define a single ModalDialog
component.
The ModalDialog
component takes the following props:
title
: String to be shown at the top of the modal dialog.children
: The content to be displayed in the modal. It can either be a custom prop or children
prop, but the latter is a more common way to render contents.open
: A boolean to control the visibility of the modal (defaults to false
). If it is false
, nothing is rendered to the DOM.onClose
: Callback triggered when the modal dialog is meant to be closed.Since the modal dialog component is a controlled component, given the current basic requirements there's no need for any state within the modal. However, the modal dialog is controlled externally and state is required outside to toggle the visibility of the modal.
The key elements for the modal dialog are the (1) overlay, (2) modal dialog, (3) modal title:
position: fixed
and inset: 0
will render the element to cover the entire screen. Set a semi-transparent color for the background, e.g. rgba(0, 0, 0, 0.7)
.display: flex; align-items: center; justify-content: center
styles.<h1>
establishes the modal's content as its own document outline, which clearly indicates the primary heading of this new context to screen readers.Rendering modal dialogs is tricky due to the fact that modals are being displayed over the page and does not follow the normal flow of page elements.
Hence it is mandatory to render the modal outside of the DOM hierarchy of the parents. Otherwise, if the parents contain styling that clips its contents, the modal contents might not be fully visible. Here's an example from the React docs demonstrating the issue.
In React, rendering outside the DOM hierarchy of the parent component can be achieved using React Portals. Other common use cases of portals include tooltips, dropdown menus, popovers.
There are a lot of a11y considerations for modal dialogs, possibly too many to implement during interviews.
For your knowledge, here are some of the more important ones:
role="dialog"
on the modal container.aria-modal="true"
to indicate that the modal is blocking interaction with the page content.aria-labelledby
to associate the modal's title with the dialog.aria-describedby
if there's additional descriptive text.The subsequent questions will involve implementing these a11y considerations: