CSS アンカー ポジショニング API のご紹介

公開日: 2024 年 5 月 10 日

CSS アンカー ポジショニング API は、ウェブ開発における画期的な機能です。この API を使用すると、アンカーと呼ばれる他の要素を基準として要素をネイティブに配置できます。この API は、メニューやサブメニュー、ツールチップ、選択、ラベル、カード、設定ダイアログなど、多くのインターフェース機能の複雑なレイアウト要件を簡素化します。ブラウザにアンカー ポジショニングが組み込まれることで、サードパーティ ライブラリに依存せずにレイヤード ユーザー インターフェースを構築できるようになり、クリエイティブな可能性が広がります。

アンカーの配置は Chrome 125 以降で利用できます。

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox Technology Preview: supported.
  • Safari: 26.

Source

コアコンセプト: アンカーと位置指定要素

この API の中心にあるのは、アンカー配置された要素の関係です。アンカーは、anchor-name プロパティを使用して参照点として指定された要素です。配置された要素とは、position-anchor プロパティを使用してアンカーに対して相対的に配置された要素、または配置ロジックで anchor-name を明示的に使用して配置された要素です。

アンカー要素と位置指定要素。

アンカーを設定する

アンカーの作成は簡単です。選択した要素に anchor-name プロパティを適用し、一意の識別子を割り当てます。この一意の識別子には、CSS 変数と同様に、二重ダッシュを前に付加する必要があります。

.anchor-button {
    anchor-name: --anchor-el;
}

アンカー名が割り当てられると、.anchor-button はアンカーとして機能し、他の要素の配置をガイドできるようになります。このアンカーは、次の 2 つの方法のいずれかで他の要素に接続できます。

暗黙的なアンカー

アンカーを別の要素に接続する最初の方法は、次のコード例のように暗黙的なアンカーを使用することです。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);
}

アンカーを基準とした要素の配置

物理プロパティを含むアンカー位置の図。

アンカー配置は 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 を使用して配置された要素を中央に配置する

アンカーを基準としたアンカー配置要素を簡単に中央に配置できるように、justify-selfalign-selfjustify-itemsalign-items プロパティで使用できる anchor-center という新しい値が追加されました。

この例では、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() を含むサイズ要素

アンカー ポジショニング API の一部である anchor-size() 関数を使用すると、アンカーのサイズ(幅、高さ、インライン サイズ、ブロックサイズ)に基づいて、アンカー ポジショニングされた要素のサイズや位置を設定できます。

次の 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-nameposition-anchor はボタンとツールチップのインライン スタイルです。各アンカーには一意のアンカー名が必要なため、動的コンテンツを生成する際は、インライン化が最も簡単な方法です。

デモのスクリーンショット。

@position-try でアンカーの位置を調整する

最初のアンカー位置を取得したら、アンカーが包含ブロックの端に達した場合に位置を調整することがあります。代替アンカー位置を作成するには、position-try-options プロパティとともに @position-try ディレクティブを使用します。

次の例では、メニューの右側にサブメニューが表示されます。メニューとサブメニューは、アンカー ポジショニング API と popover 属性を組み合わせた優れた使用例です。これらのメニューはトリガー ボタンにアンカーされる傾向があるためです。

このサブメニューでは、横方向に十分なスペースがない場合は、メニューの下に移動できます。これを行うには、まず初期位置を設定します。

#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;
}

最後に、position-try-options を使用して 2 つを接続します。すべてをまとめると、次のようになります。

#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-blockflip-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-details の処理方法を学習中ですが、サポートは改善されています。

<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 順にする必要はありません。仕様のユーザー補助機能に関するメモをご覧ください。

まとめ

これはまったく新しい機能であり、皆様がこの機能を使ってどのようなものを構築されるか、楽しみにしています。これまでに、グラフの動的ラベル、コネクタ線、脚注、視覚的な相互参照など、コミュニティから非常に優れたユースケースがいくつか寄せられています。アンカーの配置を試す際は、フィードバックをお寄せください。バグを見つけた場合は、こちらからお知らせください

関連情報