11 人が閲覧(直近 30 日) 開発

CSS Anchor Positioningの使い方|position-area・@position-tryと対応ブラウザ

CSS Anchor Positioningの使い方|position-area・@position-tryと対応ブラウザ

CSS Anchor Positioning(アンカーポジショニング)は、ある要素(アンカー)の位置と大きさを基準に、別の要素をCSSだけで配置する仕組みです。ツールチップ、ドロップダウン、入力欄の横に出すエラーメッセージなど、これまでgetBoundingClientRect()とスクロール監視のJavaScriptで追従させていたUIを、宣言だけで書けます。Chrome・Edge 125(2024年5月)、Safari 26(2025年9月)、Firefox 147(2026年1月13日)で主要3エンジンがそろいました。この記事では、最小コードから画面端のはみ出し対策、Chrome 157で動かして確認した「効かない」原因、ポリフィルで補えない機能までを順に扱います。本文の実測値は、Chrome 157.0.8103.40(macOS・ヘッドレス実行・表示領域800×600px)で各コードを動かし、要素の座標をgetBoundingClientRect()で読み取ったものです。

まとめ:CSS Anchor Positioningの要点

  • アンカー側にanchor-name: --名前、配置する側にposition: absolute(またはfixed)とposition-anchor: --名前を書けば結びつきます。
  • 置き場所はposition-area: topのような9分割グリッドのキーワードで指定するのが最短です。辺単位で細かく合わせたいときはtop: anchor(bottom)のようにanchor()を使います。
  • 画面端で隠れる問題はposition-try-fallbacks: flip-blockで反転させます。指定しないと、Chrome 157ではツールチップが画面内へ押し戻されてアンカーに重なりました。
  • 同じanchor-nameを一覧の各行に付けると、Chrome 157ではすべての配置要素が最後の行に付きます。行ごとに付けたいなら親にanchor-scopeを指定します。
  • 主要機能はFirefox 147が出た2026年1月13日にBaseline(新たに利用可能)になりました。position-try-orderはFirefox 148から使えます。
  • popoverにはposition-anchor: autoを書いておきます。初期値normalのままだと、anchor()だけで置いたpopoverはChrome 157で暗黙アンカーを使わず、初期値がnoneだったChrome 144〜150ではposition-areaでも付きません。
  • Chrome 124以前などの非対応環境には@oddbird/css-anchor-positioning(0.10.2)がありますが、position-try-order・anchor-center・position-visibility・popoverの暗黙アンカーは補えません。

CSS Anchor Positioningの仕組みと最小コード

登場するのは2つの要素です。基準になるアンカー要素と、アンカーに合わせて置かれる配置要素(anchor-positioned element)です。配置要素は絶対配置(absoluteかfixed)でなければならず、通常のフローにある要素はアンカーに追従しません。

anchor-nameとposition-anchorで結ぶ2ステップ

アンカー名は--で始まる任意の識別子(dashed-ident)です。次のコードで、ボタンの真上にツールチップが付きます。

.btn {
  anchor-name: --btn;
}
.tooltip {
  position: absolute;
  position-anchor: --btn;
  position-area: top;
  margin: 0;
}

Chrome 157で、ボタンを上端200px・高さ40pxに置いて実行すると、ツールチップ(高さ30px)は上端170px・下端200pxに描画され、下端がボタンの上端と一致しました。アンカー要素自身はpositionを持つ必要がなく、通常のフローに置いたままで構いません。

popoverの暗黙アンカー(anchor-name不要)

popovertarget属性でpopoverを開くと、押したボタンが暗黙のアンカーになります。anchor-nameは書かずに済み、配置要素にposition-anchor: autoを書けば押したボタンが基準になります。この関連付けはChrome 133、Firefox 147、Safari 26で使えます。現行版(Chrome 151以降など)ではposition-areaを使うならposition-anchorも省略できますが、初期値がnoneだったChrome 144〜150では省略すると付かないため、下の例では明示しています。

<button popovertarget="menu">メニュー</button>
<div id="menu" popover>…</div>
#menu {
  position-anchor: auto;
  position-area: bottom span-right;
  margin: 0;
}

popoverにはブラウザ既定でmargin: autoが付いており、Chrome 157でposition-areaを書かずに開くと画面中央(上端285px)に表示されました。仕様ではposition-areaかanchor-centerが効いている間はautoマージンを0として扱い、Chrome 157ではmarginを書かなくてもボタン直下(ボタン下端240px=popover上端240px)に付きました。ただしこの扱いはChrome 143・Firefox 148・Safari 26.2からの実装で、それより前の版やanchor()で位置を書く場合は働きません。上の例のようにmargin: 0を明示しておくと版を問わず同じ位置になります。JavaScriptからshowPopover({ source: 要素 })で開いたときも、sourceに渡した要素がアンカーになります。

position-areaを使わずtop: anchor(bottom)のようにanchor()だけで置く場合は、position-anchor: autoを明示します。position-anchorの初期値normal(Chrome 151・Firefox 151・Safari 27から)は、position-areaが指定されているときだけ暗黙アンカーを使う値だからです。Chrome 157で確かめると、anchor()だけのpopoverは暗黙アンカーを使わずフォールバック値(上端11px・左端13px)に置かれ、position-anchor: autoを足したpopoverはボタンの下端(400〜440pxのボタンに対し上端440px)に付きました。Firefox 151のリリースノートも、popoverでanchor()やanchor-centerを使うにはposition-anchor: autoが必要になったと書いています。ボタンからpopoverやdialogを開く宣言的な書き方はInvoker Commands APIの使い方と対応ブラウザで詳しく扱っています。

interestforによるホバーで開くツールチップ(Chromeのみ)

Chrome 142(2025年10月28日)で、<button>と<a>にinterestfor属性が入りました(Chrome 142のリリースノート)。ホバーやフォーカスでpopoverを開く宣言で、Chromeのガイドのとおり、開いたボタンがpopoverの暗黙アンカーになります。

<button interestfor="tip">保存</button>
<div id="tip" popover="hint">Ctrl+S</div>
#tip {
  position-anchor: auto;
  position-area: top;
  margin: 0;
}

Chrome 157でボタン(上端200px・中心x360px)にマウスを乗せ、1.5秒後に確かめるとツールチップは開いており、下端200px・中心x360pxでボタンの真上に付いていました。表示までの待ち時間はinterest-delayプロパティで変えられます。MDN browser-compat-data 8.1.8ではFirefoxとSafariが未対応で、そこではツールチップが開きません。ショートカットのような補足は、ボタンのaria-describedbyから参照するなど、ツールチップが出なくても読める形で置いておきます。

配置の指定:position-areaとanchor()の使い分け

位置の指定方法は2つあります。上下左右のどこに出すかだけ決めたいならposition-area、アンカーの特定の辺から何pxずらすかまで決めたいならanchor()です。

position-areaの3×3グリッドとspanキーワード

position-areaは、アンカーを中央マスとする3×3のグリッドを想定し、配置要素を置くマスをキーワードで選びます。topのように1語だけ書くと、もう一方の軸はspan-allとして扱われ、アンカーの幅を中心にした位置に収まります。2マス分に広げるときはspan-付きのキーワードを使います。

指定 表示される位置 典型的な用途
top アンカーの真上・中央揃え ツールチップ
bottom span-right 真下・アンカー左端から右へ ドロップダウン
right 右隣・上下中央 入力欄のエラー表示
top right 右上の角 通知バッジ
block-end span-inline-end ブロック方向の終端側・インライン方向の終端側へ 縦書き・RTL対応

2024年の解説には旧名のinset-areaで書かれたものがあり、今のブラウザでは無視されます(後述の旧構文の表を参照)。

anchor()で辺を指定する書き方とフォールバック値

anchor()はアンカーの辺の座標を長さとして返す関数で、top・left・insetなどインセット系のプロパティの中でしか使えません。第1引数にアンカー名(省略するとposition-anchorの既定アンカー)、第2引数に辺(top・bottom・start・end・center・inside・outside・50%など)、第3引数にアンカーが見つからないときの値を書きます。

.menu {
  position: absolute;
  top: calc(anchor(--select bottom) + 8px);
  left: anchor(--select left, 20px);
}

アンカーとの間に隙間を空けたいときは、上のようにcalc()で足すか、配置要素にmargin-top: 8pxを付けます。第3引数のフォールバックは、Chrome 157で存在しない名前--missingを指定したときに実際に使われ、top: anchor(--missing bottom, 10px)の要素は上端10pxに置かれました。フォールバックを書かない場合、その宣言は無効になりautoとして扱われます。

複数のアンカーを1つの配置要素で参照する書き方

anchor()の第1引数にアンカー名を書けば、辺ごとに別のアンカーを参照できます。2つの要素の間を線や枠で結ぶUIは、次のように書けます。

.a { anchor-name: --a; }
.b { anchor-name: --b; }
.connector {
  position: absolute;
  left: anchor(--a right);
  right: anchor(--b left);
  top: anchor(--a bottom);
  bottom: anchor(--b top);
}

Chrome 157で、Aを左端50px・幅60px・下端130px、Bを左端500px・上端220pxに置くと、.connectorは横110〜500px・縦130〜220pxの矩形になり、Aの右下角からBの左上角までを埋めました。anchor-size(--a width)のように、寸法の参照先にもアンカー名を指定できます。一方、position-areaは既定アンカー(position-anchorで指定した1つ)しか基準にできないので、複数のアンカーをまたぐ配置はanchor()で書きます。

anchor-centerによる中央揃え

position-areaを使わずにanchor()で上下だけ決め、左右はアンカーの中央にそろえたい場面ではjustify-self: anchor-centerを使います。Chrome 157では、中心x座標360pxのボタンに対し、幅60pxのツールチップの中心も360pxになりました。

.tooltip {
  position: absolute;
  position-anchor: --btn;
  bottom: anchor(top);
  justify-self: anchor-center;
}

2026年3月27日の作業草案で、anchor-centerはalign-items・justify-itemsからは削除されました(絶対配置の要素には効かないため)。justify-self・align-self・place-selfに書きます。

anchor-size()によるドロップダウンの幅合わせ

anchor-size()はアンカーの幅や高さを返す関数です。セレクトボックス風のメニューを、開く元のボタンと同じ幅にするのが代表的な使い方です。

.select {
  anchor-name: --select;
}
.listbox {
  position: absolute;
  position-anchor: --select;
  top: anchor(bottom);
  left: anchor(left);
  width: anchor-size(width);
  box-sizing: border-box;
  margin: 0;
}

Chrome 157で幅237pxのアンカーに対して実行すると、メニューの幅も237pxになり、上端はアンカーの下端(130px)に一致しました。anchor-size(width)が返すのはアンカーの枠線を含む外寸なので、メニューにパディングや枠線を付けるときはbox-sizing: border-boxで外寸をそろえます。引数にはwidth・heightのほか、書字方向に追従するinline・block・self-inline・self-blockを書けます。widthやmax-heightなど寸法系では最初から使え、topなどのインセットやmarginで使えるようになったのはChrome 132からです(Firefox 147・Safari 26は最初から対応)。

画面端でのはみ出し対策:position-try-fallbacksと@position-try

アンカー付きUIでいちばん手間がかかるのは、画面の端でツールチップが切れる問題です。CSS Anchor Positioningでは、はみ出したときに試す代わりの配置をposition-try-fallbacksに並べておきます。

flip-block・flip-inlineによる配置の反転

.tooltip {
  position: fixed;
  position-anchor: --btn;
  position-area: top;
  position-try-fallbacks: flip-block;
  margin: 0;
}

flip-blockはブロック方向(横書きでは上下)、flip-inlineはインライン方向(左右)を反転します。flip-block, flip-inlineのようにカンマで並べると順に試し、flip-block flip-inlineのように空白でつなぐと両方向を同時に反転した配置を1つの候補にします。topやright span-bottomなどposition-areaのキーワードをそのまま候補に書くこともできます。物理方向で反転するflip-x・flip-yはChrome 144・Firefox 147・Safari 26.2から使えます。

効果はChrome 157で確かめました。ボタンを画面上端から5〜45pxに置くと、flip-block付きのツールチップはボタンの下(45〜75px)に回りました。指定しなかったツールチップは0〜30pxに描画され、ボタンに重なりました。position-areaで置いた要素は、はみ出す代わりに包含ブロックの内側へ押し戻されるためです。はみ出しうるUIにはposition-try-fallbacksを付け、上下どちらにも収まらない画面幅も想定して寸法を決めておきます。

@position-tryによる独自の配置候補の定義

反転だけでは足りない場合、@position-tryで候補を名前付きで定義します。中に書けるのは位置・寸法・マージン・position-anchor・position-area・self系の配置に関わるプロパティだけで、色やフォントは書けません。

@position-try --left-narrow {
  position-area: left;
  max-width: 160px;
}
.tooltip {
  position-area: top;
  position-try-fallbacks: flip-block, --left-narrow;
}

上の例では、まず上に置き、収まらなければ下、それでも収まらなければ左に最大幅160pxで出します。どの候補でも収まらない場合は、元の配置(直前に収まった候補があればその候補)のままになり、はみ出しは解消されません。スクロール表示にする場合は、通常ルールでoverflow: autoを指定し、候補側ではmax-heightやmax-widthを使って、狭い画面でも必ず収まる寸法にしておきます。

position-try-orderによる空きの大きい側の優先

position-try-fallbacksは通常、書いた順に試して最初に収まった候補を使います。position-try-order: most-height(またはmost-width・most-block-size・most-inline-size)を付けると、元の配置と候補の中から、使える高さ(幅)が最も大きいものを優先します。

.listbox {
  position-area: top;
  position-try-fallbacks: flip-block;
  position-try-order: most-height;
}

Chrome 157で高さ600pxの画面に置き、ボタンを150〜190pxに配置したところ、既定(normal)では上に収まるので上(120〜150px)に出て、most-heightでは下の方が広いため下(190〜220px)に出ました。項目数が多いドロップダウンを広い側に開きたいときに使います。position-try-orderはChrome 125、Firefox 148、Safari 26から対応しています。

position-visibilityによる配置要素の表示制御

スクロール領域の中にアンカーがあり、配置要素がposition: fixedで外に出ている構成では、アンカーがスクロールで見えなくなっても配置要素だけが残ることがあります。これを制御するのがposition-visibilityです。

値 非表示になる条件
always 非表示にしない
anchor-visible(旧名anchors-visible) 既定アンカーがスクロール等で完全に隠れた
anchor-valid(旧名anchors-valid) 既定アンカーが見つからない
no-overflow どの候補でも包含ブロックからはみ出す

Chrome 157の初期値はanchor-visibleです。高さ200pxのスクロール領域の中のアンカーを、スクロールで領域の外(領域上端300pxに対しアンカー上端220px)に出すと、初期値のツールチップは描画されず(スクリーンショットで該当位置が白)、alwaysを指定したツールチップはアンカーから離れたまま表示され続けました。このときcheckVisibility()は初期値の側でもtrueを返すので、隠れたかどうかをスクリプトで判定する用途には使えません。

値の名前は、仕様のChanges節にあるとおり2026年9月6日の作業草案で、既定アンカーだけを見る値であることに合わせて単数形のanchor-visible・anchor-validに改称されました。対応はブラウザごとに分かれています。

  • Chrome 157:新名のanchor-visible・anchor-validを受け付け、旧名はanchors-visibleだけがCSS.supports()でtrue、anchors-validはfalseでした。以前検証したChrome 154では新名がfalseで、初期値もanchors-visibleでした。
  • Safari 27:新名に対応しています(Safari 26.2〜は旧名)。
  • Firefox:旧名だけに対応しています(MDN browser-compat-data 8.1.8)。

アンカーが隠れたら消す挙動は初期値で得られるので、多くの場合は何も書かないのが安全です。anchor-valid系を明示したいときは、旧名と新名を続けて書けば、新名を解釈できないブラウザは後の宣言を無視して旧名を使います。ただしChrome 156以前はanchors-validを出荷しておらず(browser-compat-dataではプレビュー版のみ)、どちらの宣言も無視されます。

.tooltip {
  position-visibility: anchors-valid;
  position-visibility: anchor-valid;
}

アンカーが動いたときの追従:スクロールとtransform

配置要素はアンカーの位置が変わると、スクリプト無しで付いていきます。ただしスクロールに合わせて動くのは既定アンカー(position-anchorで指定したアンカー)だけです。仕様の3.3節により、anchor()で別のアンカーを参照した辺は、表示した時点とフォールバックを切り替えた時点のスクロール位置で計算され、その後のスクロールには付いてきません。前の章の複数アンカーの例を別々のスクロール領域で使う場合は注意してください。

スクロール領域の中のアンカーへの追従

高さ200pxのスクロール領域の中にボタンを置き、配置要素は領域の外にposition: fixedで置きました。Chrome 157でスクロール量を0→50→180pxと変えると、アンカーの上端400→350→220pxに対し、配置要素の上端も410→360→230pxと同じ量だけ動きました。最後に配置要素が消えたのはposition-visibilityの初期値によるものです。

transformで動かしたアンカーへの追従

アンカーにtransform: translateX(100px)を付けると、Chrome 157ではツールチップも左端320pxから420pxへ100px動き、見た目のアンカーの真上に付きました。仕様は「アンカーの位置と大きさはレイアウトの後で決まる」としており、MDNのbrowser-compat-data 8.1.8では、transformやzoomを反映する挙動はChrome 144・Safari 27から対応、Firefoxは未対応です。Firefoxや古い版では、transformで動かす前の位置に配置要素が付くので、アンカーをtransformのアニメーションで動かすUIは対象ブラウザで確認してください。

アンカーが効かないときの確認点(Chrome 157で実測)

CSSに誤りが無いのに配置要素が動かないときは、アンカーが参照可能な条件を満たしているかを確認します。

同名アンカーの参照先とanchor-scopeによる区切り

一覧の各行に同じanchor-name: --itemを付け、行の中にposition-anchor: --itemのツールチップを置くと、Chrome 157では3行すべてのツールチップが3行目(最後の要素)の横に集まりました。CSS Anchor Positioning Level 1の仕様は2026年1月30日の作業草案で「祖先にあるアンカーを優先する」探索に変わりましたが、Chrome 157ではこの変更がまだ反映されておらず、文書順で最後の要素が選ばれます。

行ごとに付けるには、行の要素にanchor-scopeを指定して名前の有効範囲を区切ります。

.row {
  anchor-scope: --item;
}
.row .item {
  anchor-name: --item;
}
.row .tooltip {
  position: absolute;
  position-anchor: --item;
  position-area: right;
}

Chrome 157では、anchor-scopeを付けた2行(上端150px・210px)のツールチップがそれぞれの行(155px・215px)に付き、付けていない2行は両方とも2行目に付きました。anchor-scope: allとすれば、その要素以下で定義されるすべてのアンカー名を区切れます。anchor-scopeはChrome 131、Firefox 147、Safari 26から使えます。

絶対配置どうしの文書順と包含ブロックの制約

アンカーは配置要素より先にレイアウトされる必要があります。同じ包含ブロックの中で両方が絶対配置のとき、アンカーが文書順で後ろにあると参照できません。Chrome 157でツールチップをアンカーより前に書いたところ、anchor()は解決されず、第3引数のフォールバック値(上端7px・左端9px)で配置されました。アンカーが絶対配置でない通常の要素なら順序の制約は受けませんが、両方を絶対配置にする場合はアンカーを先に書くと覚えておくと迷いません。

包含ブロックにも注意が必要です。通常のposition: absoluteでは、包含ブロックを作る最も近い祖先(position: relativeなど)が基準になり、position-areaの領域もフォールバックの判定もその内側に限られます。小さな親の中では上下どちらにも収まらず、アンカーに重なります(後述の@supportsの例でChrome 157の実測値を示します)。ほかに、content-visibility: hiddenなどで描画が省略された要素の中にアンカーだけがあり、配置要素はその外にある場合も参照できません。

旧構文の名前と置き換え先

2024年以前の記事やデモには、仕様策定中の名前が残っています。Chromeは構文変更の告知で旧名を移行期間の後に外すとしており、次の旧名はChrome 157のCSS.supports()でfalseでした。

旧名 現行の名前 Chromeでの切替
inset-area position-area Chrome 129
position-try-options position-try-fallbacks Chrome 128
inset-area()関数 キーワードを直接書く Chrome 129

対応ブラウザとBaselineの状況(2026年11月時点)

MDNのbrowser-compat-data 8.1.8(2026年11月2日)で確認した対応バージョンです。EdgeはChromeと同じ番号です。

機能 Chrome・Edge Firefox Safari
anchor-name・anchor()・anchor-size() 125 147 26
position-try-fallbacks 128 147 26
position-area 129 147 26
anchor-scope 131 147 26
popoverの暗黙アンカー 133 147 26
interestfor(ホバーで開くpopover) 142 未対応 未対応
position-try-order 125 148 26
position-visibility 125 147 26.2
anchor-visible・anchor-valid(単数形の新名) 157 未対応 27
アンカーのtransformを反映 144 未対応 27
position-anchor: normal(新しい初期値) 151 151 27
アンカー位置クエリ(@container anchored()) 143 未対応 未対応

web-featuresのデータでは、主要部分はFirefox 147がリリースされた2026年1月13日にBaseline「新たに利用可能」になっています。Baselineの段階と確認方法はWeb Platform Baselineの3つの状態と対応ブラウザにまとめています。

ただし機能全体(web-featuresのanchor-positioning)としては、2026年11月時点でまだBaselineの判定が付いていません。前の章で触れたposition-visibilityの新しい値anchor-visible・anchor-validにFirefoxが対応していないためです(web-features 3.45.0の時点で対応がSafari 27だけと記録されており、Chrome 157の対応はまだ反映されていません)。position-anchorの初期値も、Chromeではimplicit(125〜126)→auto(127〜143)→none(144〜150)→normal(151〜)と変わっています。normalは「position-areaを指定していればauto(暗黙アンカーを使う)、指定していなければnone」という意味で、popoverにposition-areaを書くだけで呼び出し元に付く挙動はこの値によるものです。

配置要素にどのフォールバック候補が適用されたかを@container anchored(fallback: …)で判定し、配置要素の中身(吹き出しの矢印の向きなど)のスタイルを切り替えるアンカー位置クエリ(container-type: anchored)はChromeだけの実装です。サイズで切り替える通常のコンテナクエリはCSSコンテナクエリ(@container)の使い方を参照してください。

非対応環境の対策:@supportsとポリフィル

@supportsによる機能検出と段階的適用

対象ブラウザに古い版が残る場合は、アンカー関連の宣言を@supportsで囲み、非対応環境では従来の固定位置で表示します。

<span class="field">
  <button class="btn">保存</button>
  <span class="tooltip">Ctrl+S</span>
</span>
.field {
  position: relative;
  display: inline-block;
}
.btn {
  anchor-name: --btn;
}
.tooltip {
  position: absolute;
  top: 100%;
  left: 0;
  margin: 0;
}
@supports (position-area: top) and (position-try-fallbacks: flip-block) {
  .tooltip {
    position: fixed;
    top: auto;
    left: auto;
    position-anchor: --btn;
    position-area: top;
    position-try-fallbacks: flip-block;
  }
}

非対応環境では.fieldを包含ブロックにしてボタンの直下に出し、対応環境だけアンカー基準の配置と反転を有効にします。判定にanchor-nameではなくposition-areaとposition-try-fallbacksを使うのは、Chrome 125〜128がanchor-nameに対応していても現行名のposition-areaを持たず、判定だけ通って配置が崩れるためです。

@supportsの中でposition: fixedに切り替えているのにも理由があります。Chrome 157でabsoluteのまま試すと、position-areaの領域が包含ブロックの.field(ボタンと同じ高さ)の内側に制限され、上にも下にも収まらずにツールチップがボタンに重なりました(ボタン200〜240pxに対しツールチップ200〜230px)。fixedにすると包含ブロックが表示領域になり、ボタンの上(170〜200px)に付きました。

@oddbird/css-anchor-positioningの導入と未対応機能

OddBirdのポリフィル@oddbird/css-anchor-positioningは、npmの公開記録で2026年8月18日の0.10.2が最新です。READMEは次のように、ネイティブ対応が無いときだけ読み込む書き方を案内しています。

<script type="module">
  if (!("anchorName" in document.documentElement.style)) {
    import("https://unpkg.com/@oddbird/[email protected]");
  }
</script>

導入前に、GitHubのREADMEの「Limitations」に挙がっている未対応機能を確認してください。2026年11月時点(0.10.2が最新のまま)で次のものは補えません。

  • position-try-order(position-tryの短縮記法に書いても無視される)
  • anchor-centerとposition-visibility
  • popoverの暗黙アンカーとposition-anchor: auto
  • 読み込み後に動的に追加・削除したアンカーや配置要素
  • 別々のシャドウルートにあるアンカーと配置要素

上の読み込み条件ではChrome 125以降にポリフィルが入らないため、Chrome 125〜128のposition-area、125〜130のanchor-scopeは補われません。暗黙アンカーや動的リストに依存するUIなら、ポリフィルより次の章のJavaScriptライブラリの方が確実です。

Floating UIなどJavaScriptライブラリとの使い分け

ツールチップの位置計算は、これまで@floating-ui/dom(2026年7月11日公開の1.8.0が最新)などのライブラリが担ってきました。CSS Anchor Positioningへ置き換えるかどうかは、次の基準で判断します。

  • CSSに置き換える:使う機能ごとの対応版(position-areaとposition-try-fallbacksならChrome 129・Firefox 147・Safari 26、position-try-orderならFirefox 148)を閲覧環境が満たしていて、表示位置の切替が上下左右の反転と候補リストで表現できる場合。スクロールやリサイズのたびの位置計算が不要になります。
  • ライブラリを残す:Safari 18以前やFirefox 146以前の利用者がいて、しかも仮想スクロールのように表示中にアンカーや配置要素を追加・削除するUIの場合。動的な追加・削除はポリフィルが補えません。ライブラリのミドルウェアで独自の位置補正(ずらす量の計算など)を書いている場合も、候補を並べる宣言では再現できないので残します。

アクセシビリティの関係はCSS側では作られません。仕様にも、Anchor Positioningは支援技術向けの関連付けを作らないと明記されています。ツールチップならaria-describedby、メニューならpopover属性やaria-expandedを、従来どおりHTML側で付けてください。属性の選び方はWAI-ARIAのrole・aria属性の使い方を参照してください。モーダルとして開く場合の要素選びはモーダル・ダイアログとの違いとdialog要素での実装が参考になります。

よくある質問

CSS Anchor PositioningはFirefoxやSafariで使えますか?

使えます。Firefoxは147(2026年1月13日)、Safariは26(2025年9月15日)で対応しました。ただしposition-try-orderと、position-area指定時にautoマージンを0として扱う挙動はFirefox 148からで、後者はSafariでも26.2からです。position-visibilityもSafariは26.2からです。アンカーのtransformを位置に反映する挙動とinterestforはFirefoxが未対応なので、使う機能ごとに対応表を確認してください。

アンカーと配置要素の間に隙間を空けるには?

配置要素にmarginを付けるか、top: calc(anchor(bottom) + 8px)のようにcalc()で加算します。position-areaを使う場合はmarginで空けるのが簡単です。

anchor-size()で何ができますか?

アンカーの幅・高さを取得して、配置要素のwidthやmax-heightに使えます。ドロップダウンをボタンと同じ幅にするのが典型例で、Chrome 132以降はtopやmarginでも使えます。

ポリフィルを入れれば古いブラウザでも同じように動きますか?

基本的な配置とposition-try-fallbacksは動きますが、position-try-order・anchor-center・position-visibility・popoverの暗黙アンカー・動的に追加した要素には対応していません(0.10.2時点)。

position-try-orderはいつ使いますか?

候補を書いた順ではなく、空きが大きい側を優先したいときです。most-heightを指定すると、上下のうち表示できる高さが大きい方に開くため、項目の多いメニューで役立ちます。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

RELATED POSTS 関連記事

目次