---
title: "CSS Anchor Positioningの使い方｜position-area・@position-tryと対応ブラウザ"
url: "https://www.issoh.co.jp/tech/details/10692/"
published: 2026-01-22
updated: 2026-11-11
categories: ["開発"]
publisher: "株式会社一創"
---

# CSS Anchor Positioningの使い方｜position-area・@position-tryと対応ブラウザ

CSS Anchor Positioning（アンカーポジショニング）は、ある要素（アンカー）の位置と大きさを基準に、別の要素をCSSだけで配置する仕組みです。ツールチップ、ドロップダウン、入力欄の横に出すエラーメッセージなど、これまで`getBoundingClientRect()`とスクロール監視のJavaScriptで追従させていたUIを、宣言だけで書けます。Chrome・Edge 125（2024年5月）、Safari 26（2025年9月）、Firefox 147（2026年1月13日）で主要3エンジンがそろいました。この記事では、最小コードから画面端のはみ出し対策、Chrome 157で動かして確認した「効かない」原因、ポリフィルで補えない機能までを順に扱います。本文の実測値は、Chrome 157.0.8103.40（macOS・ヘッドレス実行・表示領域800×600px）で各コードを動かし、要素の座標を`getBoundingClientRect()`で読み取ったものです。

## まとめ：CSS Anchor Positioningの要点

- アンカー側に`anchor-name: --名前`、配置する側に`position: absolute`（または`fixed`）と`position-anchor: --名前`を書けば結びつきます。
- 置き場所は`position-area: top`のような9分割グリッドのキーワードで指定するのが最短です。辺単位で細かく合わせたいときは`top: anchor(bottom)`のように`anchor()`を使います。
- 画面端で隠れる問題は`position-try-fallbacks: flip-block`で反転させます。指定しないと、Chrome 157ではツールチップが画面内へ押し戻されてアンカーに重なりました。
- 同じ`anchor-name`を一覧の各行に付けると、Chrome 157ではすべての配置要素が最後の行に付きます。行ごとに付けたいなら親に`anchor-scope`を指定します。
- 主要機能はFirefox 147が出た2026年1月13日にBaseline（新たに利用可能）になりました。`position-try-order`はFirefox 148から使えます。
- popoverには`position-anchor: auto`を書いておきます。初期値`normal`のままだと、`anchor()`だけで置いたpopoverはChrome 157で暗黙アンカーを使わず、初期値が`none`だったChrome 144〜150では`position-area`でも付きません。
- Chrome 124以前などの非対応環境には`@oddbird/css-anchor-positioning`（0.10.2）がありますが、`position-try-order`・`anchor-center`・`position-visibility`・popoverの暗黙アンカーは補えません。

## CSS Anchor Positioningの仕組みと最小コード

登場するのは2つの要素です。基準になる**アンカー要素**と、アンカーに合わせて置かれる**配置要素**（anchor-positioned element）です。配置要素は絶対配置（`absolute`か`fixed`）でなければならず、通常のフローにある要素はアンカーに追従しません。

### anchor-nameとposition-anchorで結ぶ2ステップ

アンカー名は`--`で始まる任意の識別子（dashed-ident）です。次のコードで、ボタンの真上にツールチップが付きます。

```
.btn {
  anchor-name: --btn;
}
.tooltip {
  position: absolute;
  position-anchor: --btn;
  position-area: top;
  margin: 0;
}
```

Chrome 157で、ボタンを上端200px・高さ40pxに置いて実行すると、ツールチップ（高さ30px）は上端170px・下端200pxに描画され、下端がボタンの上端と一致しました。アンカー要素自身は`position`を持つ必要がなく、通常のフローに置いたままで構いません。

### popoverの暗黙アンカー（anchor-name不要）

`popovertarget`属性でpopoverを開くと、押したボタンが**暗黙のアンカー**になります。`anchor-name`は書かずに済み、配置要素に`position-anchor: auto`を書けば押したボタンが基準になります。この関連付けはChrome 133、Firefox 147、Safari 26で使えます。現行版（Chrome 151以降など）では`position-area`を使うなら`position-anchor`も省略できますが、初期値が`none`だったChrome 144〜150では省略すると付かないため、下の例では明示しています。

```
<button popovertarget="menu">メニュー</button>
<div id="menu" popover>…</div>
```

```
#menu {
  position-anchor: auto;
  position-area: bottom span-right;
  margin: 0;
}
```

popoverにはブラウザ既定で`margin: auto`が付いており、Chrome 157で`position-area`を書かずに開くと画面中央（上端285px）に表示されました。仕様では`position-area`か`anchor-center`が効いている間はautoマージンを0として扱い、Chrome 157では`margin`を書かなくてもボタン直下（ボタン下端240px＝popover上端240px）に付きました。ただしこの扱いはChrome 143・Firefox 148・Safari 26.2からの実装で、それより前の版や`anchor()`で位置を書く場合は働きません。上の例のように`margin: 0`を明示しておくと版を問わず同じ位置になります。JavaScriptから`showPopover({ source: 要素 })`で開いたときも、`source`に渡した要素がアンカーになります。

`position-area`を使わず`top: anchor(bottom)`のように`anchor()`だけで置く場合は、`position-anchor: auto`を明示します。`position-anchor`の初期値`normal`（Chrome 151・Firefox 151・Safari 27から）は、`position-area`が指定されているときだけ暗黙アンカーを使う値だからです。Chrome 157で確かめると、`anchor()`だけのpopoverは暗黙アンカーを使わずフォールバック値（上端11px・左端13px）に置かれ、`position-anchor: auto`を足したpopoverはボタンの下端（400〜440pxのボタンに対し上端440px）に付きました。[Firefox 151のリリースノート](https://www.firefox.com/en-US/firefox/151.0/releasenotes/)も、popoverで`anchor()`や`anchor-center`を使うには`position-anchor: auto`が必要になったと書いています。ボタンからpopoverやdialogを開く宣言的な書き方は[Invoker Commands APIの使い方と対応ブラウザ](/tech/details/5837/)で詳しく扱っています。

### interestforによるホバーで開くツールチップ（Chromeのみ）

Chrome 142（2025年10月28日）で、`<button>`と`<a>`に`interestfor`属性が入りました（[Chrome 142のリリースノート](https://developer.chrome.com/release-notes/142)）。ホバーやフォーカスでpopoverを開く宣言で、[Chromeのガイド](https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/interest-triggered-tooltips)のとおり、開いたボタンがpopoverの暗黙アンカーになります。

```
<button interestfor="tip">保存</button>
<div id="tip" popover="hint">Ctrl+S</div>
```

```
#tip {
  position-anchor: auto;
  position-area: top;
  margin: 0;
}
```

Chrome 157でボタン（上端200px・中心x360px）にマウスを乗せ、1.5秒後に確かめるとツールチップは開いており、下端200px・中心x360pxでボタンの真上に付いていました。表示までの待ち時間は`interest-delay`プロパティで変えられます。MDN browser-compat-data 8.1.8ではFirefoxとSafariが未対応で、そこではツールチップが開きません。ショートカットのような補足は、ボタンの`aria-describedby`から参照するなど、ツールチップが出なくても読める形で置いておきます。

## 配置の指定：position-areaとanchor()の使い分け

位置の指定方法は2つあります。上下左右のどこに出すかだけ決めたいなら`position-area`、アンカーの特定の辺から何pxずらすかまで決めたいなら`anchor()`です。

### position-areaの3×3グリッドとspanキーワード

`position-area`は、アンカーを中央マスとする3×3のグリッドを想定し、配置要素を置くマスをキーワードで選びます。`top`のように1語だけ書くと、もう一方の軸は`span-all`として扱われ、アンカーの幅を中心にした位置に収まります。2マス分に広げるときは`span-`付きのキーワードを使います。

| 指定                          | 表示される位置                 | 典型的な用途    |
| --------------------------- | ----------------------- | --------- |
| `top`                       | アンカーの真上・中央揃え            | ツールチップ    |
| `bottom span-right`         | 真下・アンカー左端から右へ           | ドロップダウン   |
| `right`                     | 右隣・上下中央                 | 入力欄のエラー表示 |
| `top right`                 | 右上の角                    | 通知バッジ     |
| `block-end span-inline-end` | ブロック方向の終端側・インライン方向の終端側へ | 縦書き・RTL対応 |

2024年の解説には旧名の`inset-area`で書かれたものがあり、今のブラウザでは無視されます（後述の旧構文の表を参照）。

### anchor()で辺を指定する書き方とフォールバック値

`anchor()`はアンカーの辺の座標を長さとして返す関数で、`top`・`left`・`inset`などインセット系のプロパティの中でしか使えません。第1引数にアンカー名（省略すると`position-anchor`の既定アンカー）、第2引数に辺（`top`・`bottom`・`start`・`end`・`center`・`inside`・`outside`・`50%`など）、第3引数にアンカーが見つからないときの値を書きます。

```
.menu {
  position: absolute;
  top: calc(anchor(--select bottom) + 8px);
  left: anchor(--select left, 20px);
}
```

アンカーとの間に隙間を空けたいときは、上のように`calc()`で足すか、配置要素に`margin-top: 8px`を付けます。第3引数のフォールバックは、Chrome 157で存在しない名前`--missing`を指定したときに実際に使われ、`top: anchor(--missing bottom, 10px)`の要素は上端10pxに置かれました。フォールバックを書かない場合、その宣言は無効になり`auto`として扱われます。

### 複数のアンカーを1つの配置要素で参照する書き方

`anchor()`の第1引数にアンカー名を書けば、辺ごとに別のアンカーを参照できます。2つの要素の間を線や枠で結ぶUIは、次のように書けます。

```
.a { anchor-name: --a; }
.b { anchor-name: --b; }
.connector {
  position: absolute;
  left: anchor(--a right);
  right: anchor(--b left);
  top: anchor(--a bottom);
  bottom: anchor(--b top);
}
```

Chrome 157で、Aを左端50px・幅60px・下端130px、Bを左端500px・上端220pxに置くと、`.connector`は横110〜500px・縦130〜220pxの矩形になり、Aの右下角からBの左上角までを埋めました。`anchor-size(--a width)`のように、寸法の参照先にもアンカー名を指定できます。一方、`position-area`は既定アンカー（`position-anchor`で指定した1つ）しか基準にできないので、複数のアンカーをまたぐ配置は`anchor()`で書きます。

### anchor-centerによる中央揃え

`position-area`を使わずに`anchor()`で上下だけ決め、左右はアンカーの中央にそろえたい場面では`justify-self: anchor-center`を使います。Chrome 157では、中心x座標360pxのボタンに対し、幅60pxのツールチップの中心も360pxになりました。

```
.tooltip {
  position: absolute;
  position-anchor: --btn;
  bottom: anchor(top);
  justify-self: anchor-center;
}
```

2026年3月27日の作業草案で、`anchor-center`は`align-items`・`justify-items`からは削除されました（絶対配置の要素には効かないため）。`justify-self`・`align-self`・`place-self`に書きます。

## anchor-size()によるドロップダウンの幅合わせ

`anchor-size()`はアンカーの幅や高さを返す関数です。セレクトボックス風のメニューを、開く元のボタンと同じ幅にするのが代表的な使い方です。

```
.select {
  anchor-name: --select;
}
.listbox {
  position: absolute;
  position-anchor: --select;
  top: anchor(bottom);
  left: anchor(left);
  width: anchor-size(width);
  box-sizing: border-box;
  margin: 0;
}
```

Chrome 157で幅237pxのアンカーに対して実行すると、メニューの幅も237pxになり、上端はアンカーの下端（130px）に一致しました。`anchor-size(width)`が返すのはアンカーの枠線を含む外寸なので、メニューにパディングや枠線を付けるときは`box-sizing: border-box`で外寸をそろえます。引数には`width`・`height`のほか、書字方向に追従する`inline`・`block`・`self-inline`・`self-block`を書けます。`width`や`max-height`など寸法系では最初から使え、`top`などのインセットや`margin`で使えるようになったのはChrome 132からです（Firefox 147・Safari 26は最初から対応）。

## 画面端でのはみ出し対策：position-try-fallbacksと@position-try

アンカー付きUIでいちばん手間がかかるのは、画面の端でツールチップが切れる問題です。CSS Anchor Positioningでは、はみ出したときに試す代わりの配置を`position-try-fallbacks`に並べておきます。

### flip-block・flip-inlineによる配置の反転

```
.tooltip {
  position: fixed;
  position-anchor: --btn;
  position-area: top;
  position-try-fallbacks: flip-block;
  margin: 0;
}
```

`flip-block`はブロック方向（横書きでは上下）、`flip-inline`はインライン方向（左右）を反転します。`flip-block, flip-inline`のようにカンマで並べると順に試し、`flip-block flip-inline`のように空白でつなぐと両方向を同時に反転した配置を1つの候補にします。`top`や`right span-bottom`など`position-area`のキーワードをそのまま候補に書くこともできます。物理方向で反転する`flip-x`・`flip-y`はChrome 144・Firefox 147・Safari 26.2から使えます。

効果はChrome 157で確かめました。ボタンを画面上端から5〜45pxに置くと、`flip-block`付きのツールチップはボタンの下（45〜75px）に回りました。指定しなかったツールチップは0〜30pxに描画され、ボタンに重なりました。`position-area`で置いた要素は、はみ出す代わりに包含ブロックの内側へ押し戻されるためです。はみ出しうるUIには`position-try-fallbacks`を付け、上下どちらにも収まらない画面幅も想定して寸法を決めておきます。

### @position-tryによる独自の配置候補の定義

反転だけでは足りない場合、`@position-try`で候補を名前付きで定義します。中に書けるのは位置・寸法・マージン・`position-anchor`・`position-area`・self系の配置に関わるプロパティだけで、色やフォントは書けません。

```
@position-try --left-narrow {
  position-area: left;
  max-width: 160px;
}
.tooltip {
  position-area: top;
  position-try-fallbacks: flip-block, --left-narrow;
}
```

上の例では、まず上に置き、収まらなければ下、それでも収まらなければ左に最大幅160pxで出します。どの候補でも収まらない場合は、元の配置（直前に収まった候補があればその候補）のままになり、はみ出しは解消されません。スクロール表示にする場合は、通常ルールで`overflow: auto`を指定し、候補側では`max-height`や`max-width`を使って、狭い画面でも必ず収まる寸法にしておきます。

### position-try-orderによる空きの大きい側の優先

`position-try-fallbacks`は通常、書いた順に試して最初に収まった候補を使います。`position-try-order: most-height`（または`most-width`・`most-block-size`・`most-inline-size`）を付けると、元の配置と候補の中から、使える高さ（幅）が最も大きいものを優先します。

```
.listbox {
  position-area: top;
  position-try-fallbacks: flip-block;
  position-try-order: most-height;
}
```

Chrome 157で高さ600pxの画面に置き、ボタンを150〜190pxに配置したところ、既定（`normal`）では上に収まるので上（120〜150px）に出て、`most-height`では下の方が広いため下（190〜220px）に出ました。項目数が多いドロップダウンを広い側に開きたいときに使います。`position-try-order`はChrome 125、Firefox 148、Safari 26から対応しています。

## position-visibilityによる配置要素の表示制御

スクロール領域の中にアンカーがあり、配置要素が`position: fixed`で外に出ている構成では、アンカーがスクロールで見えなくなっても配置要素だけが残ることがあります。これを制御するのが`position-visibility`です。

| 値                                     | 非表示になる条件             |
| ------------------------------------- | -------------------- |
| `always`                              | 非表示にしない              |
| `anchor-visible`（旧名`anchors-visible`） | 既定アンカーがスクロール等で完全に隠れた |
| `anchor-valid`（旧名`anchors-valid`）     | 既定アンカーが見つからない        |
| `no-overflow`                         | どの候補でも包含ブロックからはみ出す   |

Chrome 157の初期値は`anchor-visible`です。高さ200pxのスクロール領域の中のアンカーを、スクロールで領域の外（領域上端300pxに対しアンカー上端220px）に出すと、初期値のツールチップは描画されず（スクリーンショットで該当位置が白）、`always`を指定したツールチップはアンカーから離れたまま表示され続けました。このとき`checkVisibility()`は初期値の側でも`true`を返すので、隠れたかどうかをスクリプトで判定する用途には使えません。

値の名前は、[仕様のChanges節](https://drafts.csswg.org/css-anchor-position-1/#changes)にあるとおり2026年9月6日の作業草案で、既定アンカーだけを見る値であることに合わせて単数形の`anchor-visible`・`anchor-valid`に改称されました。対応はブラウザごとに分かれています。

- Chrome 157：新名の`anchor-visible`・`anchor-valid`を受け付け、旧名は`anchors-visible`だけが`CSS.supports()`で`true`、`anchors-valid`は`false`でした。以前検証したChrome 154では新名が`false`で、初期値も`anchors-visible`でした。
- Safari 27：新名に対応しています（Safari 26.2〜は旧名）。
- Firefox：旧名だけに対応しています（MDN browser-compat-data 8.1.8）。

アンカーが隠れたら消す挙動は初期値で得られるので、多くの場合は何も書かないのが安全です。`anchor-valid`系を明示したいときは、旧名と新名を続けて書けば、新名を解釈できないブラウザは後の宣言を無視して旧名を使います。ただしChrome 156以前は`anchors-valid`を出荷しておらず（browser-compat-dataではプレビュー版のみ）、どちらの宣言も無視されます。

```
.tooltip {
  position-visibility: anchors-valid;
  position-visibility: anchor-valid;
}
```

## アンカーが動いたときの追従：スクロールとtransform

配置要素はアンカーの位置が変わると、スクリプト無しで付いていきます。ただしスクロールに合わせて動くのは既定アンカー（`position-anchor`で指定したアンカー）だけです。[仕様の3.3節](https://drafts.csswg.org/css-anchor-position-1/#scroll)により、`anchor()`で別のアンカーを参照した辺は、表示した時点とフォールバックを切り替えた時点のスクロール位置で計算され、その後のスクロールには付いてきません。前の章の複数アンカーの例を別々のスクロール領域で使う場合は注意してください。

### スクロール領域の中のアンカーへの追従

高さ200pxのスクロール領域の中にボタンを置き、配置要素は領域の外に`position: fixed`で置きました。Chrome 157でスクロール量を0→50→180pxと変えると、アンカーの上端400→350→220pxに対し、配置要素の上端も410→360→230pxと同じ量だけ動きました。最後に配置要素が消えたのは`position-visibility`の初期値によるものです。

### transformで動かしたアンカーへの追従

アンカーに`transform: translateX(100px)`を付けると、Chrome 157ではツールチップも左端320pxから420pxへ100px動き、見た目のアンカーの真上に付きました。仕様は「アンカーの位置と大きさはレイアウトの後で決まる」としており、MDNのbrowser-compat-data 8.1.8では、transformやzoomを反映する挙動はChrome 144・Safari 27から対応、Firefoxは未対応です。Firefoxや古い版では、transformで動かす前の位置に配置要素が付くので、アンカーをtransformのアニメーションで動かすUIは対象ブラウザで確認してください。

## アンカーが効かないときの確認点（Chrome 157で実測）

CSSに誤りが無いのに配置要素が動かないときは、アンカーが参照可能な条件を満たしているかを確認します。

### 同名アンカーの参照先とanchor-scopeによる区切り

一覧の各行に同じ`anchor-name: --item`を付け、行の中に`position-anchor: --item`のツールチップを置くと、Chrome 157では3行すべてのツールチップが3行目（最後の要素）の横に集まりました。[CSS Anchor Positioning Level 1の仕様](https://drafts.csswg.org/css-anchor-position-1/)は2026年1月30日の作業草案で「祖先にあるアンカーを優先する」探索に変わりましたが、Chrome 157ではこの変更がまだ反映されておらず、文書順で最後の要素が選ばれます。

行ごとに付けるには、行の要素に`anchor-scope`を指定して名前の有効範囲を区切ります。

```
.row {
  anchor-scope: --item;
}
.row .item {
  anchor-name: --item;
}
.row .tooltip {
  position: absolute;
  position-anchor: --item;
  position-area: right;
}
```

Chrome 157では、`anchor-scope`を付けた2行（上端150px・210px）のツールチップがそれぞれの行（155px・215px）に付き、付けていない2行は両方とも2行目に付きました。`anchor-scope: all`とすれば、その要素以下で定義されるすべてのアンカー名を区切れます。`anchor-scope`はChrome 131、Firefox 147、Safari 26から使えます。

### 絶対配置どうしの文書順と包含ブロックの制約

アンカーは配置要素より**先にレイアウトされる**必要があります。同じ包含ブロックの中で両方が絶対配置のとき、アンカーが文書順で後ろにあると参照できません。Chrome 157でツールチップをアンカーより前に書いたところ、`anchor()`は解決されず、第3引数のフォールバック値（上端7px・左端9px）で配置されました。アンカーが絶対配置でない通常の要素なら順序の制約は受けませんが、両方を絶対配置にする場合はアンカーを先に書くと覚えておくと迷いません。

包含ブロックにも注意が必要です。通常の`position: absolute`では、包含ブロックを作る最も近い祖先（`position: relative`など）が基準になり、`position-area`の領域もフォールバックの判定もその内側に限られます。小さな親の中では上下どちらにも収まらず、アンカーに重なります（後述の`@supports`の例でChrome 157の実測値を示します）。ほかに、`content-visibility: hidden`などで描画が省略された要素の中にアンカーだけがあり、配置要素はその外にある場合も参照できません。

### 旧構文の名前と置き換え先

2024年以前の記事やデモには、仕様策定中の名前が残っています。Chromeは[構文変更の告知](https://developer.chrome.com/blog/anchor-syntax-changes)で旧名を移行期間の後に外すとしており、次の旧名はChrome 157の`CSS.supports()`で`false`でした。

| 旧名                     | 現行の名前                    | Chromeでの切替 |
| ---------------------- | ------------------------ | ---------- |
| `inset-area`           | `position-area`          | Chrome 129 |
| `position-try-options` | `position-try-fallbacks` | Chrome 128 |
| `inset-area()`関数       | キーワードを直接書く               | Chrome 129 |

## 対応ブラウザとBaselineの状況（2026年11月時点）

[MDNのbrowser-compat-data](https://github.com/mdn/browser-compat-data) 8.1.8（2026年11月2日）で確認した対応バージョンです。EdgeはChromeと同じ番号です。

| 機能                                       | Chrome・Edge | Firefox | Safari |
| ---------------------------------------- | ----------- | ------- | ------ |
| `anchor-name`・`anchor()`・`anchor-size()` | 125         | 147     | 26     |
| `position-try-fallbacks`                 | 128         | 147     | 26     |
| `position-area`                          | 129         | 147     | 26     |
| `anchor-scope`                           | 131         | 147     | 26     |
| popoverの暗黙アンカー                           | 133         | 147     | 26     |
| `interestfor`（ホバーで開くpopover）             | 142         | 未対応     | 未対応    |
| `position-try-order`                     | 125         | 148     | 26     |
| `position-visibility`                    | 125         | 147     | 26.2   |
| `anchor-visible`・`anchor-valid`（単数形の新名）  | 157         | 未対応     | 27     |
| アンカーのtransformを反映                        | 144         | 未対応     | 27     |
| `position-anchor: normal`（新しい初期値）        | 151         | 151     | 27     |
| アンカー位置クエリ（`@container anchored()`）       | 143         | 未対応     | 未対応    |

web-featuresのデータでは、主要部分はFirefox 147がリリースされた2026年1月13日にBaseline「新たに利用可能」になっています。Baselineの段階と確認方法は[Web Platform Baselineの3つの状態と対応ブラウザ](/tech/details/5467/)にまとめています。

ただし機能全体（web-featuresの`anchor-positioning`）としては、2026年11月時点でまだBaselineの判定が付いていません。前の章で触れた`position-visibility`の新しい値`anchor-visible`・`anchor-valid`にFirefoxが対応していないためです（web-features 3.45.0の時点で対応がSafari 27だけと記録されており、Chrome 157の対応はまだ反映されていません）。`position-anchor`の初期値も、Chromeでは`implicit`（125〜126）→`auto`（127〜143）→`none`（144〜150）→`normal`（151〜）と変わっています。`normal`は「`position-area`を指定していれば`auto`（暗黙アンカーを使う）、指定していなければ`none`」という意味で、popoverに`position-area`を書くだけで呼び出し元に付く挙動はこの値によるものです。

配置要素にどのフォールバック候補が適用されたかを`@container anchored(fallback: …)`で判定し、配置要素の中身（吹き出しの矢印の向きなど）のスタイルを切り替えるアンカー位置クエリ（`container-type: anchored`）はChromeだけの実装です。サイズで切り替える通常のコンテナクエリは[CSSコンテナクエリ（@container）の使い方](/tech/details/4708/)を参照してください。

## 非対応環境の対策：@supportsとポリフィル

### @supportsによる機能検出と段階的適用

対象ブラウザに古い版が残る場合は、アンカー関連の宣言を`@supports`で囲み、非対応環境では従来の固定位置で表示します。

```
<span class="field">
  <button class="btn">保存</button>
  <span class="tooltip">Ctrl+S</span>
</span>
```

```
.field {
  position: relative;
  display: inline-block;
}
.btn {
  anchor-name: --btn;
}
.tooltip {
  position: absolute;
  top: 100%;
  left: 0;
  margin: 0;
}
@supports (position-area: top) and (position-try-fallbacks: flip-block) {
  .tooltip {
    position: fixed;
    top: auto;
    left: auto;
    position-anchor: --btn;
    position-area: top;
    position-try-fallbacks: flip-block;
  }
}
```

非対応環境では`.field`を包含ブロックにしてボタンの直下に出し、対応環境だけアンカー基準の配置と反転を有効にします。判定に`anchor-name`ではなく`position-area`と`position-try-fallbacks`を使うのは、Chrome 125〜128が`anchor-name`に対応していても現行名の`position-area`を持たず、判定だけ通って配置が崩れるためです。

`@supports`の中で`position: fixed`に切り替えているのにも理由があります。Chrome 157で`absolute`のまま試すと、`position-area`の領域が包含ブロックの`.field`（ボタンと同じ高さ）の内側に制限され、上にも下にも収まらずにツールチップがボタンに重なりました（ボタン200〜240pxに対しツールチップ200〜230px）。`fixed`にすると包含ブロックが表示領域になり、ボタンの上（170〜200px）に付きました。

### @oddbird/css-anchor-positioningの導入と未対応機能

OddBirdのポリフィル`@oddbird/css-anchor-positioning`は、npmの公開記録で2026年8月18日の0.10.2が最新です。READMEは次のように、ネイティブ対応が無いときだけ読み込む書き方を案内しています。

```
<script type="module">
  if (!("anchorName" in document.documentElement.style)) {
    import("https://unpkg.com/@oddbird/css-anchor-positioning@0.10.2");
  }
</script>
```

導入前に、[GitHubのREADME](https://github.com/oddbird/css-anchor-positioning)の「Limitations」に挙がっている未対応機能を確認してください。2026年11月時点（0.10.2が最新のまま）で次のものは補えません。

- `position-try-order`（`position-try`の短縮記法に書いても無視される）
- `anchor-center`と`position-visibility`
- popoverの暗黙アンカーと`position-anchor: auto`
- 読み込み後に動的に追加・削除したアンカーや配置要素
- 別々のシャドウルートにあるアンカーと配置要素

上の読み込み条件ではChrome 125以降にポリフィルが入らないため、Chrome 125〜128の`position-area`、125〜130の`anchor-scope`は補われません。暗黙アンカーや動的リストに依存するUIなら、ポリフィルより次の章のJavaScriptライブラリの方が確実です。

## Floating UIなどJavaScriptライブラリとの使い分け

ツールチップの位置計算は、これまで`@floating-ui/dom`（2026年7月11日公開の1.8.0が最新）などのライブラリが担ってきました。CSS Anchor Positioningへ置き換えるかどうかは、次の基準で判断します。

- **CSSに置き換える**：使う機能ごとの対応版（`position-area`と`position-try-fallbacks`ならChrome 129・Firefox 147・Safari 26、`position-try-order`ならFirefox 148）を閲覧環境が満たしていて、表示位置の切替が上下左右の反転と候補リストで表現できる場合。スクロールやリサイズのたびの位置計算が不要になります。
- **ライブラリを残す**：Safari 18以前やFirefox 146以前の利用者がいて、しかも仮想スクロールのように表示中にアンカーや配置要素を追加・削除するUIの場合。動的な追加・削除はポリフィルが補えません。ライブラリのミドルウェアで独自の位置補正（ずらす量の計算など）を書いている場合も、候補を並べる宣言では再現できないので残します。

アクセシビリティの関係はCSS側では作られません。仕様にも、Anchor Positioningは支援技術向けの関連付けを作らないと明記されています。ツールチップなら`aria-describedby`、メニューならpopover属性や`aria-expanded`を、従来どおりHTML側で付けてください。属性の選び方は[WAI-ARIAのrole・aria属性の使い方](/tech/details/6970/)を参照してください。モーダルとして開く場合の要素選びは[モーダル・ダイアログとの違いとdialog要素での実装](/tech/details/7075/)が参考になります。

## よくある質問

### CSS Anchor PositioningはFirefoxやSafariで使えますか？

使えます。Firefoxは147（2026年1月13日）、Safariは26（2025年9月15日）で対応しました。ただし`position-try-order`と、`position-area`指定時にautoマージンを0として扱う挙動はFirefox 148からで、後者はSafariでも26.2からです。`position-visibility`もSafariは26.2からです。アンカーのtransformを位置に反映する挙動と`interestfor`はFirefoxが未対応なので、使う機能ごとに対応表を確認してください。

### アンカーと配置要素の間に隙間を空けるには？

配置要素に`margin`を付けるか、`top: calc(anchor(bottom) + 8px)`のように`calc()`で加算します。`position-area`を使う場合は`margin`で空けるのが簡単です。

### anchor-size()で何ができますか？

アンカーの幅・高さを取得して、配置要素の`width`や`max-height`に使えます。ドロップダウンをボタンと同じ幅にするのが典型例で、Chrome 132以降は`top`や`margin`でも使えます。

### ポリフィルを入れれば古いブラウザでも同じように動きますか？

基本的な配置と`position-try-fallbacks`は動きますが、`position-try-order`・`anchor-center`・`position-visibility`・popoverの暗黙アンカー・動的に追加した要素には対応していません（0.10.2時点）。

### position-try-orderはいつ使いますか？

候補を書いた順ではなく、空きが大きい側を優先したいときです。`most-height`を指定すると、上下のうち表示できる高さが大きい方に開くため、項目の多いメニューで役立ちます。

## 関連記事

- [Invokerとは？意味・読み方とInvoker Commands APIの使い方、対応ブラウザ、HTTP Invokerとの違い](/tech/details/5837/)
- [Web Platform Baselineとは？3つの状態と対応ブラウザ、確認・ビルド・Lintへの組み込み【2026年10月】](/tech/details/5467/)
- [CSSコンテナクエリ（@container）の使い方｜container-type・cqi単位・メディアクエリとの違い](/tech/details/4708/)
- [ドロワーUIとは？モーダル・ダイアログとの違いと使い分け、dialog要素での実装](/tech/details/7075/)
- [WAI-ARIAとは？role・aria属性の使い方とネイティブHTMLを優先すべき理由](/tech/details/6970/)

---

出典: [CSS Anchor Positioningの使い方｜position-area・@position-tryと対応ブラウザ](<https://www.issoh.co.jp/tech/details/10692/>)（株式会社一創）
