Portals provide a mechanism to render child components into a different DOM node located outside the DOM hierarchy of the parent component, while retaining standard React event bubbling behavior.
Portals are essential for UI overlays such as modal dialogs, tooltips, notification toasts, and popovers that must break out of parent container overflow: hidden or z-index stacking contexts.
flowchart LR
CompTree["React Component Tree (<Modal /> in <Card />)"] --> Portal["ReactDOM.createPortal()"]
Portal --> TargetDOM["HTML DOM (#modal-root)"]
index.html<body>
<div id="root"></div>
<!-- Separate DOM target node for portals -->
<div id="modal-root"></div>
</body>
Modal.jsximport React from 'react';
import { createPortal } from 'react-dom';
export default function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
const modalRoot = document.getElementById('modal-root');
if (!modalRoot) return null;
return createPortal(
<div className="modal-backdrop" onClick={onClose}>
<div
className="modal-content"
onClick={(e) => e.stopPropagation()} // Prevent closing when clicking content
>
<button className="close-btn" onClick={onClose}>×</button>
{children}
</div>
</div>,
modalRoot // Target DOM Node
);
}
Even though a portal element is rendered into a separate HTML DOM node, it behaves like a standard React child in all other ways. Events fired from inside a portal propagate up the React component tree (not the HTML DOM tree).
document.getElementById('modal-root') exists before mounting the portal to avoid runtime null reference errors.Escape key to close) and maintain focus traps inside modal portals for web accessibility compliance.Explain why tooltips rendered inside containers with overflow: hidden get clipped unless rendered through a React Portal.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With