What's a Portal?
You might have never heard of the HTML <portal>
element. It's an experimental feature since Chrome 75 (June, 2019) and its proposal is in the draft stages. But what is it exactly? Essentially the <portal>
is like a souped-up <iframe>
and includes the ability to seamlessly navigate into embedded content.
Similar to an <iframe>
, <portal>
includes a src
attribute which is the URL of the page you want to embed and the embedded content will look identical to an <iframe>
. The <portal>
is clickable but is not interactable since its purpose is to provide a smooth navigation into a prerended page - similar to the way most SPAs navigate. This differs from iframes which cannot immediately be navigated to without another request to the source. Clicking on a portal will navigate you right into all that content that's already loaded and rendered as the child inset of the parent document.
What's cool about portals is that they can be cross-origin, meaning you can create a portal to a different domain from where you're embedded it.
How To Use
So since portals are an experimental, we need to enable 2 flags in Chrome at about://flags/#enable-portals
:
- 🚩 Enable Portals
- 🚩 Enable cross-origin Portals
Chrome will prompt you to relaunch your Browser and after doing so, you should see the HTMLPortalElement
function available in your console:
So now let's create a basic portal! It's as easy as adding this HTML to your web page.
<portal src="https://theoatmeal.com"></portal>
You can add styles to this element to adjust height, width, etc. but in its raw form you'll see the webpage from The Oatmeal embedded. When you click the portal, you navigate instantly to the source page and should not notice the normal "blink" you'd otherwise get from visiting a new Web page.
Let's Get Fancy
Here's a use case where we'll create a list of popular webcomics. Each block of content will show a preview image of the comic and when the user hovers over it our code will render a portal in place that can be clicked to navigate directly to the the webcomic's page:
First, the HTML:
<h2>Best Webcomics</h2>
<ol>
<li>
<h3>The Oatmeal</h3>
<div
class="comic-container"
data-src="https://theoatmeal.com/comics/forbidden_love"
>
<img src="/forbidden_love_big.png">
<img class="spinner" src="/spinner.gif">
<portal src=""></portal>
</div>
</li>
<!-- Repeat lis for other webcomics -->
</ol>
Notice we're using an empty src
for the portal. To avoid unnecessary loading, we'll set the source in JavaScript only when the user hovers over .comic-container
via the mouseenter
event. As the source is being loaded, we'll show the spinner overlay so there's user feedback to show something is loading. Once fully loaded (by listening to the load
event), we can display the portal over the existing image.
const blocks = document.querySelectorAll('.comic-container');
blocks.forEach(block => {
block.addEventListener('mouseenter', e => {
block.classList.add('hover');
const portal = block.querySelector('portal');
const { src } = block.dataset;
portal.src = src;
});
// Add "mouseleave" listener to reset classes
});
const portals = document.querySelectorAll('portal');
portals.forEach(portal => {
portal.addEventListener('load', e => {
if (portal.closest('.comic-container').matches('.hover')) {
portal.classList.add('show-portal');
}
});
});
From there, the user can click the portal and be instantly transported to the source page!
The default click behavior on a portal can also be prevented if you wanted to create a fancy animation the on click event and then call portal.activate()
to activate the portal programmatically.
See full code here: https://github.com/doctafaustus/html-portal
Closing Thoughts
While portals give us a new way to preview and prerender pages, it's unclear if they'll ever be standard in browsers. My first thoughts about security were assuaged by reading that portals do not allow user interaction to channel through to the "portaled" document. Additionally, the embedded content will not have direct access to the host document. However, portals would still introduce yet another opportunity to create clever browser exploits, so a sound content security policy (CSP) would be recommended.
Nevertheless, they're still pretty cool!
Yo! I post byte-sized tips like these often. Follow me if you crave more! 🍿
I'm on Twitter, TikTok and I have a new debugging course out now!
Top comments (2)
Oh man, this get's me hyped to try it out 🤯
You should!