Design

ツールチップを JS なしで置く — Popover API と CSS Anchor Positioning の導入判断

ツールチップやポップオーバーの位置決めを、floating-ui のような JS ライブラリから Popover API と CSS Anchor Positioning へ移す導入判断を、運用者目線で書きます。2026 年のブラウザ対応の現実、最小コード、何を捨て何を得たかまで具体的に整理します。

2026年6月10日 12:05·11 min·SoraEndo
SoSoraEndo2026年6月10日 12:0511 min1,941

動画で読む

まず結論 — 2026 年なら、配置のための JS ライブラリは多くの場面で外せる

ツールチップやポップオーバーの「位置決め」は、2026 年現在、Popover API(ポップオーバー表示を担う HTML 標準)と CSS Anchor Positioning(要素を別要素に紐づけて配置する CSS)の組み合わせで、ほぼネイティブに書けます。floating-ui や Popper.js を入れていた理由の大半は、これで消えます。決め手はブラウザが出揃ったことです。Popover API は 2024 年に Baseline(主要ブラウザで広く使える状態)入りし、CSS Anchor Positioning も Firefox 147(2026 年 1 月 13 日の安定版)でようやく主要ブラウザが揃いました。

私はこのブログの管理画面に出していた小さなツールチップを、実際に native へ置き換えてみました。配置を計算する JS をまるごと削れて、バンドルも軽くなった。ただし「いつでも全部外せる」わけではありません。どこまで外せて、どこに保険を残すか。その線引きが運用者にとっての本題です。

Popover API と Anchor Positioning は「別々の半分」を解く

この 2 つは別の問題を解く道具です。混同すると確実に詰まります。Popover API は「出す・隠す」の表示制御の半分を、Anchor Positioning は「どこに置くか」の配置の半分を担当します。両方を組み合わせて初めて、ツールチップやドロップダウンが JS なしで完成します。

Popover API 側がやってくれるのは、トップレイヤー(最前面レイヤー、z-index の競争から降りられる)への描画、Esc キーでの閉じる、外側クリックでの light-dismiss(軽い消去)、そしてトリガーとの紐づけです。ボタンに popovertarget、出す側に popover 属性を書くだけで、開閉のロジックを自分で書く必要がなくなります。

Anchor Positioning 側は配置です。アンカーにしたい要素へ anchor-name を付け、出す側で position-anchor でそれを指し、anchor() 関数や position-area で「アンカーのどの辺に置くか」を宣言します。詳しい仕様は MDN の CSS anchor positioning が一次情報として正確です。CSS で「位置を解く」という発想は、以前書いた固定ヘッダと scroll-margin の話とも地続きで、JS に逃がさず宣言で済ませる流れの延長にあります。

実際に置いてみる — anchor-name から position-try まで

最小構成は驚くほど短いです。トリガーのボタンに popovertargetanchor-name、出す側に popoverposition-anchor を書く。これだけで開閉と紐づけが揃います。

<button popovertarget="menu" style="anchor-name: --trigger">開く</button>
<div id="menu" popover style="position-anchor: --trigger">
  メニューの中身
</div>

配置は CSS 側で宣言します。position-area: bottom center で「アンカーの真下中央」に置き、余白を margin で足すだけです。

[popover] {
  position-area: bottom center;
  margin-top: 8px;
}

画面端でのはみ出し対策も、かつては JS の見せ場でしたが、いまは position-try-fallbacks を 1 行足すだけで済みます。下に入りきらなければ上へ倒す、という反転をブラウザが勝手にやります。

[popover] {
  position-area: bottom center;
  position-try-fallbacks: flip-block, flip-inline;
}

flip-block が縦方向の反転、flip-inline が横方向の反転です。floating-ui で flip ミドルウェアを差し込んでいた処理が、CSS の 1 プロパティに畳まれた格好です。導入の温度感は Chrome for Developers のアナウンス記事が分かりやすく、実装例も豊富です。

ブラウザ対応の現実 — どこまで外せて、どこに保険を残すか

配置を完全に native へ寄せられるのは、対応バージョンがユーザーに行き渡ってからです。ここを楽観すると事故ります。表示制御の Popover API は早く、Chrome 114 / Safari 17 / Firefox 125 で 2024 年に Baseline 入り済み。一方の配置の Anchor Positioning は、もう少し新しいのが現実です。

機能Chrome / EdgeSafariFirefox
Popover API11417125
Anchor Positioning(基本)12518.2132
@position-try(反転)12518.4既定 ON は 147

ここで一晩溶かした失敗談を書きます。私は最初、検証を Safari 18.3 でやっていて、position-try が効かずポップが画面下にはみ出したまま反転しない現象を「自分の CSS のバグ」だと小一時間疑いました。実際には反転は Safari 18.4 以降の対応で、18.3 では配置はできても自動反転だけが来ていなかった。リリースノートを読めば一発で分かる話を、律儀に自分のせいにして溶かした夜でした。基本の配置と反転で対応バージョンが割れている、という一点は覚えておいて損がないです。

判断としては、新規に作る UI は native に寄せ、古い環境を踏むユーザーが多い面ではポリフィル(@oddbird/css-anchor-positioning)を条件付きで読み込む、という二段構えにしました。全ユーザーが最新ブラウザという前提を置けるなら保険は要りませんが、その前提が立つかは面ごとに違います。

運用者として何を捨て、何を得たか

得たものははっきりしています。ランタイムの JS ゼロ、最前面への描画、そしてキーボード操作やフォーカス管理(アクセシビリティ)が標準で付いてくること。自前で Esc 閉じや外側クリック検知を書いて、しかも詰めきれずに微妙なバグを残す、というお決まりの工程から解放されます。捨てたものもあります。floating-ui の shift(はみ出し時にスッと連続でスライドさせる挙動)のような、一部の動的な振る舞いは native では素直に再現できません。

この「書き味は floating-ui のまま、中身を native へ寄せる」橋渡しとして、css-anchor-kit という移行ライブラリが出ているのも面白いところです。codemod(コードの機械変換)で既存コードベースから移せると謳っていて、いきなり全部を手で剥がしたくない現場には現実的な選択肢に見えます。

私自身は、既存の floating-ui を全部剥がす作業はしませんでした。動いているものをわざわざ触る ROI が薄いからです。新規 UI からネイティブに倒し、既存は対応バージョンが完全に行き渡ったタイミングで段階的に、と決めました。この「やる・やらないを先に線引きする」考え方は、始める前にやめ方を決める運用や、勘ではなく測ってから自動化する話で書いてきたものと同じです。新しい標準が来ても、入れる判断の枠組みは変わりません。

よくある質問

Popover API と CSS Anchor Positioning は何が違うのですか?
解く問題が違います。Popover API は「出す・隠す・最前面表示・Esc や外側クリックで閉じる」という表示制御を担い、CSS Anchor Positioning は anchor-name や position-area で「どこに置くか」という配置を担います。両方を組み合わせて初めてツールチップが JS なしで完成します。
2026 年時点でブラウザ対応はどこまで進んでいますか?
Popover API は 2024 年に Baseline 入り済みです。CSS Anchor Positioning は Chrome/Edge 125、Safari 18.2、Firefox 132 から使え、Firefox 147(2026-01-13 安定版)で既定 ON になり主要ブラウザが出揃いました。ただし反転の @position-try は Safari 18.4 以降と、基本配置より対応が一歩遅れます。
floating-ui や Popper.js はもう不要になりますか?
多くの場面で外せますが、全部ではありません。shift のような連続スライド挙動など native で素直に再現できない動きは残ります。新規 UI は native に寄せ、既存は対応バージョンが行き渡ってから段階移行、という二段構えが現実的です。
古いブラウザへの対策はどうすればいいですか?
対応していない環境を踏むユーザーが多い面では、@oddbird/css-anchor-positioning などのポリフィルを条件付きで読み込みます。全ユーザーが最新ブラウザという前提を置ける面なら保険は不要で、面ごとに判断を分けるのが無駄がありません。

参考文献

  1. CSS anchor positioning — MDN Web Docs
  2. Introducing the CSS anchor positioning API — Chrome for Developers
  3. Popover API — MDN Web Docs
  4. floating-ui を CSS Anchor Positioning へ寄せる css-anchor-kit(mk668a / Zenn)

Reaction

Share

X (Twitter)