ReactPortalModalFrontend

React Portal: Render Modals Outside Parent DOM

Use React Portal for modals, dropdowns, tooltips, drawers, and toasts that must escape overflow, stacking context, or local layout boundaries.

·Updated ·7 min read·Counting...
React Portal: Render Modals Outside Parent DOM

React normally renders a component inside its parent DOM tree. That works for most UI, but overlays such as modals, drawers, dropdowns, tooltips, and toasts often need to escape local layout constraints. A parent may have overflow: hidden, a new stacking context, or a layout boundary that clips the overlay.

React Portal lets the component stay in the React tree while its DOM is mounted somewhere else, usually under document.body.

What Portal solves

Portal is useful when:

  • A parent clips the overlay with overflow: hidden.
  • A parent creates a stacking context and z-index no longer wins.
  • A component inside a card needs to show a page-level modal.
  • A toast or command palette should live at the app shell level.

Portal separates ownership from DOM placement. State, Context, and React event behavior still follow the React component tree, but the actual DOM node can be outside the parent container.

Basic usage

import { createPortal } from "react-dom"

function Modal({ open, children }: { open: boolean; children: React.ReactNode }) {
  if (!open) return null

  return createPortal(
    <div className="modal-backdrop">
      <div className="modal-panel">{children}</div>
    </div>,
    document.body,
  )
}

Now Modal can be used inside any component, while the DOM is rendered under body.

When to use Portal

Good fits:

  • Global modal dialogs
  • Drawers and sheets
  • Toast notifications
  • Tooltips
  • Dropdown menus that escape clipping
  • Command palettes

Not every popup needs Portal. If a menu belongs inside a small local area and is not clipped, a normal component may be simpler.

Next.js and browser-only APIs

In Next.js, code that touches document.body must run in a Client Component or after the browser is available. A Portal component usually starts with "use client" because it needs browser DOM access and often handles events.

"use client"

import { createPortal } from "react-dom"

Keep the Portal boundary small. Do not make the entire page a Client Component just because the modal needs one.

Accessibility matters

Portal fixes DOM placement. It does not automatically make a modal accessible.

A modal should usually:

  • Move focus into the dialog when opened.
  • Restore focus when closed.
  • Support Escape to close when appropriate.
  • Provide an accessible title.
  • Prevent background content from being read or interacted with.
  • Lock background scroll for full-screen overlays.

For production UI, consider a well-tested dialog primitive rather than hand-rolling every focus behavior.

Portal and z-index

If a tooltip with z-index: 9999 is still hidden, the issue may be stacking context, not the number. Moving the overlay to a top-level Portal can change the comparison boundary.

For the CSS side, read Why z-index Fails: Understanding CSS Stacking Context.

Subscribe to FreeMac

Weekly picks: free Mac software reviews, trusted source updates, alternatives, and low-friction guides.