公開日: 2024 年 5 月 10 日
CSS Anchor Positioning API は、アンカーと呼ばれる他の要素に対してネイティブに要素を配置できるため、ウェブ開発に大きな変化をもたらします。この API は、メニュー、サブメニュー、ツールチップ、選択、ラベル、カード、設定ダイアログなど、多くのインターフェース機能の複雑なレイアウト要件を簡素化します。ブラウザにアンカー ポジショニングが組み込まれたことで、サードパーティ ライブラリに依存することなくレイヤ状のユーザー インターフェースを構築できるようになり、クリエイティブな可能性の幅が広がりました。
アンカー ポジショニングは Chrome 125 以降で利用できます。
基本コンセプト: アンカーと配置された要素
この API の中核にあるのは、「アンカー」と「配置された要素」の関係です。アンカーは、anchor-name
プロパティを使用して参照ポイントとして指定された要素です。配置された要素とは、position-anchor
プロパティを使用してアンカーに対して配置された要素、または配置ロジックで anchor-name
を明示的に使用して配置された要素です。
アンカーを設定する
アンカーの作成は簡単です。選択した要素に anchor-name プロパティを適用し、一意の ID を割り当てます。この一意の識別子には、CSS 変数と同様に二重ダッシュを先頭に追加する必要があります。
.anchor-button {
anchor-name: --anchor-el;
}
アンカー名を割り当てると、.anchor-button
はアンカーとして機能し、他の要素の配置を指示できるようになります。このアンカーを他の要素に接続するには、次のいずれかの方法を使用します。
暗黙的アンカー
アンカーを別の要素に接続する方法の 1 つは、次のコード例のように暗黙的なアンカーを使用する方法です。アンカーに接続する要素に position-anchor
プロパティを追加し、値としてアンカーの名前(この場合は --anchor-el
)を指定します。
.positioned-notice {
position-anchor: --anchor-el;
}
暗黙的なアンカー関係では、最初の引数でアンカー名を明示的に指定しなくても、anchor()
関数を使用して要素を配置できます。
.positioned-notice {
position-anchor: --anchor-el;
top: anchor(bottom);
}
明示的アンカー
または、アンカー関数でアンカー名を直接使用することもできます(例: top: anchor(--anchor-el bottom
)。これは「明示的アンカー」と呼ばれ、複数の要素を固定したい場合に便利です(後述)。
.positioned-notice {
top: anchor(--anchor-el bottom);
}
アンカーを基準とした要素の配置
<ph type="x-smartling-placeholder">アンカー ポジショニングは、CSS の絶対位置に基づいて構築されます。ポジショニングの値を使用するには、配置する要素に position: absolute
を追加する必要があります。次に、anchor()
関数を使用して位置の値を適用します。たとえば、アンカー要素をアンカー要素の左上に配置するには、次のように配置します。
.positioned-notice {
position-anchor: --anchor-el;
/* absolutely position the positioned element */
position: absolute;
/* position the right of the positioned element at the right edge of the anchor */
right: anchor(right);
/* position the bottom of the positioned element at the top edge of the anchor */
bottom: anchor(top);
}
これで、次の画像のように、1 つの要素が別の要素にアンカー付けされました。
これらの値に論理的な配置を使用する場合、同等の値は次のとおりです。
top
=inset-block-start
left
=inset-inline-start
bottom
=inset-block-end
right
=inset-inline-end
anchor-center
を使用して配置した要素を中央に配置する
アンカーが配置された要素をアンカーに対して中央に配置しやすくするために、anchor-center
という新しい値が追加されました。この値は、justify-self
、align-self
、justify-items
、align-items
の各プロパティで使用できます。
この例では、justify-self: anchor-center
を使用して、配置された要素がアンカーの上に中央寄せされるように、前の要素を変更します。
.positioned-notice {
position: absolute;
/* Anchor reference */
position-anchor: --anchor-el;
/* Position bottom of positioned elem at top of anchor */
bottom: anchor(top);
/* Center justification to the anchor */
justify-self: anchor-center;
}
複数のアンカー
要素は複数のアンカーにテザリングできます。つまり、場合によっては、複数のアンカーを基準として位置する位置値を設定する必要があります。これを行うには、anchor()
関数を使用して、参照するアンカーを最初の引数で明示的に指定します。次の例では、配置された要素の左上が 1 つのアンカーの右下に固定され、配置された要素の右下が 2 つ目のアンカーの左上に固定されています。
.anchored {
position: absolute;
top: anchor(--one bottom);
left: anchor(--one right);
right: anchor(--two left);
bottom: anchor(--two top);
}
inset-area
での位置
絶対位置からのデフォルトの方向配置に加えて、アンカー API には、インセット領域という新しいレイアウト メカニズムが含まれています。
インセット領域を使用すると、アンカー位置の要素をそれぞれのアンカーに対して簡単に配置できます。アンカー要素が中央にある 9 セルのグリッドで機能します。
9 セルのグリッドに表示されている、さまざまなインセット領域の配置オプション
絶対位置ではなくインセット領域を使用するには、物理値または論理値で inset-area
プロパティを使用します。例:
- 上部中央:
inset-area: top
またはinset-area: block-start
- 左中央:
inset-area: left
またはinset-area: inline-start
- 中央下:
inset-area: bottom
またはinset-area: block-end
- 右中央:
inset-area: right
またはinset-area: inline-end
anchor-size()
を使用して要素のサイズを設定する
anchor-size()
関数(こちらはアンカー ポジショニング API の一部)を使用すると、アンカーのサイズ(幅、高さ、インラインとブロックのサイズ)に基づいて、アンカーが配置された要素のサイズまたは配置を行うことができます。
次の CSS は、高さにこの関数を使用する例を示しています。calc()
関数内で anchor-size(height)
を使用して、ツールチップの最大高さをアンカーの高さの 2 倍に設定しています。
.positioned-notice {
position-anchor: --question-mark;
/* set max height of the tooltip to 2x height of the anchor */
max-height: calc(anchor-size(height) * 2);
}
ポップオーバーやダイアログなどの最上位レイヤ要素でアンカーを使用する
アンカーの配置は、popover
などの最上位レイヤ要素で非常に効果的です。および <dialog>
。これらの要素は DOM サブツリーの他の部分とは別のレイヤに配置されますが、アンカーの位置指定により、最上層にない要素をテザリングして戻したり、一緒にスクロールしたりできます。これは、レイヤ化されたインターフェースにとって大きなメリットです。
次の例では、ボタンを使用して一連のツールチップ ポップオーバーを開いています。ボタンがアンカーで、ツールチップが配置された要素です。配置された要素は、他のアンカー要素と同様にスタイル設定できます。この特定の例では、anchor-name
と position-anchor
は、ボタンとツールチップのインライン スタイルです。各アンカーには一意のアンカ名が必要であるため、動的コンテンツを生成する場合は、インライン化が最も簡単な方法です。
@position-try
でアンカーの位置を調整する
最初のアンカー位置を設定したら、アンカーがその包含ブロックの端に達している場合は、位置を調整します。代替アンカー位置を作成するには、position-try-options
プロパティとともに @position-try
ディレクティブを使用します。
次の例では、メニューの右側にサブメニューが表示されます。メニューとサブメニューは、トリガーボタンに固定されることが多いため、アンカー ポジショニング API と ポップオーバー属性を組み合わせて使用すると効果的です。
このサブメニューの横方向に十分なスペースがない場合は、メニューの下に移動できます。そのためには、まず初期位置を設定します。
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
}
次に、@position-try
を使用して、フォールバック アンカー位置を設定します。
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
最後に、2 つを position-try-options
で接続します。まとめると、次のようになります。
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
*/ connect with position-try options */
position-try-options: --bottom;
}
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
アンカー位置の自動切り替えのキーワード
上から下、左から右(またはその両方)に反転させるなど、基本的な調整を行っている場合は、カスタムの @position-try
宣言を作成する手順をスキップして、ブラウザでサポートされている組み込みの flip キーワード(flip-block
や flip-inline
など)を使用することもできます。これらはカスタムの @position-try
宣言の代用として機能し、組み合わせて使用できます。
position-try-options: flip-block, flip-inline, flip-block flip-inline;
フリップ キーワードを使用すると、アンカーコードを大幅に簡素化できます。数行のコードで、代替の位置を持つ完全な機能を備えたアンカーを作成できます。
#my-tooltip {
position-anchor: --question-mark;
inset-area: top;
position-try-options: flip-block;
}
position-visibility
(サブスクローラー内のアンカー用)
場合によっては、ページのサブスクローラー内に要素を固定する必要があります。そのような場合は、position-visibility
を使用してアンカーの表示 / 非表示を制御できます。アンカーはいつ固定されますか?いつ消えますか?この機能では、これらのオプションを管理できます。アンカーが画面外に移動するまで、配置された要素を画面内に表示する場合は、position-visibility: anchors-visible
を使用します。
#tooltip {
position: fixed;
position-anchor: --anchor-top-anchor;
position-visibility: anchors-visible;
bottom: anchor(top);
}
または、position-visibility: no-overflow
を使用して、アンカーがコンテナからはみ出さないようにします。
#tooltip {
position: absolute;
position-anchor: --anchor-top-anchor;
position-visibility: no-overflow;
bottom: anchor(top);
}
機能の検出とポリフィル
現時点ではブラウザのサポートが限定的であるため、この API を使用する場合は注意が必要です。まず、@supports
機能クエリを使用して、CSS で直接サポートを確認できます。そのためには、アンカー スタイルを次のようにラップします。
@supports (anchor-name: --myanchor) {
/* Anchor styles here */
}
さらに、Oddbird の CSS アンカー位置指定ポリフィルを使用してアンカー配置機能をポリフィルすることもできます。これは Firefox 54、Chrome 51、Edge 79、Safari 10 で動作します。このポリフィルは、基本的なアンカー位置機能のほとんどをサポートしていますが、現在の実装は完全ではなく、古い構文が含まれています。unpkg リンクを使用するか、パッケージ マネージャーで直接インポートできます。
アクセシビリティに関する注意事項
アンカー ポジショニング API を使用すると、要素を他の要素に対して配置できますが、要素間に有意なセマンティックな関係を本質的に作成することはありません。アンカー要素と配置された要素の間に実際にセマンティック関係がある場合(たとえば、配置された要素がアンカー テキストに関するサイドバー コメントである場合)、そのための 1 つの方法は、アンカー要素から配置された要素を指すように aria-details
を使用することです。スクリーン リーダー ソフトウェアは、Aria の詳細を処理する方法をまだ学習中ですが、サポートは改善中です。
<div class="anchor" aria-details="sidebar-comment">Main content</div>
<div class="positioned" id="sidebar-comment">Sidebar content</div>
.anchor {
anchor-name: --anchor;
}
.positioned {
position: fixed;
position-anchor: --anchor;
}
popover
属性または <dialog>
要素でアンカー ポジショニングを使用している場合、ブラウザは適切なユーザー補助のためにフォーカス ナビゲーションの修正を処理するため、ポップオーバーやダイアログを DOM 順に並べ替える必要はありません。詳しくは、仕様のユーザー補助に関する注記をご覧ください。
まとめ
これはまったく新しい機能です。皆様がこの機能を使ってどのようなものを構築されるか、楽しみにしております。これまでに、グラフの動的ラベル、コネクタ線、脚注、視覚的な相互参照など、コミュニティで優れたユースケースをいくつか見てきました。アンカーの配置をテストする際には、ぜひフィードバックをお寄せください。バグが見つかった場合は、お知らせください。