Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified public/og-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/og/checklist.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/og/spec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/og/spec/foundations.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/og/spec/foundations/anchor-positioning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/content/changelog/2026-06-24-anchor-positioning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: New page on CSS anchor positioning
date: "2026-06-24"
type: added
relatedSlugs: [anchor-positioning]
---

Added a page on [CSS anchor positioning](/spec/foundations/anchor-positioning/) — the `anchor-name`, `position-anchor`, and `position-area` mechanism (CSS Anchor Positioning Module Level 1) that tethers tooltips, menus, and popovers to their trigger with no JavaScript, working across overflow and stacking boundaries. It became Baseline newly available in early 2026 and pairs with the [Popover API](/spec/foundations/popover-api/).
86 changes: 86 additions & 0 deletions src/content/spec/foundations/anchor-positioning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: "CSS anchor positioning"
slug: anchor-positioning
category: foundations
summary: "Tether tooltips, menus, and popovers to the element that triggers them with pure CSS — no JavaScript positioning library, and it works across overflow and stacking boundaries."
status: recommended
order: 140
appliesTo: [all]
relatedSlugs: [popover-api, native-interactive-elements, scroll-driven-animations]
updated: "2026-06-24T00:00:00.000Z"
sources:
- title: "CSS Anchor Positioning Module Level 1"
url: "https://drafts.csswg.org/css-anchor-position-1/"
publisher: "W3C CSS Working Group"
- title: "MDN — Using CSS anchor positioning"
url: "https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning/Using"
publisher: "MDN"
- title: "MDN — anchor-name"
url: "https://developer.mozilla.org/en-US/docs/Web/CSS/anchor-name"
publisher: "MDN"
- title: "Introducing the CSS anchor positioning API"
url: "https://developer.chrome.com/blog/anchor-positioning-api"
publisher: "Chrome for Developers"
---

## What it is

CSS anchor positioning lets one element be positioned relative to another — its _anchor_ — without the two sharing a parent or a containing block. You name an anchor, associate a positioned element with it, and place that element against the anchor's edges using CSS alone.

Three pieces do the work:

- `anchor-name: --trigger` registers an element as a named anchor.
- `position-anchor: --trigger` on an absolutely (or fixed) positioned element associates it with that anchor.
- The `anchor()` function and the `position-area` property place the element against the anchor's edges.

```css
.trigger {
anchor-name: --trigger;
}

.tooltip {
position: absolute;
position-anchor: --trigger;
position-area: top center; /* sit above, centred on the anchor */
margin-bottom: 0.5rem;
}
```

`anchor-size()` sizes an element from its anchor's dimensions (a dropdown panel as wide as its button), and `@position-try` plus `position-try-fallbacks` let the element flip to a different side when it would overflow the viewport.

## Why it matters

- **No JavaScript positioning library.** Tooltips, menus, comboboxes, and popovers have historically needed scripts (or Popper/Floating UI) to measure the trigger and reposition on scroll and resize. The browser now does this natively, every frame.
- **It crosses boundaries.** Anchor positioning works regardless of `overflow: hidden` ancestors, `z-index`, or `transform` containing blocks — the same constraints that break hand-rolled overlays. It pairs naturally with [the Popover API](/spec/foundations/popover-api/) and top-layer elements.
- **Viewport-aware by default.** `@position-try` gives you fallback positions, so an overlay that would clip off-screen flips to a side that fits — behaviour you previously wrote and maintained by hand.

## How to implement

Use it to position non-blocking UI relative to its trigger. Treat it as progressive enhancement: give the element a sensible static position first, then layer anchor positioning on top.

```css
@supports (anchor-name: --x) {
.menu {
position: absolute;
position-anchor: --menu-button;
position-area: bottom span-right;
position-try-fallbacks: flip-block, flip-inline;
}
}
```

`position-try-fallbacks` lists alternatives the browser tries in order until the element fits. `position-visibility: anchors-visible` hides the element when its anchor scrolls out of view, so a detached tooltip does not linger.

## Common mistakes

- **Forgetting to position the element.** `position-anchor` and `anchor()` only apply to an element with `position: absolute` or `fixed`. Without it, nothing moves.
- **No fallbacks.** An anchored element with a single fixed side will overflow the viewport near screen edges. Provide `position-try-fallbacks`.
- **Making it the only mechanism.** Until anchor positioning is universally available, keep a usable static fallback for browsers without support rather than leaving the overlay unpositioned.
- **Anchoring across documents.** Anchor and anchored element must be in the same document and not separated by certain layout containers — check the association actually resolves.

## Verification

- `@supports (anchor-name: --x)` gates the enhancement; confirm the fallback layout is acceptable on its own.
- In DevTools, inspect the anchored element and confirm its inset values resolve against the anchor.
- Scroll and resize the viewport: the element should follow its anchor and flip via fallbacks rather than clipping.
- Baseline: CSS anchor positioning became newly available across browsers in early 2026 — verify your target support before relying on it without a fallback.
4 changes: 2 additions & 2 deletions src/content/spec/foundations/popover-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ summary: "Replace ARIA-puzzled JavaScript modals, menus, and tooltips with a nat
status: recommended
order: 130
appliesTo: [all]
relatedSlugs: [semantic-html, aria-usage, keyboard-navigation, focus-indicators]
relatedSlugs: [semantic-html, aria-usage, keyboard-navigation, focus-indicators, anchor-positioning]
updated: "2026-06-08T00:00:00.000Z"
sources:
- title: "HTML Standard — Popover"
Expand Down Expand Up @@ -45,7 +45,7 @@ The Popover API turns any element into a top-layer overlay using three HTML attr

The `auto` value gives you light-dismiss (click outside to close) and auto-close on Escape. `manual` requires an explicit dismiss control. `hint` is for tooltip-style transient overlays that close when another `hint` opens.

CSS hooks: `:popover-open` matches an open popover, `::backdrop` styles the layer behind it, and CSS **Anchor Positioning** (`position-anchor`, `anchor()`) can position a popover relative to its trigger where supported.
CSS hooks: `:popover-open` matches an open popover, `::backdrop` styles the layer behind it, and [CSS **Anchor Positioning**](/spec/foundations/anchor-positioning/) (`position-anchor`, `anchor()`) can position a popover relative to its trigger where supported.

## Why it matters

Expand Down
Loading