メインコンテンツまでスキップ
  • Created:
  • Updated:
  • Author:
    Takeshi Takatsudo

アンカーポジショニング

問題

要素を他の要素に対して相対的に配置すること(ツールチップ、ポップオーバー、ドロップダウンメニュー、ラベルなど)は、これまで常に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パターン

ライブプレビュー

CSS Anchor Positioning — ツールチップパターン

参考リンク