CSS anchor names start with two dashes, so tip becomes --tip. Using --anchor.
Click the button in the preview to open the positioned element. The frame is fully sandboxed: it runs no script and makes no request.
<!-- HTML: the anchor comes first, the positioned element second. --> <button type="button" class="anchor-trigger" popovertarget="anchor-tooltip">Show tooltip</button> <div id="anchor-tooltip" class="anchor-tooltip" popover> Tooltip text </div>
/* 1. Name the anchor. Any element can carry an anchor name. */
.anchor-trigger {
anchor-name: --anchor;
}
/* 2. Tether the tooltip to that anchor. */
.anchor-tooltip {
position: fixed;
position-anchor: --anchor;
position-area: top;
/* The popover UA styles set inset: 0 and margin: auto. Both have to go. */
inset: auto;
margin: 8px;
width: max-content;
max-width: 30ch;
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
/* Hide the element once the anchor scrolls out of view. Newer than the rest, so check support. */
position-visibility: anchors-visible;
/* Cosmetics only. Replace these with your own styles. */
--anchor-surface: #1f2937;
background: var(--anchor-surface);
color: #ffffff;
border: 0;
border-radius: 6px;
padding: 6px 10px;
font: inherit;
}
/* Fallback for browsers without CSS anchor positioning. The guard is true
only where anchor-name is understood, so this block is the else branch. */
@supports not (anchor-name: --a) {
/* A popover lives in the top layer, so no ancestor can position it.
Without anchor positioning the honest fallback is the browser's own
centered placement, or a JavaScript positioner such as Floating UI. */
.anchor-tooltip {
inset: 0;
margin: auto;
}
}
/* Notes
Pattern: tooltip. Placement: position-area: top.
A single position-area keyword such as top or bottom spans the whole other
axis, so the element stays centered on the anchor even when it is wider than it.
popover="auto" toggles on click. Newer Chromium also has popover="hint",
which is aimed at tooltips and does not close other open popovers.
anchor() reads one edge of the anchor and anchor-size() reads its box, so
things like top: anchor(bottom) or min-width: anchor-size(width) work anywhere
a length is allowed.
Repeating this component in a list? Add anchor-scope to keep each copy's
anchor-name from leaking to its siblings.
Chrome 125 and later: anchor-name, position-anchor, position-area, position-try-fallbacks, and @position-try all work. The property was called inset-area before Chrome 129.
Edge 125 and later: same engine as Chrome, so the same support.
Safari 26: partial support. Test the newer pieces (position-visibility, position-try-order) on a real device before you rely on them.
Firefox: still behind a flag as of 2025, so treat anchor positioning as progressive enhancement rather than a hard dependency.
Support numbers move every few months. Check caniuse.com/css-anchor-positioning before you ship.
*/Browser support notes
- Chrome 125 and later: anchor-name, position-anchor, position-area, position-try-fallbacks, and @position-try all work. The property was called inset-area before Chrome 129.
- Edge 125 and later: same engine as Chrome, so the same support.
- Safari 26: partial support. Test the newer pieces (position-visibility, position-try-order) on a real device before you rely on them.
- Firefox: still behind a flag as of 2025, so treat anchor positioning as progressive enhancement rather than a hard dependency.
- Support numbers move every few months. Check caniuse.com/css-anchor-positioning before you ship.
Every result ends with an @supports block, so a browser without anchor positioning still places the element somewhere sensible.
Related tools
- Box Shadow GeneratorStack multiple CSS box-shadow layers visually, preview them on light and dark, and copy the CSS or the Tailwind value.
- CSS Keyframes BuilderBuild @keyframes animations on a visual timeline, preview them live, and copy the CSS with a reduced motion guard.
- Clip Path GeneratorDrag shape handles over your own image and copy the matching CSS clip-path or SVG path.
- Cubic Bezier Easing EditorDrag the control points of a CSS easing curve, watch it animate, and copy the cubic-bezier or linear() value.
- Fluid Clamp CalculatorTurn a min and max size into a responsive CSS clamp() expression, with a preview at six viewport widths.
- CSS Gradient GeneratorBuild linear, radial, and conic CSS gradients visually, pick the interpolation color space, and copy the CSS.
What it does
Generates the HTML and CSS for an element tethered to another element with CSS anchor positioning, the browser feature that replaces a JavaScript positioning library for tooltips, dropdown menus, and popovers. The output wires up anchor-name on the trigger, position-anchor and position-area on the positioned element, position-try-fallbacks so it flips instead of overflowing the viewport, and position-visibility so it disappears when the anchor scrolls away. Optional extras include an arrow drawn with the anchor() function, a named @position-try rule, anchor-size() sizing for menus, and the popover attribute so the whole thing works without a line of script. Every result ends with an @supports guard holding a plain-CSS fallback for browsers that do not understand anchor positioning yet.
How to use it
Pick a pattern, then a placement on the nine region grid around the anchor. Type an anchor name in the input if you want something other than --anchor: a bare name like tip becomes --tip, since CSS anchor names must start with two dashes. Turn on the arrow, the flip fallbacks, or the logical keywords as needed, then copy the HTML block into your markup and the CSS block into your stylesheet.
Why this one
Most anchor positioning examples online were written against the pre-Chrome 129 syntax and still say inset-area, which no current browser accepts, so copying them silently does nothing. This builder emits the current property names, keeps the popover user agent styles from fighting your placement, and always ships the @supports fallback that tutorials leave out. It also runs entirely in the page, so your files and inputs never leave your device.
FAQ
- Which browsers support CSS anchor positioning?
- Chrome and Edge 125 and later have it, with the position-area spelling from version 129 on. Safari 26 has partial support, and Firefox is still behind a flag as of 2025. Because the numbers move every few months, check caniuse.com/css-anchor-positioning before you ship, and keep the @supports fallback that this tool generates so unsupporting browsers still place the element somewhere sensible.
- Why does my example use inset-area instead of position-area?
- inset-area was the original name while the feature was being developed. The CSS Working Group renamed it to position-area, and Chrome made the switch in version 129, dropping inset-area entirely. Articles and Stack Overflow answers written in 2024 still use the old name, so a copied snippet does nothing at all in a current browser. This tool only emits position-area.
- How do I add an arrow that points at the anchor?
- Turn on the arrow option. It emits an ::after pseudo-element drawn as a CSS triangle, positioned with anchor() so one edge sits exactly on the anchor's edge, and with anchor-center so it lines up with the middle of the anchor rather than the middle of the box. It also sets overflow: visible on the positioned element, because the popover user agent stylesheet sets overflow: auto and would otherwise clip the arrow away.
Keyboard shortcuts: press ? anywhere on this page to see them.