CSSアンカー位置指定
ツールチップやポップオーバーの位置合わせをJSの座標計算なしに解決でき、画面端でのはみ出しもCSSだけで自動反転できます。
- 1.anchor-name でアンカー要素を宣言し、位置指定要素側は position-anchor と anchor() 関数でアンカーの辺・中心を基準に配置する。
- 2.position-try-fallbacks(旧 position-try-options)ではみ出し時の代替位置を宣言的に列挙でき、ブラウザが自動でフォールバックを選ぶ。
- 3.アンカーと位置指定要素は別々の包含ブロック配下に置けるため、従来 JS で座標を再計算していたポップオーバー/ツールチップ実装をCSSのみに置き換えられる。
何を解決する仕様か
ツールチップやドロップダウン、ポップオーバーを「基準要素の近くに、画面からはみ出さないように」配置する処理は、従来 JavaScript が担ってきました。基準要素の getBoundingClientRect() を取得し、ビューポート残り幅を見て左右反転を判定し、スクロールやリサイズのたびに再計算する——という一連の処理です。CSS アンカー位置指定(CSS Anchor Positioning)は、この座標計算をブラウザのレイアウトエンジン内部に持ち込み、宣言的な CSS だけで完結させる仕様です。核となるのは「アンカーを名付ける」「アンカーを基準に置く」「はみ出したら代替案に切り替える」という3つの機能です。
アンカーの宣言と参照
任意の要素は anchor-name プロパティでアンカーとして名付けられます。名前は -- から始まるカスタム識別子です。
.trigger {
anchor-name: --my-anchor;
}
位置指定される側(position: absolute または fixed の要素)は position-anchor でどのアンカーを参照するかを宣言し、top/left/inset などのオフセットプロパティの値に anchor() 関数を使うことで、アンカーの辺や中心を基準値として取り込みます。
.tooltip {
position: fixed;
position-anchor: --my-anchor;
top: anchor(bottom);
left: anchor(center);
translate: -50% 0;
}
anchor(bottom) はアンカー要素の下辺の座標、anchor(center) は中心座標を返します。anchor() は top/right/bottom/left/start/end/center に加え、パーセンテージ(anchor(30%) のように辺の間を補間)も受け付けます。重要なのは、この計算が通常の包含ブロックの親子関係を必要としない点です。位置指定要素とアンカー要素は DOM 上どこにあっても構いません。ポップオーバーを body 直下に置きつつ、ボタンの真下に出す、といった構造がそのまま書けます。この仕組みは包含ブロックと位置指定(position)の解決過程で説明した「absolute は直近 positioned 祖先のパディング領域を基準にする」という原則の外側に、アンカーという第二の基準系を追加するものだと理解すると位置づけが明確になります。
anchor() は top/left/right/bottom/inset-* など、位置指定要素のオフセットを決めるプロパティの値としてのみ使えます。width や margin に直接使うことはできません(サイズ側は後述の anchor-size() が担当します)。
サイズ合わせには anchor-size()
アンカーの幅・高さに追従してサイズを決めたい場合は anchor-size() を使います。例えばドロップダウンの幅をトリガーボタンと揃えるには次のようにします。
.dropdown {
position: fixed;
position-anchor: --my-anchor;
width: anchor-size(width);
top: anchor(bottom);
left: anchor(left);
}
anchor() が「位置」、anchor-size() が「寸法」を担当するという役割分担です。どちらも参照先は position-anchor で結び付けたアンカー、または個々のオフセットで明示する anchor() の第一引数(アンカー名)で上書きできます。
フォールバック位置:position-try-fallbacks
アンカー位置指定の実用上の核心は、画面端での自動反転です。ツールチップを常に「アンカーの下」に置くと決め打ちすると、画面下端付近の要素では吹き出しが画面外にはみ出します。これを解決するのが position-try-fallbacks です。あらかじめ複数の配置案を宣言しておくと、ブラウザは最初の案ではみ出しが発生する場合に自動で次の案を試し、実際にビューポート内に収まる案を採用します。
.tooltip {
position: fixed;
position-anchor: --my-anchor;
top: anchor(bottom);
left: anchor(center);
translate: -50% 0;
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}
flip-block はブロック方向(多くの場合縦方向)の配置を反転し、flip-inline はインライン方向(横方向)を反転します。組み合わせて指定すると、最初にはみ出さない組み合わせが優先度順に採用されます。独自の代替案を細かく書きたい場合は @position-try ルールで名前付きの代替スタイルセットを定義し、position-try-fallbacks からその名前を参照します。
@position-try --above {
top: anchor(top);
bottom: unset;
translate: -50% -100%;
}
.tooltip {
position-try-fallbacks: --above;
}
従来の実装は「配置 → 実際の矩形を測定 → はみ出し判定 → スタイル書き換え → 再レイアウト」というループをスクロール・リサイズのたびに JavaScript で回していました。position-try-fallbacks はこのループをレイアウトエンジン内部(スタイル計算とレイアウトの間)で完結させるため、レイアウトスラッシングや測定用の余分なリフローが発生しません。これはリフローとリペイントを引き起こすCSSプロパティの分類で扱う「JSによる強制同期レイアウト」を構造的に避けられることを意味します。
ポップオーバーAPIとの関係
popover 属性(popoverとdialogの標準化されたUI状態管理で扱われるようなネイティブ開閉制御)と組み合わせると、ポップオーバーは表示時にトップレイヤーへ昇格し、位置指定要素としての fixed 配置とアンカー位置指定の相性が特に良くなります。トップレイヤーに載った要素は他要素の overflow: hidden などに影響されず、アンカーとの位置関係だけで配置が決まるため、スタッキングコンテキストとz-indexで説明される重なり順の問題も同時に解消します。
アンカー位置指定は比較的新しい仕様であり、未対応ブラウザでは anchor() を含む宣言全体が無視されます。@supports (anchor-name: --a) で機能検出し、非対応環境では JS ベースの位置計算(あるいは単純な position: relative 配置)にフォールバックする設計が現実的です。CSSのみで完結させる利点を活かしつつ、境界条件は明示的に分岐させます。
まとめ
(1) anchor-name でアンカーを命名し、position-anchor と anchor()/anchor-size() で位置・寸法を参照する、(2) アンカーと位置指定要素は DOM 構造上の親子関係を必要とせず、包含ブロックとは独立した第二の基準系である、(3) position-try-fallbacks(および @position-try)ではみ出し時の代替配置を宣言し、ブラウザが自動選択することで JS の再計算ループを不要にする、の3点が要点です。座標計算という「動的なJS処理」を「宣言的なCSS」に移す典型例として、レイアウト全体の解決順序を理解する上でもCSSレイアウトアルゴリズム(Flexbox/Gridの解決過程)と合わせて押さえておくと、CSSがどこまでレイアウトの意思決定を引き受けられるようになったかが見えてきます。
Web/フロントエンド Article
CSSアンカー位置指定を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
CSS
比較で見る軸
難易度: advanced / カテゴリ: Web/フロントエンド / タグ数: 5
導入後に効く点
position-try-fallbacks(旧 position-try-options)ではみ出し時の代替位置を宣言的に列挙でき、ブラウザが自動でフォールバックを選ぶ。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- Web/フロントエンド
- タグ数
- 5
判断チェックリスト
- 自社の用途が「CSS / レイアウト」に近いか確認する。
- 強みである「anchor-name でアンカー要素を宣言し、位置指定要素側は position-anchor と anchor() 関数でアンカーの辺・中心を基準に配置する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。