Putty Ssh
📖 Tutorial

How to Build a Tooltip with the Native Popover API (No Library Needed)

Last updated: 2026-05-01 04:05:36 Intermediate
Complete guide
Follow along with this comprehensive guide

Introduction

Tooltips are a common UI element, but building one that works seamlessly across mouse, keyboard, and screen readers has traditionally required heavy JavaScript libraries. The Popover API, now supported in modern browsers, offers a native way to create tooltips without external dependencies. This guide walks you through rebuilding a simple tooltip using the Popover API, eliminating the complexity of manual event handling and ARIA attribute syncing.

How to Build a Tooltip with the Native Popover API (No Library Needed)
Source: www.smashingmagazine.com

What You Need

  • A modern browser (Chrome, Edge, Firefox 125+, Safari 17+) that supports the Popover API
  • A basic HTML file to work in
  • A text editor (VS Code, Sublime, or any code editor)
  • Basic knowledge of HTML, CSS, and JavaScript (minimal)

Step-by-Step Guide

Step 1: Set Up the Trigger and Tooltip Elements

Start with two HTML elements: one that triggers the tooltip (e.g., a button) and one that contains the tooltip content. The trigger must be interactive, like a <button> or <a>, to ensure keyboard accessibility.

<button class="info-trigger" popovertarget="my-tooltip">?</button>
<div id="my-tooltip" popover role="tooltip">Helpful text here</div>

Here, the popovertarget attribute on the button links to the tooltip's id. The popover attribute on the <div> tells the browser this element is a popover.

Step 2: Control Visibility with popovertargetaction

By default, clicking the trigger toggles the popover. For a tooltip that shows on hover or focus, you'll need to override the default toggle behavior using JavaScript. But for a basic click-to-show tooltip, the previous step is enough. However, to follow the tooltip pattern (show on hover/focus), we'll add JavaScript in Step 4.

If you want a toggle button, you can set popovertargetaction="toggle" (the default). For a show-only button, use show; for hide-only, use hide.

Step 3: Style the Tooltip with CSS

The Popover API automatically places the tooltip in the top layer, above other content. You can style it with CSS, but be aware that the browser may adjust positioning to avoid clipping. Use ::backdrop pseudo-element if needed for overlays.

[popover] {
  background: #333;
  color: #fff;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  font-size: 0.875rem;
  max-width: 250px;
}

For a tooltip, you may want to remove the default display: none behavior by using the :popover-open state.

[popover]:not(:popover-open) {
  display: none;
}
[popover]:popover-open {
  display: block;
}

But the API handles visibility, so you can just rely on CSS for styling rather than display control.

Step 4: Add JavaScript for Hover/Focus Behavior (Optional but Recommended for Tooltips)

To replicate the classic tooltip that appears on hover or focus and hides on blur or mouse leave, use JavaScript to call showPopover() and hidePopover() on the tooltip element. Attach event listeners to the trigger.

const trigger = document.querySelector('.info-trigger');
const tooltip = document.getElementById('my-tooltip');

function showTooltip() {
  tooltip.showPopover();
}

function hideTooltip() {
  tooltip.hidePopover();
}

trigger.addEventListener('mouseenter', showTooltip);
trigger.addEventListener('mouseleave', hideTooltip);
trigger.addEventListener('focus', showTooltip);
trigger.addEventListener('blur', hideTooltip);

Note: The browser already provides focus management when the popover is opened, but additional ARIA attributes may be needed for screen readers (see Step 6).

How to Build a Tooltip with the Native Popover API (No Library Needed)
Source: www.smashingmagazine.com

Step 5: Handle Keyboard and Dismissal

The Popover API automatically dismisses the tooltip when the user presses the Esc key or clicks outside the tooltip. This is a major advantage over custom implementations. You can also use the beforetoggle event to perform actions when the popover is about to open or close.

tooltip.addEventListener('beforetoggle', (event) => {
  if (event.newState === 'open') {
    console.log('Tooltip is opening');
  }
});

Step 6: Ensure Accessibility

Even with the Popover API, you must add proper ARIA roles and relationships. Use role="tooltip" on the popover element and aria-describedby on the trigger pointing to the tooltip's ID. This helps screen readers announce the tooltip when it appears.

<button class="info-trigger" popovertarget="my-tooltip" aria-describedby="my-tooltip">?</button>
<div id="my-tooltip" popover role="tooltip">Helpful text</div>

Also, ensure the tooltip content is brief and useful. Test with keyboard navigation (Tab key) and a screen reader (e.g., VoiceOver, NVDA) to verify it works.

Tips

  • Check browser support regularly. The Popover API is still evolving. Monitor Can I Use for updates.
  • Keep it simple. The beauty of the API is that it handles many edge cases (Esc key, outside click, focus management) out of the box. Don't add unnecessary JavaScript.
  • Positioning is tricky. The browser decides where to place the popover to keep it visible. For absolute control, consider using a positioning library like Floating UI, but test without it first.
  • Use :popover-open for animations. You can animate the opening/closing with CSS transitions or the ::backdrop pseudo-element for overlays.
  • Don't rely solely on hover. Always provide a click or focus trigger for mobile users and those with motor disabilities.
  • Test with real users. A tooltip that works technically may still be confusing. Keep text short and avoid essential information in tooltips.

By using the Popover API, you reduce hundreds of lines of custom JavaScript to just a handful. The browser handles the heavy lifting, letting you focus on styling and content. Start building your first native tooltip today!