Anchor Positioningが全対応。HTML・CSSだけのポップオーバーが完全体に
2026年1月13日に、Firefox 147がリリースされ、「CSS Anchor Positioning」が全ブラウザ対応しました。HTML・CSSだけでポップオーバー表現をしつつ、好きな要素を基準に、ポップオーバーを表示できるようになりました。
たとえば、タスク管理のサブメニューを右側に表示する表現や、ヘッダーのユーザーアイコン下にドロップダウンメニューを表示できます。

タスク管理のサブメニュー

ユーザーアイコンの下にドロップダウンメニューが表示される
私はずっっっとこの表現をHTML・CSSで実現したいと思っており、Firefoxの対応を待ち望んでいました。本記事で詳しく解説します。
Popover APIとは
従来、ポップオーバーを実装するには、大量のイベントリスナー、複雑な位置計算のロジック、スクロールやリサイズへの対応が必要でした。
たとえば次のようなJavaScriptのコードが必要です。
// 従来のJavaScript実装
const button = document.querySelector('.trigger');
const popover = document.querySelector('.popover');
// 表示・非表示の制御
button.addEventListener('click', () => {
popover.classList.toggle('open');
});
// ESCキーで閉じる
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
popover.classList.remove('open');
}
});
// 背景クリックで閉じる
document.addEventListener('click', (e) => {
if (!popover.contains(e.target) && !button.contains(e.target)) {
popover.classList.remove('open');
}
});
これを毎度実装するのは、かなり面倒でした。
Popover APIで表示・非表示が簡単に
Popover APIを使うと、JavaScriptを使わず、ポップオーバーの表示・非表示がHTML属性だけで実現できます。
ボタンをクリックするとポップオーバーが開くシンプルな例です。
<button popovertarget="my-popover">開く</button>
<div id="my-popover" popover>
<p>ポップオーバーの内容</p>
</div>
これだけで、以下の機能が自動的に実装されます。JavaScriptは不要です。
- クリックで開閉
- ESCキーで閉じる
- 背景クリックで閉じる
- 適切なフォーカス管理
popovertarget属性で開閉ボタンを指定し、popover属性で要素をポップオーバーとして宣言します。
| 属性 | 役割 |
|---|---|
popover |
要素をポップオーバーとして宣言 |
popovertarget |
クリック時に開閉するポップオーバーのIDを指定 |
popovertargetaction |
動作を指定(toggle / show / hide) |
なお、popovertarget属性はHTML仕様上、<button>要素と<input type="button">でのみ使用できます。<a>要素では動作しません。
Popover APIがあっても、結局位置計算にはJavaScriptが必要
Popover APIは便利な機能ですが、ポップオーバーの位置を指定する機能はありません。ボタンの下や右側にポップオーバーを表示したい場合、従来はJavaScriptで位置を計算する必要がありました。
次のコードは、ボタンの位置を取得して、ポップオーバーの位置を計算し、CSSで位置を指定するJavaScriptの例です。リサイズやスクロールのたびに再計算が必要なので、処理負荷も大きくなってしまいます。
function updatePosition() {
// ボタンの位置を取得して、ポップオーバーの位置を計算
const rect = button.getBoundingClientRect();
popover.style.top = `${rect.bottom + 8}px`;
popover.style.left = `${rect.left}px`;
}
全ブラウザ対応したCSS Anchor Positioningで位置指定をする
今回全ブラウザで対応したCSS Anchor Positioningを使うと、CSSだけでポップオーバーの位置を指定できます。
次のHTMLを例に解説します。
<button class="button" popovertarget="my-popover">開く</button>
<div id="my-popover" popover class="popover">
<p>ポップオーバーの内容</p>
</div>
ステップ1: ポップオーバーの基準となる要素を指定する(anchor-name)
ポップオーバーの基準となる要素を、CSSのanchor-nameで定義します。アンカー(anchor)とは船のいかりのことで、そこを基準にして位置を指定します。ちなみにHTMLの<a>要素も「アンカー」です。anchor-nameには任意の名前を指定できます。
.button {
anchor-name: --my-anchor;
}
ステップ2: ポップオーバーをアンカー要素と紐づける(position-anchor)
ポップオーバーをアンカー要素と紐づけるには、position-anchorプロパティを使用します。これで、CSSではアンカー要素を基準とする位置を指定できるようになります。
.popover {
position-anchor: --my-anchor;
}
ステップ3: ポップオーバーの位置を指定する
位置の指定方法は2種類あります。
anchor()関数
anchor()関数を使うと、アンカー要素の特定の位置を基準にした配置ができます。
.popover {
top: anchor(bottom); /* アンカーの下端 */
left: anchor(left); /* アンカーの左端 */
}
また、calc()と組み合わせて余白を調整することもできます。
.popover {
position-anchor: --my-anchor;
top: calc(anchor(bottom) + 8px);
left: anchor(center);
}
| 値 | 説明 |
|---|---|
top |
アンカーの上端 |
bottom |
アンカーの下端 |
left |
アンカーの左端 |
right |
アンカーの右端 |
center |
アンカーの中央 |
position-areaプロパティ
position-areaプロパティを使うと、アンカー周囲のエリアを指定して配置できます。
.popover {
position-area: block-end;
}
| 値 | 配置位置 |
|---|---|
block-start |
上 |
block-end |
下 |
inline-start |
書字方向の開始位置(LTRなら左) |
inline-end |
書字方向の終了位置(LTRなら右) |
2つの値を組み合わせることで、斜め方向にも配置できます。
| 値 | 配置位置 |
|---|---|
block-start inline-end |
右上 |
block-end inline-start |
左下 |
なお、書字方向を使ったレイアウトについては、margin-inline: auto; による話も関連しています。
シンプルなデモで挙動を確認する
さまざまな配置を試すための、シンプルなデモをつくりました。
動作している様子は次のとおりです。

ポップオーバーが上側に表示されている様子

ポップオーバーが右側に表示されている様子
画面端ではみ出さない配置(position-try-fallbacks)
ポップオーバーを表示するとき、画面外にはみ出してしまうことがあります。position-try-fallbacksを使うと、はみ出す場合に自動で代替位置へ切り替わります。これもFirefox 147で全ブラウザ対応しました。
.popover {
position-anchor: --my-anchor;
position-area: block-end; /* デフォルト: 下に表示 */
/* はみ出したら上下を反転 */
position-try-fallbacks: flip-block;
}
| 値 | 動作 |
|---|---|
flip-block |
上下を反転 |
flip-inline |
左右を反転 |
flip-block flip-inline |
両方を反転 |
これで、画面端でも常に見える位置にポップオーバーが表示されます。
実例
サブメニューナビゲーション
私はAnchor Positioningが出たなら、絶対にこれをCSSだけで表現したいと思っていました。メニューのサブメニューの位置をAnchor Positioningで実装します。

タスク管理のサブメニュー

設定のサブメニュー
<nav class="menu">
<ul class="menu-list">
<li class="menu-item">
<button class="menu-link" id="task-menu-anchor" popovertarget="task-submenu">
タスク管理
<span class="chevron">›</span>
</button>
<ul class="submenu" popover id="task-submenu">
<li><a href="#">今日のタスク</a></li>
<li><a href="#">週次タスク</a></li>
<li><a href="#">アーカイブ</a></li>
</ul>
</li>
</ul>
</nav>
前述のとおり、popovertarget属性は<button>要素で使用します(<a>要素では動作しません)。
/* メニューリンクをアンカーとして定義 */
#task-menu-anchor {
anchor-name: --task-menu;
}
/* サブメニューの位置指定 */
.submenu {
position-anchor: --task-menu;
top: anchor(top);
left: anchor(right);
}
ヘッダーのユーザーメニュー
このパターンもよく使いますね。ヘッダーのユーザーアイコン下に、ドロップダウンメニューを配置する例です。

ユーザーアイコンの下にドロップダウンメニューが表示される
<header class="header">
<button popovertarget="user-menu" class="user-icon">
<img src="avatar.png" alt="ユーザー" />
</button>
<div id="user-menu" popover class="dropdown-menu">
<a href="#">プロフィール</a>
<a href="#">設定</a>
<a href="#">ログアウト</a>
</div>
</header>
.user-icon {
anchor-name: --user-icon;
}
.dropdown-menu {
position-anchor: --user-icon;
top: anchor(bottom);
right: anchor(right);
margin-top: 8px;
}
right: anchor(right)を指定することで、ドロップダウンの右端とアイコンの右端が揃います。ヘッダー右端のアイコンからドロップダウンを表示するとき、メニューが画面外へはみ出さないための指定です。
なお、position-area: block-end inline-endだと「アンカーの右下エリアに配置」となり、ドロップダウンの左端がアンカー付近に来るため、右側にはみ出してしまいます。右端を揃えたい場合はanchor()関数を使いましょう。
ブラウザ対応状況
CSS Anchor Positioningは、2026年1月13日に全主要ブラウザで対応しました。
| ブラウザ | 対応バージョン | リリース日 |
|---|---|---|
| Chrome | 125以降 | 2024年5月 |
| Edge | 125以降 | 2024年5月 |
| Safari | 26.0以降 | 2025年9月 |
| Firefox | 147以降 🎉 | 2026年1月 |
まとめ
Popover APIが登場したとき、ポップオーバーがJSなしで実装できて感動しました。しかし位置指定にはCSS Anchor Positioningが必要で、Firefoxが対応するまで実務では使いづらい状況が続いていました。
Safari 26、そしてFirefox 147で全ブラウザ対応したことで、ようやくHTML・CSSだけでポップオーバーを完結できるようになりました。サブメニューやドロップダウンメニューは頻出するUIなので、すぐに使える場面は多いはずです。
参考リンク
Discussion