DEV Community

Cover image for CSS-only tooltip using popover & anchor
Reuven Hozias
Reuven Hozias

Posted on • Edited on

CSS-only tooltip using popover & anchor

To improve performance in a project I'm working on, I'm refactoring some components and replacing them with more native implementations.
In this post, I will start with a component that we use widely: the tooltip. I will use two relatively new features: the Popover API and Anchor CSS.

Popover API and Anchor CSS:

The Popover API provides developers with a standard, consistent, flexible mechanism for displaying popover content on top of other page content. Popover content can be controlled declaratively using HTML attributes or JavaScript.

The anchor() CSS function can be used within an anchor-positioned element's inset property values, returning a length value relative to the position of the edges of its associated anchor element.

🤔

Our baseline

Let's start with a basic info icon that will serve as our tooltip opener,
Nothing fancy here:

<button class="info-icon"></button>
Enter fullscreen mode Exit fullscreen mode

The Popover API

We're adding an information div, marking it as a popover and passing a unique id to it. popovertarget property is added to the icon, excepting the popover id string.
note that popovertarget can be only of type button or input:

<button popovertarget="info" class="info-icon"></button>
<div id="info" popover>Lorem ipsum dolor sit amet</div>
Enter fullscreen mode Exit fullscreen mode

Clicking the info button toggles the popover visibility, and clicking outside closes it. This initial implementation results in a more modal-style element.

Image description

Let's go one step further, and position the tooltip using the anchor CSS.

Adding anchor CSS

The anchor CSS is still experimental but getting adopted quickly by all major browsers:

All major browser engines are working on implementing this spec.
Can be enabled via the #enable-experimental-web-platform-features flag in chrome://flags

We'll add the anchor property to our info div. It expects a string id of the element we're anchoring to:

<button id="info-opener"
        popovertarget="info"
        class="info-icon"></button>
<div id="info" popover="auto" anchor="info-opener">
  Lorem ipsum dolor sit amet
</div>
Enter fullscreen mode Exit fullscreen mode

Placing the tooltip

To position the target tooltip beside the anchor (info icon), we'll use the anchor() CSS:

<button id="info-opener"
        popovertarget="info"
        class="info-icon"></button>
<div id="info"
     popover="auto"
     anchor="info-opener" class="info-tooltip left">
  Lorem ipsum dolor sit amet
</div>
Enter fullscreen mode Exit fullscreen mode
.left {
  padding-left: .75rem;
  clip-path: polygon(
    100% 0%,
    100% 100%,
    5px 100%,
    5px calc(50% + 5px),
    0% 50%,
    5px calc(50% - 5px),
    5px 0%
  );
}

.info-tooltip[popover] {
  background: #007bff;
  color: #fff;
}

.info-tooltip[popover] {
  left: calc(anchor(right) + 2px);
  top: anchor(center);
  transform: translateY(-50%);
}
Enter fullscreen mode Exit fullscreen mode

which results in:

Image description

Breaking it down

The .info-tooltip class styles the element and adds anchor-like functionality.

What does this anchoring do? It attaches the tooltip to a logical grid cell—one of a 3 by 3 grid representing our info element.

The left property aligns the tooltip's left side with the info element's right side, adding 2px of space. The top property centers the tooltip vertically to the tooltip's midpoint.

Some extras

The popover property accepts two values:

  • auto: This is the default behavior. Click anywhere on the page to
  • toggle: the popover visibility.
  • manual: Toggles the visibility only by clicking the opener element.

Another property that can be utilized from the opener element is popoverTargetAction:

  • toggle: This is the default action— as the name implies, it toggles the visibility.
  • show: Only triggers showing the popover; you can’t close it.
  • hide: Only hides the popover.

Conclusion

We briefly covered two relatively new features: the Popover API and the CSS anchor() feature. Both are extremely powerful and combining them can enable amazing, JavaScript-free functionality.

As mentioned, both are relatively new. The Popover API has wide browser support and can be safely used. The anchor() feature, on the other hand, is still experimental and is not yet recommended for use in production environments.

Next up

In upcoming posts, I’ll demonstrate more advanced usage of these features. Stay tuned!

Top comments (2)

Collapse
 
andreasvirkus profile image
ajv

Love what the modern APIs allow us to achieve! Can't wait for the next post ✊

Collapse
 
hreuven profile image
Reuven Hozias

Thanks!
I'm also waiting to new css features getting baseline support!