CSS Anchor Positioning入門:Popoverをボタンのそばに表示する

2026.09.22 09:00
2026.08.30 14:33
CSS Anchor Positioning入門:Popoverをボタンのそばに表示する

ボタンのすぐ下にメニューを表示したいとき、これまではJavaScriptでボタンの座標やサイズを調べ、メニューの位置を計算することがありました。CSS Anchor Positioningを使うと、基準となる要素(アンカー)と表示する要素をCSSで関連付けて配置できます。

この記事では、HTMLだけで開閉できるPopover APIと組み合わせ、ボタンのそばにメニューを表示する基本を解説します。

CSS Anchor Positioningとは

CSS Anchor Positioningは、ある要素の位置を基準にして、別の要素を配置するためのCSS機能です。

例えば、次のようなUIに利用できます。

  • ボタンの下に表示する操作メニュー
  • アイコンのそばに表示する説明
  • 入力欄に関連付ける候補リスト
  • 要素を指し示す吹き出し

基準にする要素にはanchor-nameで名前を付け、配置する要素にはposition-anchorでその名前を指定します。これにより、「どの要素を基準にするか」がCSSから分かるようになります。

Popover APIと組み合わせるメリット

Popover APIは、メニューや補足情報などをほかの内容より手前に表示するためのHTML機能です。popover属性を付けた要素は最初は非表示になり、popovertargetを持つボタンから開閉できます。

<button type="button" popovertarget="account-menu">
  アカウント
</button>

<div id="account-menu" popover>
  メニューの内容
</div>

この時点で開閉処理は動作するため、基本的なトグル処理をJavaScriptで書く必要はありません。また、自動で開く通常のPopoverは、外側をクリックする操作やEscキーでも閉じられます。

ただし、Popover APIだけではボタンのすぐ下に配置されるとは限りません。そこで、表示位置をCSS Anchor Positioningで指定します。

ボタンの下にメニューを配置する

まずは全体のHTMLです。ボタンとPopoverをaccount-menuというIDで関連付けています。

<button
  class="account-button"
  type="button"
  popovertarget="account-menu"
>
  アカウント
</button>

<nav id="account-menu" class="account-menu" popover aria-label="アカウントメニュー">
  <a href="/profile/">プロフィール</a>
  <a href="/settings/">設定</a>
  <button type="button">ログアウト</button>
</nav>

続いて、ボタンをアンカーとして登録します。--account-buttonはCSS内で使うカスタム識別子で、名前の先頭には--が必要です。

.account-button {
  anchor-name: --account-button;
}

Popover側では、position-anchorに同じ名前を指定します。さらにposition-area: bottomを指定すると、アンカーの下側を配置領域として利用できます。

.account-menu {
  position: fixed;
  position-anchor: --account-button;
  position-area: bottom;
  margin: 8px 0 0;

  padding: 8px;
  border: 1px solid #d0d7de;
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 8px 24px rgb(0 0 0 / 16%);
}

ここでのポイントは、次の3つです。

1. anchor-nameで基準となるボタンに名前を付ける

2. position-anchorでPopoverからアンカーを参照する

3. position-areaでアンカーに対する配置場所を決める

popover要素にはブラウザ標準の余白などがあるため、作りたいデザインに合わせてmarginやpaddingを明示すると調整しやすくなります。

画面端では表示位置を切り替える

ボタンが画面の下端にあると、下向きに開いたメニューが画面外にはみ出す可能性があります。position-try-fallbacksを使うと、最初の位置に十分な空間がない場合の候補を指定できます。

.account-menu {
  position: fixed;
  position-anchor: --account-button;
  position-area: bottom;
  position-try-fallbacks: flip-block, flip-inline;
  margin: 8px;
}

flip-blockは上下方向、flip-inlineは左右方向で位置を反転する候補です。例えばボタンの下に空間が足りなければ、ブラウザは上側への配置を試せます。

フォールバックは「常に反転する」という指定ではありません。最初に指定した配置が収まらないときに、ブラウザが次の候補を試すための指定です。

anchor()で位置を細かく指定する

position-areaは簡潔ですが、アンカーの端を使って位置を細かく決めたい場合はanchor()関数も利用できます。

.account-menu {
  position: fixed;
  position-anchor: --account-button;

  top: anchor(bottom);
  right: anchor(right);
  margin-top: 8px;
}

この例では、Popoverの上端をボタンの下端に、Popoverの右端をボタンの右端に合わせています。position-anchorで基準を指定しているため、anchor(bottom)やanchor(right)にはアンカー名を繰り返し書かずに済みます。

最初は読みやすいposition-areaから試し、位置を細かく調整する必要が出たらanchor()を検討するとよいでしょう。

未対応環境も考慮する

CSS Anchor Positioningの対応状況はブラウザやバージョンによって異なります。実際に利用するときは対象ブラウザを確認し、非対応でも操作できる作りにします。

今回の例では、配置用CSSが解釈されなくてもPopover自体の開閉機能は独立しています。まず通常の位置でも内容を利用できる状態を用意し、対応ブラウザだけ配置を拡張する方法があります。

.account-menu {
  /* Anchor Positioningに依存しない見た目 */
  padding: 8px;
  border: 1px solid #d0d7de;
  border-radius: 8px;
  background: #fff;
}

@supports (anchor-name: --example) {
  .account-button {
    anchor-name: --account-button;
  }

  .account-menu {
    position: fixed;
    position-anchor: --account-button;
    position-area: bottom;
    position-try-fallbacks: flip-block, flip-inline;
    margin: 8px;
  }
}

Popover APIにも対応していない環境を対象に含める場合は、JavaScriptによる開閉処理や別ページへのリンクなど、要件に合った代替手段も検討してください。

実装時に確認したいこと

最後に、PopoverとAnchor Positioningを組み合わせるときの確認事項をまとめます。

  • ボタンはbutton要素にし、キーボードでも操作できるようにする
  • popovertargetとPopoverのidを一致させる
  • anchor-nameとposition-anchorの名前を一致させる
  • 画面の上下左右の端でも内容が見切れないか確認する
  • ズーム時や狭い画面でも操作できるか確認する
  • 対象ブラウザでPopover APIとCSS Anchor Positioningの対応状況を確認する

Popover APIが表示状態を管理し、CSS Anchor Positioningが表示場所を担当すると、HTML・CSSそれぞれの役割が分かりやすくなります。まずは小さな操作メニューから試し、JavaScriptによる座標計算を減らせるか検討してみてください。

今回は以上です。