Using Portals for Modals and Tooltips in React

Table of Contents

  1. Introduction
  2. What are React Portals?
  3. Why Use Portals?
  4. Creating a Portal in React
  5. Building a Modal with Portals
  6. Tooltip Example Using Portals
  7. Accessibility Considerations
  8. Styling and Z-Index Handling
  9. Best Practices for Portals
  10. Portals in Frameworks and Libraries
  11. Conclusion

1. Introduction

In modern web applications, it’s common to use overlays like modals, tooltips, or dropdowns that visually break out of the DOM hierarchy. React’s default rendering model doesn’t support this well without a little help. That’s where React Portals come in—a powerful feature that allows you to render children into a DOM node that exists outside the main React component tree.


2. What are React Portals?

React Portals provide a way to render a component into a DOM node that’s not a direct descendant of its parent component. They allow for breaking out of the DOM hierarchy without breaking React’s component hierarchy.

React provides a built-in method:

jsCopyEditReactDOM.createPortal(child, container)

This renders the child into the container, which is typically a DOM node outside your root React app node.


3. Why Use Portals?

Some use cases demand elements that should visually appear on top of other elements or outside their parent containers, such as:

  • Modals and Dialog boxes
  • Tooltips and Popovers
  • Floating dropdowns
  • Global overlays and notifications

Without portals, these components may be clipped, hidden, or mispositioned due to CSS overflow or z-index limitations of their parent containers.


4. Creating a Portal in React

Let’s create a basic portal:

Step 1: Add a div outside your React root in index.html:

htmlCopyEdit<body>
  <div id="root"></div>
  <div id="portal-root"></div>
</body>

Step 2: Create a Portal component:

jsCopyEditimport ReactDOM from 'react-dom';

const Portal = ({ children }) => {
  const portalRoot = document.getElementById('portal-root');
  return ReactDOM.createPortal(children, portalRoot);
};

Now you can wrap any JSX inside the Portal component and it will render into the portal-root.


5. Building a Modal with Portals

Here’s a simple modal component:

jsxCopyEditconst Modal = ({ isOpen, onClose, children }) => {
  if (!isOpen) return null;

  return ReactDOM.createPortal(
    <div className="modal-backdrop">
      <div className="modal-content">
        <button onClick={onClose}>Close</button>
        {children}
      </div>
    </div>,
    document.getElementById('portal-root')
  );
};

Usage:

jsxCopyEdit<Modal isOpen={showModal} onClose={() => setShowModal(false)}>
  <h2>Hello from Modal</h2>
</Modal>

You can now build modals that render cleanly outside the main app hierarchy and are unaffected by container overflow or z-index.


6. Tooltip Example Using Portals

A tooltip might need to escape overflow constraints:

jsxCopyEditconst Tooltip = ({ text, position }) => {
  return ReactDOM.createPortal(
    <div className={`tooltip ${position}`}>{text}</div>,
    document.getElementById('portal-root')
  );
};

This makes sure your tooltip is positioned correctly even if the parent container has overflow: hidden.


7. Accessibility Considerations

When building modals or tooltips, accessibility must be a priority:

  • Use ARIA attributes like role="dialog" and aria-modal="true" for modals.
  • Trap focus inside modals using libraries like focus-trap-react.
  • Ensure keyboard navigation and ESC key support.

React Portals don’t automatically handle these; they just help with rendering structure.


8. Styling and Z-Index Handling

Portal content is often styled using fixed positioning:

cssCopyEdit.modal-backdrop {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0,0,0,0.5);
  z-index: 999;
}
.modal-content {
  background: white;
  padding: 20px;
  margin: auto;
}

Since portals render outside the component tree, z-index must be carefully managed so overlays appear correctly.


9. Best Practices for Portals

  • Always clean up event listeners and timers when using portals for modals.
  • Handle scroll locking on the background when modal is open.
  • Use React context or props to control visibility from parent components.
  • Keep portal logic in reusable components for consistency.

10. Portals in Frameworks and Libraries

Many component libraries use portals internally:

  • Material UI uses portals for Dialogs, Menus, Popovers.
  • Radix UI and shadcn/ui use portals to correctly render dropdowns and modals outside scrollable containers.
  • Headless UI‘s Popover and Dialog components also leverage portals.

This abstraction ensures UI elements work consistently regardless of nesting or styling.


11. Conclusion

React Portals are essential for building dynamic, layered UI components like modals and tooltips. They provide a clean solution for rendering outside the DOM hierarchy while staying within React’s component model.

By learning how portals work, and combining them with tools like focus management and z-index control, you’ll be equipped to build flexible, accessible, and reliable UI overlays in your React applications.