a-portal
An element that teleports its content to a different location in the DOM, typically the document body.
The a-portal element renders its children at a different location in the DOM tree, typically at the end of document.body. This is essential for elements that need to break out of their parent's stacking context, overflow constraints, or z-index limitations.
Used internally by Popover, Dialog, and Sheet.
Usage
Basic Usage
Content placed inside the portal will be rendered at the document body:
<div class="container">
<a-portal>
<div class="tooltip">
This content is rendered at document.body
</div>
</a-portal>
</div>
Escaping Overflow Hidden
A common use case is rendering tooltips or dropdowns from within containers that have overflow: hidden:
<div style="overflow: hidden; height: 100px;">
<p>Some content...</p>
<a-portal>
<div class="dropdown-menu">
<!-- This menu won't be clipped by the parent's overflow -->
<button>Option 1</button>
<button>Option 2</button>
</div>
</a-portal>
</div>
Z-Index Stacking Context
Portals help escape stacking context limitations:
<div style="position: relative; z-index: 1;">
<a-portal>
<div class="modal" style="z-index: 1000;">
<!-- This modal renders above everything because it's at body level -->
</div>
</a-portal>
</div>
Cleanup Behaviour
The portal automatically cleans up its rendered content when removed from the DOM:
const portal = document.querySelector('a-portal');
// Content is rendered at document.body
document.body.appendChild(portal);
// Content is removed from document.body
portal.remove();
How It Works
- When the portal is connected to the DOM, it creates a container element at
document.body - The portal's children are moved into this container
- The original portal element renders nothing
- When disconnected, the container is removed from the body
<!-- Before portal connects -->
<body>
<div class="parent">
<a-portal>
<div class="content">Hello</div>
</a-portal>
</div>
</body>
<!-- After portal connects -->
<body>
<div class="parent">
<a-portal></a-portal>
</div>
<div>
<div class="content">Hello</div>
</div>
</body>
Styling Portaled Content
Since content is moved to the body, it may lose inherited styles. Be explicit with your styling:
/* Won't work - portal content isn't a child anymore */
.parent a-portal .content {
color: red;
}
/* Use direct selectors instead */
[data-portal] .content {
color: red;
}
Accessibility
The portal by itself does not affect accessibility. Ensure that any interactive content within the portal is properly labeled and focusable.
When to Use Portals
- Modal dialogs and sheets
- Tooltips and popovers
- Dropdown menus
- Any overlay that needs to escape parent constraints
Portal
The a-portal element is used to render elements (its children) in a different location in the DOM. Most frameworks have their own primitives for this. Vue has Teleports, React has createPortal and Solid as well calls it Portal.
Example
<a-portal>
<div>
Content rendered over the page
</div>
</a-portal>