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>
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>
Clicking the info button toggles the popover visibility, and clicking outside closes it. This initial implementation results in a more modal-style element.
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>
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>
.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%);
}
which results in:
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)
Love what the modern APIs allow us to achieve! Can't wait for the next post ✊
Thanks!
I'm also waiting to new css features getting baseline support!