ポップアップが画面内に収まらない場合に自動的に表示位置を調整する CSS Anchor Positioning
CSS Anchor Positioning とは、特定の要素を Anchor(基準)としてツールチップなどの要素の位置を決定する機能の総称です。CSS Anchor Positioning を使用することで、Floating UI のように自動で画面内に表示されるツールチップやコンテキストメニューを実装できます。
CSS Anchor Positioning は 2024 年 4 月現在 Chrome Canary でのみ利用可能です。
CSS Anchor Positioning とは、特定の要素を Anchor(基準)としてツールチップなどの要素の位置を決定する機能の総称です。CSS Anchor Positioning を使用することで、Floating UI のように自動で画面内に表示されるツールチップやコンテキストメニューを実装できます。
ポップオーバーの表示位置を調整する
冒頭の動画で使用されたコードを見てみましょう。ツールチップとして表示される要素はポップオーバー APIを使用しています。
<button popovertarget="menu">Open</button>
<div popover id="menu">
<ul>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
</ul>
</div>
ポップオーバー API とは他のページコンテンツの上に表示されるポップオーバーコンテンツを表示するための標準的な仕組みです。HTML 属性を用いて宣言的にポップオーバーの表示非表示を切り替えられるという特徴があります。
ポップオーバーの表示を制御するための要素に対して popovertarget
属性を指定します。この属性の値には、ポップオーバー要素の id
を指定します。ポップオーバー要素には popover
属性を指定します。popovertarget
属性を指定した要素をクリックするたびに、popover
属性を指定した要素の表示・非表示が切り替わります。
上記のコード例を実行すると、「Open」ボタンをクリックしたタイミングでポップオーバーが表示されることが確認できます。このとき、ポップオーバー要素はブラウザのデフォルトのスタイルシートにより画面の中央に表示されます。
CSS スタイルを追加してポップオーバーの表示位置を修正できますが、ここでは CSS Anchor Positioning を使用してポップオーバーを表示する位置を指定しましょう。まずはポップオーバーの表示位置の基準となるアンカー要素を定義する必要があります。アンカー要素を定義するためには以下の 2 つの方法があります。
- CSS プロパティ
anchor-name
を設定する - HTML 属性
anchor
を設定する
CSS プロパティ anchor-name
を使用する場合、アンカー要素の名前 CSS 変数と同じ命名規則(dashed-ident)を使用します。
.anchor {
anchor-name: --my-anchor;
}
HTML 属性 anchor
を使用する場合、アンカー要素とする要素の id
を指定します。これにより暗黙的なアンカーが定義されます。
<button id="trigger" popovertarget="menu">Open</button>
<div popover id="menu" anchor="trigger">
<ul>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
</ul>
</div>
アンカーを作成することで、以下のようにポップオーバーがアンカー要素の近くに表示されるようになります。
さらに CSS の anchor()
関数を使用することで、アンカー要素の位置を指定できます。anchor()
関数は以下の 3 つの引数を受け付けます。
- アンカー要素:CSS プロパティ
anchor-name
で定義したアンカー要素の名前。HTML 属性による暗黙的なアンカーを使用している場合には、この値を省略する - アンカーの位置:アンカー要素の位置を指定するキーワード。以下の値を受け取る
inside
,outside
:inside
はアンカー要素の内側、outside
は外側に配置するtop
,right
,bottom
,left
:アンカー要素の上下左右の位置start
,end
,self-start
,self-end
:論理プロパティによるアンカー要素の位置指定50%
のようなパーセンテージ値を指定する
- フォールバック:引数に不正な値が指定された場合に使用する値
以下の CSS は、アンカー要素の右から 12px 離れた位置にポップオーバーを表示するスタイルを定義しています。
[popover] {
top: anchor(top);
left: calc(anchor(right) + 12px);
}
position-try-options によるフォールバック
ここまでは固定的な値を用いてポップオーバーの位置を指定してきましたが、現実のユースケースではポップオーバーをトリガーする要素の位置に合わせてポップオーバーが表示される位置を調整することが求められます。例えば、以下のようにボタンが画面の右端に配置されている場合、ポップオーバーが画面外に表示されてしまう問題が発生します。
従来まではこの問題は JavaScript を使用して解決する必要がありました。CSS Anchor Positioning では position-try-options
というプロパティを使用することで、ポップオーバーの表示位置を調整できます。position-try-options
プロパティは絶対位置に配置された要素が包含ブロックを超える場合に、代替の位置を指定するためのプロパティです。
この要素は @position-try
で定義されたルールを使用するあるいは、あらかじめ定義された以下のキーワードのいずれかを使用できます。
flip-block
:ブロック軸に関するプロパティ(例:margin-block-start
,margin-block-end
)を反転させるflip-inline
:インライン軸に関するプロパティ(例:margin-inline-start
,margin-inline-end
)を反転させるflip-start
:start
とend
の値を反転させる(例:margin-block-start
,margin-inline-start
)
これらの値は複数指定できます。以下のように position-try-options
プロパティを使用すると、ポップオーバーが画面内に収まらない場合に自動的に表示位置が反転されるようになります。
[popover] {
top: anchor(top);
left: calc(anchor(right) + 12px);
position-try-options: flip-block flip-inline;
}
まとめ
- CSS Anchor Positioning を使用することで、アンカー要素を基準にして要素の位置を指定できる
- アンカー要素を定義するためには CSS プロパティ
anchor-name
または HTML 属性anchor
を使用する - アンカー要素を元にポップオーバーの表示位置を調整するために
anchor()
関数を使用する position-try-options
プロパティを使用することで、ポップオーバーが画面内に収まらない場合に自動的に表示位置を調整できる