ドロップダウン。ツールチップ。サブメニュー。ユーザーアイコンを押したら出てくるアレ。
UIの現場では毎日のように出番があるのに、実装はなぜか毎回しんどい。クリックで開閉して、Escで閉じて、外側クリックでも閉じて、フォーカスも良い感じにして、さらに位置はボタンの下。スクロールしたら追従。画面端なら反転。はい、今日も位置計算で一日が終わる。
ここに新しい選択肢が入ってきました。Popover APIとCSS Anchor Positioningです。組み合わせると、HTMLとCSSだけで「開閉」と「位置決め」をかなりの範囲まで片付けられます。2026年1月のFirefox 147対応で、Anchor Positioningが主要ブラウザに揃ったという流れもあり、現場投入を検討しやすくなりました。
- まず何がうれしいのか ざっくり3行
- なぜ今までつらかったのか 位置計算という名の沼
- 止める必要があるのは何か それは手動の位置計算
- Popover APIとは 開閉がHTML属性で済むやつ
- Popoverだけだと位置が決められない そこにAnchor Positioning
- Anchor Positioningの考え方 アンカーに結びつける
- 実装例 HTMLとCSSだけでドロップダウンを作る
- 画面端でのはみ出し対策 position-try-fallbacksが効く
- メリット こういう現場で刺さる
- デメリット 夢だけ見ていると足を取られる
- やり方のコツ 既存実装から移行するならここを見る
- 忙しい人向け 最小セットだけ覚える
- 関連して役に立つ知識 ポップオーバー実装の地雷回避
- この話が好きなら 次に読むと楽しい作品たち
まず何がうれしいのか ざっくり3行
Popover APIで、開閉とフォーカスの面倒をブラウザがやってくれる。
Anchor Positioningで、基準要素に対してCSSだけで位置を決められる。
さらにフォールバック指定で、画面端ではみ出さない動きまで狙える。
なぜ今までつらかったのか 位置計算という名の沼
従来のポップオーバー実装は、だいたい同じ苦労を踏みます。
- 開閉イベントの管理が増える。クリック、Esc、外側クリック。
- フォーカス制御が厄介。アクセシビリティ対応で急に難易度が上がる。
- 位置決めが地獄。getBoundingClientRect、スクロール、リサイズ、ズレ、はみ出し。
「この程度のUI、コピペで済むでしょ」と思っても、微妙に要件が違う。右寄せなのか、左寄せなのか。ヘッダー固定なのか。overflowの中なのか。気づいたら例外対応の寄せ集めになって、いつか自分が泣きます。
止める必要があるのは何か それは手動の位置計算
今回のテーマで止めたいのは「毎回自前で位置を計算して、top/leftを当て込むやり方」です。
もちろん全部を捨てられるわけではありません。けれど、標準機能で届く範囲は想像より広い。ここを標準に寄せるだけで、保守コストがごっそり落ちます。
あなたのプロジェクト、ポップオーバーのためだけに小さな位置計算関数が増殖していませんか。
Popover APIとは 開閉がHTML属性で済むやつ
Popover APIは、ポップオーバー要素を「popover」として宣言し、ボタン側から「popovertarget」で紐付ける仕組みです。開閉の基本動作をブラウザが持ってくれます。
最小構成のHTML
<button popovertarget="my-popover">開く</button>
<div id="my-popover" popover>
<p>ポップオーバーの中身</p>
</div>
これだけで、クリックで開閉、Escで閉じる、外側クリックで閉じる、フォーカス管理、といったお作法を標準側が面倒見てくれます。
注意点もあります。popovertargetは仕様上、buttonやinput type=”button”での利用が前提になっており、a要素ではそのまま動かない場面があります。リンク見た目で押したいなら、buttonをリンク風にスタイルする方が事故が少ない。
popovertargetactionも覚えておくと便利
トグルだけでなく、showやhideを明示できます。連打や状態同期が絡むときに効きます。
<button popovertarget="my-popover" popovertargetaction="show">開く</button>
<button popovertarget="my-popover" popovertargetaction="hide">閉じる</button>
Popoverだけだと位置が決められない そこにAnchor Positioning
Popover APIは開閉を簡単にしてくれます。けれど「ボタンの右に出したい」「アイコンの下に出したい」みたいな位置指定は、従来だとJSで座標を計算しがちでした。
そこでCSS Anchor Positioningです。アンカーとなる要素を決めて、そこを基準に別要素を配置できます。つまり、位置計算の主役がJSからCSSに移る。
Anchor Positioningの考え方 アンカーに結びつける
ざっくり手順は3つです。
- 基準要素に名前をつける(anchor-name)
- ポップオーバー側でその名前を参照する(position-anchor)
- 配置方法を指定する(anchor()関数、またはposition-area)
ステップ1 anchor-nameで基準を作る
.trigger {
anchor-name: --trigger-anchor;
}
ここでの”–trigger-anchor”は任意の識別子です。CSS変数みたいな見た目ですが、アンカー名として使われます。
ステップ2 position-anchorで紐付ける
.menu {
position-anchor: --trigger-anchor;
}
これで.menuは.triggerを基準にできる状態になります。
ステップ3 位置を決める 2つの流儀
流儀A anchor()関数で座標を取る
アンカー要素の上端、下端、左端、右端、中央などを参照できます。
.menu {
position: absolute;
top: anchor(bottom);
left: anchor(left);
}
余白を足したいならcalcも普通に使えます。
.menu {
position: absolute;
top: calc(anchor(bottom) + 8px);
left: anchor(center);
transform: translateX(-50%);
}
流儀B position-areaでエリア指定する
block-endなら下、inline-endなら右、という感じで「どっち側に出すか」を宣言できます。書字方向も踏まえてくれるのが地味に良い。
.menu {
position-anchor: --trigger-anchor;
position-area: block-end;
}
右上に出したいなら組み合わせます。
.menu {
position-anchor: --trigger-anchor;
position-area: block-start inline-end;
}
実装例 HTMLとCSSだけでドロップダウンを作る
ここで一回、まとまった形を置きます。まずはシンプルに「ボタンの下に出るメニュー」です。
HTML
<div class="demo">
<button class="trigger" popovertarget="user-menu">ユーザーメニュー</button>
<div id="user-menu" class="menu" popover>
<ul>
<li><a href="#">プロフィール</a></li>
<li><a href="#">設定</a></li>
<li><a href="#">ログアウト</a></li>
</ul>
</div>
</div>
CSS
.trigger {
anchor-name: --user-trigger;
}
/* popoverはトップレイヤーに乗るので、positionの扱いが普段と少し違って見える場合があります */
.menu {
position-anchor: --user-trigger;
/* 分かりやすさ優先で下に出す */
position-area: block-end;
/* 見た目は適当に */
padding: 12px;
border: 1px solid #ddd;
border-radius: 10px;
background: #fff;
box-shadow: 0 8px 24px rgba(0,0,0,.12);
}
.menu ul {
margin: 0;
padding: 0;
list-style: none;
}
.menu li + li {
margin-top: 8px;
}
.menu a {
text-decoration: none;
}
JSゼロで、開閉と配置が成立します。スクロールやリサイズでズレたら自前で再計算、みたいな発想から距離を置けるのがポイント。
画面端でのはみ出し対策 position-try-fallbacksが効く
ポップオーバーは端っこで破綻しがちです。右端にいるのに右に出そうとして画面外へ、あるある。これをCSS側で「はみ出したら反転してね」と書けるのがposition-try-fallbacksです。
.menu {
position-anchor: --user-trigger;
position-area: block-end;
position-try-fallbacks: flip-block;
}
上下だけでなく左右も反転できます。
.menu {
position-anchor: --user-trigger;
position-area: inline-end;
position-try-fallbacks: flip-inline;
}
上下も左右も両方見たいなら並べます。
.menu {
position-anchor: --user-trigger;
position-area: block-end inline-end;
position-try-fallbacks: flip-block flip-inline;
}
このあたり、今までならJSで分岐していた領域です。CSSで宣言できるのがうれしい。
メリット こういう現場で刺さる
- 開閉ロジックとフォーカス管理を標準に寄せられる。アクセシビリティ対応の負担が下がる。
- 位置計算が減る。スクロールやリサイズで再計算、という発想を薄められる。
- ドロップダウンやサブメニューが、設計として単純になる。後から読む人が助かる。
- 小さなUIのために巨大なライブラリを抱えないで済む場面が増える。
個人的には、保守で効きます。半年後の自分が「これ誰が作ったんだよ」と言わない確率が上がる。大事。
デメリット 夢だけ見ていると足を取られる
- ブラウザ対応は揃ってきたとはいえ、社内端末や組み込みブラウザの事情で足踏みすることがある。
- Popoverはトップレイヤーに乗るため、既存のz-index運用やレイアウト前提と噛み合わないケースが出る。
- デザイン要件が特殊だと、結局JSが必要になる場面もある。アニメーションの細かい同期など。
- 実装チーム内で知識差があると、レビューで止まりやすい。新機能あるある。
とはいえ、全部が完璧でないのはいつものことです。必要なところから小さく入れるのが現実的。
やり方のコツ 既存実装から移行するならここを見る
1 まずはPopoverだけ導入してJSを削る
位置決めは後回しで良いです。まず開閉だけ標準に寄せる。イベントリスナーが減るだけでも価値があります。
2 位置計算が辛い箇所からAnchor Positioningへ
ヘッダーのユーザーメニュー、カードの三点リーダー、タスクのサブメニュー。頻出で、かつ画面端問題が起きやすいところが狙い目。
3 フォールバックを早めに決める
ブラウザ未対応や古い環境が混ざるなら、段階的に対応します。
- 未対応時は単純な位置固定にする
- 未対応時は従来JSにフォールバックする
- そもそも未対応ブラウザを対象外にする
どれが正しいかはプロダクト次第。あなたの現場、IEの亡霊がまだいますか。いますよね、たまに。
忙しい人向け 最小セットだけ覚える
- button側: popovertargetで紐付ける
- popover側: popover属性を付ける
- 基準側: anchor-nameで名前を付ける
- 追従側: position-anchorで参照する
- 配置: position-areaかanchor()で指定する
- はみ出し: position-try-fallbacksで反転
関連して役に立つ知識 ポップオーバー実装の地雷回避
クリックで閉じる動きとフォームの相性
ポップオーバーの中にフォームが入ると、入力中に外側クリック扱いで閉じてしまう事故が起きがちです。Popover APIの動作を理解した上で、UI設計として「閉じない」動作が必要かを先に決めるのが安全。
アクセシビリティは後付けしない
ポップオーバーはフォーカスの扱いが全て、と言ってもいい。標準機能の恩恵が大きい領域なので、カスタム実装で頑張るほど失点しやすい。ここは好みよりも勝率を取りたいところです。
既存のライブラリを全否定しない
Popper系のライブラリが不要になる場面は増えます。けれど、複雑な衝突回避や高度なレイアウト最適化が必要なら、成熟したライブラリがまだ強い。標準で足りるか、ライブラリが必要か。見極めが腕の見せどころ。
この話が好きなら 次に読むと楽しい作品たち
映画の話ではありません。実装の話です。UIの体験は細部で決まるので。
- Dialog要素: モーダルの標準化で同じく救われる領域
- details/summary: アコーディオンを標準に寄せると保守が軽い
- inert属性: モーダルやポップオーバーと一緒に語ると強い
- prefers-reduced-motion: アニメーションを盛りたい人ほど一度は向き合う
ポップオーバーは小物です。だけど、サイトの印象を左右する小物でもある。小物をラクに作れる環境が整ってきた。2026年はこの波に乗ると気持ちいいです。

