アンカーポジショニング
問題
要素を他の要素に対して相対的に配置すること(ツールチップ、ポップオーバー、ドロップダウンメニュー、ラベルなど)は、これまで常にJavaScriptが必要でした。Floating UI(Popper.js)のようなライブラリが位置を計算し、ビューポートのオーバーフローを処理し、スクロールやリサイズ時に再配置します。これによりバンドルサイズ、複雑さ、フレームレートの問題が生じます。AIエージェントは、純粋なCSS Anchor Positioningの方がパフォーマンスが良く保守しやすい場合でも、一貫してJavaScriptの配置ライブラリを推奨します。
解決方法
CSS Anchor Positioningを使うと、純粋なCSSで要素を「アンカー」要素に対して宣言的に配置できます。アンカー関係(anchor-name / position-anchor)、配置(position-areaまたはanchor()関数)、そしてビューポートからはみ出した場合の自動フォールバック再配置(position-try-fallbacks)を処理します。Popover APIと組み合わせることで、ほとんどのJavaScriptツールチップ/ドロップダウンライブラリを置き換えられます。
コード例
基本的なツールチップ
.anchor-button {
anchor-name: --my-tooltip-anchor;
}
.tooltip {
/* Attach to the anchor */
position: fixed;
position-anchor: --my-tooltip-anchor;
/* Position above the anchor, centered */
position-area: top center;
/* Spacing from the anchor */
margin-bottom: 8px;
/* Styling */
background: #1f2937;
color: white;
padding: 0.5rem 0.75rem;
border-radius: 6px;
font-size: 0.875rem;
white-space: nowrap;
}
<button class="anchor-button">Hover me</button>
<div class="tooltip" popover="hint">Helpful tooltip text</div>
ドロップダウンメニュー
.menu-trigger {
anchor-name: --menu-anchor;
}
.dropdown-menu {
position: fixed;
position-anchor: --menu-anchor;
/* Below the trigger, left-aligned */
position-area: bottom span-right;
margin-top: 4px;
background: white;
border: 1px solid #e5e7eb;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 0.25rem;
min-width: 180px;
}
<button class="menu-trigger" popovertarget="dropdown">Menu</button>
<div class="dropdown-menu" id="dropdown" popover>
<button>Option 1</button>
<button>Option 2</button>
<button>Option 3</button>
</div>
自動フォールバック配置
配置された要素がビューポートからはみ出す場合、自動的に代替位置を試みます。
.tooltip {
position: fixed;
position-anchor: --tooltip-anchor;
position-area: top center;
margin: 8px;
/* If top overflows, try bottom, then right, then left */
position-try-fallbacks: flip-block, flip-inline;
}
@position-tryによるカスタムフォールバック位置
@position-try --below {
position-area: bottom center;
margin-top: 8px;
}
@position-try --right {
position-area: right center;
margin-left: 8px;
}
@position-try --left {
position-area: left center;
margin-right: 8px;
}
.tooltip {
position: fixed;
position-anchor: --tooltip-anchor;
/* Default: above */
position-area: top center;
margin-bottom: 8px;
/* Try these in order if default overflows */
position-try-fallbacks: --below, --right, --left;
}
anchor()関数による精密な配置
position-areaより細かい制御が必要な場合、insetプロパティ内でanchor()関数を使用します。
.popover {
position: fixed;
position-anchor: --trigger;
/* Position the popover's top-left corner at the anchor's bottom-left corner */
top: anchor(bottom);
left: anchor(left);
/* Or center horizontally relative to anchor */
left: anchor(center);
translate: -50% 0;
}
ラベルとフォームフィールドの接続
.form-field {
anchor-name: --field;
}
.field-hint {
position: fixed;
position-anchor: --field;
position-area: right center;
margin-left: 12px;
font-size: 0.75rem;
color: #6b7280;
max-width: 200px;
}
<div>
<input class="form-field" type="email" placeholder="Email" />
<p class="field-hint">We'll never share your email.</p>
</div>
複数要素での動的アンカーとanchor-name
.list-item {
anchor-name: --item;
}
.list-item:hover {
/* The detail panel follows whichever item is hovered */
}
.detail-panel {
position: fixed;
position-anchor: --item;
position-area: right center;
margin-left: 1rem;
}
Popover APIとの組み合わせ
[popovertarget] {
anchor-name: --popover-trigger;
}
[popover] {
position: fixed;
position-anchor: --popover-trigger;
position-area: bottom center;
margin-top: 4px;
/* Automatic fallback */
position-try-fallbacks: flip-block;
/* Styling */
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 1rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}
<button popovertarget="info-popover">Info</button>
<div id="info-popover" popover>
<h3>Additional Information</h3>
<p>This popover is positioned and managed entirely in CSS/HTML.</p>
</div>
ブラウザサポート
- Chrome 125+
- Edge 125+
- Safari 26+(Technology Preview、2025-2026年に正式リリース予定)
- Firefox 145+(フラグ付き)、Firefox 150+で完全サポート
2025年後半の時点で、Anchor Positioningはすべての主要ブラウザで利用可能です。古いブラウザには、OddBirdによるCSS anchor positioning polyfillがChrome 51+、Firefox 54+、Safari 10+をサポートしています。常に合理的な非配置フォールバックを提供しましょう。
AIがよくやるミス
- CSS Anchor Positioningでネイティブに処理できるツールチップやポップオーバーに対して、JavaScriptの配置ライブラリ(Floating UI、Popper.js)を推奨する
- CSS Anchor Positioningの存在を知らない
position-areaの代わりにposition: absoluteと手動のtop/left計算を使用する- アンカーされた要素に
position: fixedを忘れる(Anchor Positioningが機能するために必要) - ビューポートのオーバーフロー処理に
position-try-fallbacksを使用しない — 要素がクリップされる - 古いプロパティ名
inset-areaと現在のposition-areaを混同する(Chrome 129でリネーム) - アクセシブルなディスクロージャーパターンのために、Anchor PositioningとPopover APIを組み合わせない
使い分け
- トリガーに対して相対的に配置されるツールチップ、ポップオーバー、情報パネル
- ビューポートの端付近で再配置が必要なドロップダウンメニュー
- 入力フィールドの横に配置されるフォームフィールドのヒントやバリデーションメッセージ
- フローティングラベルやアノテーションマーカー
- これまでJavaScriptで要素を別の要素に対して配置していたあらゆるUIパターン