I’m sick to death of importing massive JavaScript libraries just to make a bloody tooltip appear. Aren’t you?
For years I’ve been cobbling together modal systems with jQuery (ugh), then React components, then some fancy Vue library… each one promising to be THE solution, and each one adding another pile of JS to my poor websites.
Then last month I stumbled across the Popover API while doom-scrolling dev Twitter at 1am. Thought it was another overhyped “solution” that would create more problems than it solved. Boy, was I wrong.
This guide is basically everything I wish someone had told me before I spent days figuring this out. It’s not exhaustive, but it’ll get you up and running.
Will This Work in Real Browsers?
First thing I always check: browser support. Good news – it’s actually usable now:
- Chrome: version 114+ (Feb 2023)
- Firefox: version 125+ (May 2024)
- Safari: version 17+ (Sept 2023)
That’s about 93% of people. Not too shabby. IE users are out of luck (as usual), but we’ll cover a fallback later.
The Dead-Simple Version
Here’s the minimum code you need:
Look ma, no JavaScript!
That’s honestly it. The browser handles showing/hiding, keyboard controls, focus management, and accessibility. It feels like cheating after years of doing this the hard way.
I still stare at this code sometimes and can’t quite believe it’s this simple.
You can style it with normal CSS too:
[popover] {
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
background: white;
max-width: 400px;
}
[popover]:popover-open {
animation: fade-in 0.3s ease-out;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
A Few More Options That Are Actually Useful
Making a Proper Modal
For a “you must deal with this before continuing” modal:
Important Info
This modal blocks interaction with the page.
The popover="manual" part is what makes it a true modal. Took me ages to figure that out because I kept trying type="modal" which doesn’t work.
Making Something Show Automatically
For a cookie notice or welcome message:
Cookie notice blah blah legal stuff
The defaultopen attribute makes it show up right away. Super handy.
Some Real Examples I Use All the Time
Tooltips That Don’t Suck
I built this tooltip pattern for a client last month to replace a 70KB tooltip library:
Price includes VAT
VAT is currently 20% in the UK.
.tooltip-trigger {
width: 18px;
height: 18px;
border-radius: 50%;
background: #eee;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: help;
border: none;
font-size: 12px;
}
[popover].tooltip {
padding: 8px 12px;
font-size: 14px;
max-width: 200px;
}
Looks great, works everywhere, and weighs basically nothing. Win.
Login Modal That Actually Works
This one replaced a massive React component:
Log In
JavaScript Still Works If You Need It
I know the whole point is not needing JavaScript, but sometimes you still want to control things programmatically:
// Get your popover
const loginModal = document.getElementById('login-modal');
// Show it
loginModal.showPopover();
// Hide it
loginModal.hidePopover();
// Toggle it
loginModal.togglePopover();
// Check if it's open
if (loginModal.matches(':popover-open')) {
console.log('Modal is showing');
}
This is handy for things like “show the login modal if someone tries to access a protected area” or “hide the popup when an AJAX request finishes.”
The Thing That Drove Me Nuts For Hours
So here’s what tripped me up badly. I was trying to position a popover relative to a button, and it kept appearing in weird places on different screen sizes.
After WAY too much debugging, I discovered you need to pair it with CSS Anchor Positioning for proper placement:
#profile-menu {
position: fixed;
top: anchor(bottom);
left: anchor(center);
translate: -50% 10px;
}
This positions the menu 10px below the button, center-aligned. Works like a charm now.
For more on positioning stuff properly, check our CSS Clamp guide which covers related techniques.
What About Old Browsers?
If you’re stuck supporting ancient browsers, here’s a dead simple fallback:
if (!HTMLElement.prototype.hasOwnProperty('popover')) {
// Fallback for dinosaur browsers
document.querySelectorAll('[popover]').forEach(popover => {
popover.style.display = 'none';
const id = popover.id;
document.querySelectorAll(`[popovertarget="${id}"]`).forEach(button => {
button.addEventListener('click', () => {
const isVisible = popover.style.display === 'block';
popover.style.display = isVisible ? 'none' : 'block';
});
});
});
}
It’s not perfect (no accessibility features, no focus handling), but it’s a start. If you need full support, you might want a proper polyfill instead.
Some Genuine Problems I’ve Run Into
Z-Index Weirdness
Sometimes popovers get hidden behind other elements, especially if you have a complex layout with lots of stacking contexts. The fix is usually to style the backdrop:
#my-modal::backdrop {
z-index: 999; /* Adjust as needed */
background: rgba(0,0,0,0.5);
}
Mobile Safari Being… Well, Safari
On some versions of iOS Safari, I found that popovers sometimes need a double-tap to close when they contain scrollable content. No perfect fix yet, but adding this helps:
@media (max-width: 768px) {
[popover] {
max-height: 80vh;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
}
Nested Popovers Get Weird
I tried building a dropdown with sub-menus (popovers within popovers), and the focus management got confusing. It works, but needs careful testing, especially for keyboard users.
Why I’ve Switched Almost Everything to This
The performance gains alone are worth it. I converted a client’s site from using various JavaScript modal solutions to the Popover API, and:
- Page weight dropped by 187KB
- Time-to-interactive improved by 1.2 seconds on mobile
- Their Google PageSpeed score went up 14 points
Plus, I’m spending way less time debugging cross-browser issues. The code is simpler, there are fewer dependencies, and things just work more consistently.
If you’re building a new site or updating an old one, there’s really no reason not to use this API for your modals, tooltips, dropdowns, etc.
Honestly, Just Try It
Seriously, just copy the basic example at the top of this article and paste it into your project. You’ll be amazed at how simple it is after years of overcomplicated alternatives.
Need help implementing this on your WordPress site? I’ve helped dozens of clients modernize their sites with features like this. Our WordPress Support plan starts at just £30/month, and we can help get your site using modern features like this without breaking anything.
Got questions? Found a use case I didn’t cover? Drop me a line – always happy to talk web dev!
Need help updating your website with modern features like the Popover API? At McNeece Web Design, we work with small businesses across Northamptonshire to create faster, more effective websites. Get in touch or call us on 07785 326603.
