How to position a tooltip next to a button with anchor positioning
Short answer
Give the button an anchor name, and give the tooltip a reference to it and the side to sit on:
<style>
.btn { anchor-name: --save; margin: 48px 16px 8px; }
.tip { position: absolute; position-anchor: --save; position-area: top; margin-bottom: 6px;
padding: 4px 8px; border-radius: 4px; background: #222; color: white; font: 12px system-ui;
opacity: 0; transition: opacity 0.2s; }
.btn:hover + .tip, .btn:focus-visible + .tip { opacity: 1; }
</style>
<button class="btn">Save</button>
<span class="tip">Saved to your list</span>anchor-name declares an anchor (the name starts with two dashes), position-anchor links an absolutely positioned element to it, and position-area: top places the tooltip above the anchor, centered. The tooltip does not have to be inside the button, and the parent needs no position: relative.
A click tooltip in a popover
A popover is shown in the top layer above everything, and overflow: hidden on parents does not clip it. The anchor sets the place:
<style>
.help { anchor-name: --help; margin: 8px 16px 64px; }
#hint { position-anchor: --help; position-area: bottom span-right; inset: auto; margin: 6px 0 0;
padding: 8px 12px; border: 1px solid #ccc; border-radius: 6px;
position-try-fallbacks: flip-block; }
</style>
<button class="help" popovertarget="hint">What is this?</button>
<div id="hint" popover>Your list is saved for 30 days.</div>inset: auto and margin cancel the default centering of a popover. position-try-fallbacks: flip-block moves the tooltip above when there is not enough room below.
Exact coordinates with anchor()
Instead of position-area you can set individual sides: top: anchor(bottom); left: anchor(left); — the top of the tooltip meets the bottom of the button, and the left edges line up.
Common mistake
Forgetting browsers without support. Anchor positioning is recent, and in older browsers the tooltip lands in the corner of the page. Wrap the rules in @supports (anchor-name: --a) and keep simple positioning with position: relative on a wrapper for the rest.
Functions used in this recipe
- anchor-name — Names an element as an anchor, so that an absolutely positioned element anywhere on the page can be placed next to it.
- position-anchor — Chooses the default anchor for an absolutely or fixed positioned element; `position-area` and `anchor()` then measure from it.
- anchor() — Returns the position of a side of the anchor element; used in `top`, `left`, `right`, `bottom` to attach an element to it.
- popover — Turns an element into a layer that pops up over the page — without JavaScript.
- position — How an element is positioned: in the normal flow or by offsets.