1. はじめに
CSSの絶対位置指定は、 著者がボックスをページ上のどこにでも配置できるようにします。 これは、他のボックスのレイアウト(包含ブロック以外)を考慮しません。 この柔軟性は非常に便利ですが、 制限もあり、しばしば何らかの他のボックスを基準に配置したい場合があります。 アンカーポジショニング (position-anchorプロパティ、 position-areaプロパティ、 または アンカー関数 anchor() や anchor-size() を用いることで) 著者はこの目的を達成できます。 絶対位置指定されたボックスを ページ上の1つ以上の他のボックス(アンカー参照)に「アンカー」し、 重なりやオーバーフローを避けるために複数の配置位置を試すことも可能です。
.anchor{ anchor-name : --tooltip; } .tooltip{ /* Fixposは、含有ブロック関係について 気にする必要がないことを意味します。 ツールチップはDOM内のどこにでも存在できます。 */ position: fixed; /* すべてのアンカー動作はデフォルトで --tooltipアンカーを参照します。 */ position-anchor: --tooltip; /* ツールチップの下端をアンカーの上端に揃えます。 これにより(横書きモードの場合)ツールチップとアンカーの水平方向の中央揃えもデフォルトになります。 */ position-area: block-start; /* ウィンドウからはみ出した場合、自動的に切り替えて ツールチップの上端がアンカーの下端に揃うようにします。 */ position-try: flip-block; /* 幅が広くなりすぎないようにします */ max-inline-size:20 em ; }
Popover API を使用すると、positionが自動的に設定され、 anchor-nameやposition-anchor値を設定せずに (暗黙的アンカー要素を定義することで) アンカー関係を作成します。 そのため、これらのプロパティは明示的に設定する必要がありません。 適切なマークアップの場合、この例は次のように簡略化できます。
.tooltip{ /* popover + popovertarget属性を使うと 'position: fixed' と 必要なposition-anchor関係がすでに作成されます。 */ position-area: block-start; position-try : flip-block; max-inline-size : 20 em ; }
1.1. 値の定義
この仕様では、CSSプロパティ定義の規約([CSS2])に従い、 値の定義構文([CSS-VALUES-3])を使用しています。 この仕様で定義されていない値型については、CSS Values & Units [CSS-VALUES-3]で定義されています。 他のCSSモジュールとの組み合わせにより、これらの値型の定義が拡張される場合があります。
各プロパティ定義に記載されたプロパティ固有の値に加え、 この仕様で定義されるすべてのプロパティは CSSワイドキーワード もプロパティ値として受け付けます。 可読性向上のため、ここでは繰り返し記載しません。
CSSのほとんどの操作と同様に、セレクタ一致以外の 本仕様の機能はフラット化要素ツリー上で動作します。
2. アンカーの決定
本仕様のいくつかの機能では、アンカーボックスの位置とサイズを参照します。 特に明記しない限り、 これは関連するborder-boxエッジおよびprincipal box のアンカー要素を意味します。 多くの場合、該当するアンカー要素は 既定のアンカー要素として指定され、 position-anchorプロパティによって CSS anchor-nameおよびanchor-scopeプロパティで 名前付けされたアンカーや、ホスト言語で定義された暗黙的アンカー要素を指すことができます。 (anchor()関数で 名前付きアンカーを直接参照することも可能です。)
アンカーボックスの位置とサイズは レイアウト後に決定されます。 この位置とサイズにはzoomや positionにもとづく調整( position: relative や position: sticky など)および transformや offset-pathなどの変形も含まれます。 この場合、アンカーボックスの軸整列バウンディング矩形が 絶対位置要素の 包含ブロック の座標空間で使用されます。 変形はしばしば別スレッド上で最適化されるため、 変形によるアンカーボックス位置の更新は 数フレーム遅延する場合があります。 著者は、実用上可能であれば絶対配置または相対配置を使用することでこの遅延を回避できます。
アンカーボックスが 分断されている場合、 その包含ブロックが 絶対配置ボックス の関連分断コンテキストの外にある場合は、 ボックスフラグメント の軸整列バウンディング矩形が代わりに使用されます。 (絶対配置ボックスが 分断コンテキスト内にある場合、 それにはアンカーボックスが非分断として見え、 分断コンテキストによって自ら分断されることがあります。)
パフォーマンス上の理由から、 スクロールは特別な方法で扱われます。詳細は§ 3.3 スクロールの考慮を参照してください。 他のレイアウト後の効果(フィルタなど)は アンカーボックス の位置に影響しません。
2.1. アンカーの作成: anchor-name プロパティ
| Name: | anchor-name |
|---|---|
| Value: | none | <dashed-ident># |
| Initial: | none |
| Applies to: | 主ボックスを生成するすべての要素 |
| Inherited: | no |
| Percentages: | n/a |
| Computed value: | as specified |
| Canonical order: | per grammar |
| Animation type: | discrete |
anchor-name プロパティは 要素をアンカー要素とし、 その主ボックスをアンカーボックスとみなします。 また、その要素にターゲットとなるアンカー名リストを持たせます。 値の意味は以下の通りです:
- none
-
プロパティは効果を持ちません。
- <dashed-ident>#
-
要素が主ボックス を生成する場合、 その要素はアンカー要素となり、 指定されたリストのアンカー名を持ちます。 各アンカー名はルーズマッチなツリー・スコープ名です。
それ以外の場合、このプロパティは効果を持ちません。
アンカー名は一意である必要はありません。 すべての要素が ターゲットアンカー要素 になれるわけではありません。 したがって、適切にスコープすれば 同じ名前を複数箇所で使うことができます。
注記: 複数の要素が同じアンカー名を共有し、 すべてがある位置決めボックスから見える場合、 ターゲットアンカー要素は DOM順で最後のものになります。 anchor-scopeプロパティを使って、 参照ボックスに対して見える名前をさらに限定できます。
アンカー名はデフォルトでは 包含でスコープされません。 要素がstyleまたはlayout containment (その他類似の包含)を持つ場合でも、 その子孫のアンカー名は ページ上の他の要素から見える状態です。
注記: 要素が他の要素のスキップ内容にある場合 (例えばcontent-visibility: hidden など)、 それは有効なアンカー要素とはなりません。 事実上、名前がないものとして扱われます。
注記: シャドウツリー内の 位置決め要素は、「上位」のツリーで定義された アンカー名を参照できます。 現状、「下位」シャドウツリーで定義されたアンカー名 を参照することはできません。
2.2. アンカー名のスコープ指定: anchor-scope プロパティ
| Name: | anchor-scope |
|---|---|
| Value: | none | all | <dashed-ident># |
| Initial: | none |
| Applies to: | all elements |
| Inherited: | no |
| Percentages: | n/a |
| Computed value: | as specified |
| Canonical order: | per grammar |
| Animation type: | discrete |
このプロパティは、指定されたアンカー名と、これらのアンカー名の検索のスコープをこの要素のサブツリーに限定します。 詳しくは § 2 アンカーの決定 を参照してください。
値の意味は次のとおりです:
- none
-
アンカー名のスコープに変更はありません。
- all
-
この要素またはその子孫によって定義された、かつ子孫がさらに anchor-scope によって既にスコープが限定されていないすべてのアンカー名を、 この要素の子孫のみにスコープされるように指定します。 また、子孫がマッチできるアンカー名をこのサブツリー内のアンカー要素に限定します。
この値は同じツリー・スコープ内のアンカー名にのみ影響し、 それを厳密マッチのツリー・スコープ名であるかのように扱います。 (つまり、anchor-scope: all は 実質的に anchor-scope: --foo, --bar, ... と同じ動作をし、 関連するすべてのアンカー名を列挙するのと同じになります。)
- <dashed-ident>
-
この要素またはその子孫によって定義された、かつ子孫がさらに anchor-scope によって既にスコープが限定されていない、 一致するアンカー名を この要素の子孫のみにスコープされるように指定します。 また、子孫がマッチできるこれらのアンカー名を このサブツリー内のアンカー要素に限定します。
<dashed-ident> は 厳密マッチの ツリー・スコープ名を表し、 すなわち同じシャドウツリー内のアンカー名にのみマッチします。[CSS-SCOPING-1]
このプロパティは暗黙的アンカー要素には影響しません。
デザインパターンを再利用する際、anchor-scope は同一のコンポーネント間での名前衝突を防ぐことができます。 例えば、リストが各リスト項目内に位置決め要素を含み、それぞれが自分の所属するリスト項目に対して相対的に位置決めしたい場合、
li{ anchor-name : --list-item; anchor-scope : --list-item; } li .positioned{ position : absolute; position-anchor : --list-item; position-area : inline-start; }
もし anchor-scope を使わなければ、
すべての
li
要素が
すべての位置決め要素から見えるようになり、
それらはすべて 最後の
li
を基準に位置決めされ、
重なり合ってしまいます。
2.3. アンカーを見つける
本仕様のいくつかの箇所では、ターゲットアンカー要素を、 与えられたアンカースペシファイアに基づいて検索します。 このアンカースペシファイアは、ページの他の場所の<dashed-ident>(およびそれに対応するツリー・スコープ参照)で、 他の場所のanchor-name の値にマッチするべきもの、 またはキーワード auto、 あるいは何もない(スペシファイアが欠落している)もののいずれかです。
注記: ここで示される一般的な規則は、要素が位置決めボックスの ターゲットアンカー要素になり得るのは、 参照される側のボックスが参照する側の位置決めボックスより先に完全にレイアウトされている場合のみである、ということです。 CSS のレイアウト規則は、アンカーと位置決めボックスの互いの関係やそれらの包含ブロックに応じてこの点に関する有用な保証を提供します。 以下の条件リストは、積み重ねコンテキストに関する規則をこの目的に必要な部分だけに言い換えたもので、 アンカーポジショニングにおける循環の可能性がないことを保証します。
-
もし anchor spec が渡されなかった場合、 存在すれば 既定のアンカー要素 を返し、 そうでなければ何も返しません。
-
もし anchor spec が auto の場合:
注記: 将来の API は暗黙的アンカー要素を追加で定義する可能性があり、 その場合は協調を確保するためにこれらをこのアルゴリズムで明示的に扱います。
-
それ以外の場合、anchor spec は <dashed-ident> です。 次の条件を満たすツリー順で最後の要素 el を返します:
-
el の アンカー名 が anchor spec に対して ルーズマッチ すること。
注記: アンカー名 は ツリー・スコープ名 であり、 anchor spec は ツリー・スコープ参照 であることに注意してください。
-
el が クエリ元の query el にとって有効なアンカー要素 であること。
もしこれらの条件を満たす要素が存在しなければ、何も返しません。
注記: anchor-scope は特定のアンカー名の可視性を制限し、 これがどの要素が特定のルックアップのアンカー要素になり得るかに影響することがあります。
注記: あるシャドウツリー内のスタイルで定義された anchor-name は別のシャドウツリー内のスタイルにおける anchor 関数 から見えないため、 カプセル化が維持されます。 しかし、異なるシャドウツリーの 要素同士 は引き続き相互にアンカーでき、 その場合は anchor-name と anchor 関数の両方が同じツリー内のスタイルから来ていることが必要です(例えば ::part() を使ってシャドウ内の要素をスタイリングする場合など)。 (暗黙的アンカー要素 も本質的に単一のツリーに限定されるわけではありませんが、 その詳細はそれらを割り当てる API に依存します。)
要素 possible anchor が、絶対配置された要素 positioned el にとって 有効なアンカー要素 であるのは、以下すべてが真である場合です:
-
possible anchor が要素(element) または完全にスタイル可能なツリーに従う疑似要素であること。
-
possible anchor が、その祖先や自身に対する anchor-scope の効果に従って positioned el に対してスコープ内であること。
-
possible anchor が positioned el よりも厳密に先にレイアウトされていること、つまり次のいずれかが真であること:
-
possible anchor と positioned el が同じ オリジナル包含ブロック を持ち、さらに次のいずれか:
-
possible anchor を生成する要素の 包含ブロック(存在する場合)が、 positioned el にとっての 有効なアンカー要素 であること
-
-
もし possible anchor が他の要素の スキップされた内容 にある場合、 そのとき positioned el も同じ要素の スキップされた内容 にあること。
注記: 言い換えると、positioned el は 両者が同じスキップされた「リーフ」にいる場合に限り possible anchor にアンカーでき、 「リーフ」を越えてアンカーすることはできません。 つまり、両方を含む要素をスキップしても positioned el が突然別のアンカーに移動することはありませんが、 ページの他の場所にある位置決め要素がそのスキップされた要素にアンカーするのを防ぎます。
2.4. デフォルトアンカー: position-anchor プロパティ
| Name: | position-anchor |
|---|---|
| Value: | none | auto | <anchor-name> |
| Initial: | none |
| Applies to: | 絶対配置ボックス |
| Inherited: | no |
| Percentages: | n/a |
| Computed value: | as specified |
| Canonical order: | per grammar |
| Animation type: | discrete |
position-anchor プロパティは、デフォルトアンカー要素を指定します。 この要素は position-area、position-try、 および(デフォルトで)この要素に対して適用されるすべてのアンカー関数で使用されます。 position-anchorは リセット専用サブプロパティであり、 position のサブプロパティです。
- none
-
このボックスはデフォルトアンカー要素を持ちません。
- auto
-
存在する場合は暗黙的アンカー要素を使用し、 そうでなければボックスはデフォルトアンカー要素を持ちません。
- <anchor-name>
-
指定されたターゲットアンカー要素が ボックスのデフォルトアンカー要素となります。
初期値をより自動的(magical)なものにし、 none と auto の間を position-area の有無で自動選択するように したほうがよいかもしれません。[Issue #13067]
主ボックスが デフォルトアンカー要素の場合、 それがボックスのデフォルトアンカーボックスとなります。
.anchored{ position : absolute; top : calc ( .5 em +anchor ( outside)); /* アンカー名を指定していないため、 デフォルトアンカーボックスを自動的に参照します。 */ } .foo.anchored{ position-anchor : --foo; } .bar.anchored{ position-anchor : --bar; }
2.4.1. 暗黙的アンカー要素
一部の仕様では、特定の条件下で特定の要素を別の要素に対する 暗黙的アンカー要素と定義できます。
TODO: new popover 関連仕様が HTML に追加されたら 具体例を記入
暗黙的アンカー要素は auto キーワードや position-anchor で参照できます。 また、アンカー関数で アンカー参照を省略した場合も参照されます。
暗黙的アンカー要素が 疑似要素の場合、 特に指定がなければそれは発生元要素です。
2.5. アンカーの関連性
要素 el の ユーザーに関連するかどうか を判断する際、 el の子孫が、位置決めボックスの ターゲットアンカー要素であり (自身が スキップ されておらず、 かつその 包含ブロック が el またはその子孫でない場合)、 el はユーザーに関連するとみなさなければなりません。
注記: これは例えば、 content-visibility: auto サブツリー内のアンカーが それに依存する位置決めボックスがスキップされていない限り 内容のスキップを 防ぐことを意味します。 (ただし、アンカーと位置決めボックスが同じ content-visibility: auto 要素のもとにいる場合は、 互いを可視状態にし続けることはできません。)
3. アンカーベースの位置決め
絶対配置ボックスは ページ上の1つ以上のアンカーボックスを基準に 自身を位置決めできます。
position-areaプロパティは、デフォルトアンカーボックスに対して グリッドベースの便利な位置決め概念を提供します。 より複雑な位置決めや複数ボックスを基準とした位置決めを行う場合は、 anchor() 関数をinset プロパティで使用し、 アンカーボックスの各辺を明示的に参照できます。
3.1. position-area プロパティ
| Name: | position-area |
|---|---|
| Value: | none | <position-area> |
| Initial: | none |
| Applies to: | デフォルトアンカーボックスを持つ位置決めボックス |
| Inherited: | no |
| Percentages: | n/a |
| Computed value: | none キーワードまたはキーワードの組み合わせ。詳細は§ 3.1.3 <position-area> の算出値とシリアライズ参照 |
| Canonical order: | per grammar |
| Animation type: | TBD |
もっとも一般的なアンカーポジショニング用途は、 位置決めボックスの包含ブロックの端と デフォルトアンカーボックスの端だけが関係するものです。 これらの線は3×3のグリッドを形成すると考えられます。 position-areaを使うと、 このposition-area グリッド内のどのエリアに 位置決めボックスをレイアウトするかを簡単に指定できます。
- none
-
プロパティは効果を持ちません。
- <position-area>
-
ボックスがデフォルトアンカーボックスを持たない場合や 絶対配置ボックスでない場合、 この値は効果を持ちません。
それ以外の場合、position-area グリッド上の領域を選択し、 それをボックスの包含ブロックとします。
注記: これは、 insetプロパティが position-areaからのオフセットを指定することを意味します。 また一部のプロパティ値( max-height: 100% など)は position-areaを基準とします。
none 以外の値には追加の効果があります:
-
スクロール可能な包含ブロックは ローカル包含ブロックの代わりとして使用されます。 これは絶対配置用包含ブロックが スクロールコンテナによって生成される場合に該当し、 ページ全体のスクロール可能なオーバーフロー領域全体(典型的には)が 位置決めに利用可能になります。
-
used value(実際の値)は auto の insetプロパティ や auto の marginプロパティ について 0 となります。
-
normal 値は self-alignmentプロパティ で対応する値に解決されます。詳細は§ 4.1 エリア固有のデフォルト整列を参照。
3.1.1. ポジションエリアグリッドの解決
ポジションエリアグリッドは、各軸に4本のグリッド線からなる3×3のグリッドです。 (包含ブロックの書字モードを用いる順序で):
-
ボックスの修正前の包含ブロックのstart端、またはそれよりもさらにstart側にある場合はデフォルトアンカーボックスのstart端
-
ボックスの修正前の包含ブロックのend端、またはそれよりもさらにend側にある場合はデフォルトアンカーボックスのend端
注: デフォルトアンカーボックスが 修正前の包含ブロックの外側に部分的または完全に存在する場合、 ポジションエリアグリッドの行や列がサイズ0になることがあります。
3.1.2. <position-area>値の構文
位置は値のペアとして指定されます。 これはフロー相対または物理用語で表現できます。 <position-area>値の許容構文は次の通りです:
<position-area> = [
[ left | center | right | span-left | span-right
| x-start | x-end | span-x-start | span-x-end
| self-x-start | self-x-end | span-self-x-start | span-self-x-end
| span-all ]
||
[ top | center | bottom | span-top | span-bottom
| y-start | y-end | span-y-start | span-y-end
| self-y-start | self-y-end | span-self-y-start | span-self-y-end
| span-all ]
|
[ block-start | center | block-end | span-block-start | span-block-end | span-all ]
||
[ inline-start | center | inline-end | span-inline-start | span-inline-end
| span-all ]
|
[ self-block-start | center | self-block-end | span-self-block-start
| span-self-block-end | span-all ]
||
[ self-inline-start | center | self-inline-end | span-self-inline-start
| span-self-inline-end | span-all ]
|
[ start | center | end | span-start | span-end | span-all ]{1,2}
|
[ self-start | center | self-end | span-self-start | span-self-end | span-all ]{1,2}
]
<position-area>値は、以下のように領域が占める行と列を指定することでポジションエリアグリッドの領域を選択します:
- start, end, self-start, self-end
- top, bottom, left, right
- y-start, y-end, self-y-start, self-y-end
- x-start, x-end, self-x-start, self-x-end
- block-start, block-end, self-block-start, self-block-end
- inline-start, inline-end, self-inline-start, self-inline-end
- center
- top, bottom, left, right
-
指定した軸における対応する単一の行または列。
anchor() と同様に、 通常の論理キーワード (start、end など) は、 ボックスの 書字モード を 包含ブロック 基準で解釈します。 x-start などのキーワードも同様ですが、 指定された物理軸でその方向を決定します。
self-*論理キーワード(self-startやself-x-endなど)は同じですが、 ボックス自身の書字モードを基準にします。
- span-start, span-end, span-self-start, span-self-end
- span-top, span-bottom, span-left, span-right
- span-y-start, span-y-end, span-self-y-start, span-self-y-end
- span-x-start, span-x-end, span-self-x-start, span-self-x-end
- span-block-start, span-block-end, span-self-block-start, span-self-block-end
- span-inline-start, span-inline-end, span-self-inline-start, span-self-inline-end
- span-top, span-bottom, span-left, span-right
-
指定した軸における隣接する2つの行または列:中央の行/列と、単一トラックキーワードで示されるもう一方の行/列。
(例:span-topは最初の2行(中央行+top行)を含みます。)
- span-all
-
指定した軸における3つすべての行または列。
いくつかのキーワードはどの軸を指すか曖昧です: center、 span-all、 また、block軸やinline軸を明示しないstartなどのキーワード。 もう一方のキーワードが軸に関して明確であれば、 曖昧な方は反対軸を指します。 (例:block-start centerの場合、centerはinline軸を指します。) 両方とも曖昧な場合は、最初がボックスのblock軸、 2番目がinline軸を指します。 (例:span-all startはspan-all inline-startと同義です。)
キーワードが1つだけの場合、軸が明確なら2番目はspan-allとして扱い、 軸が不明瞭なら指定キーワードを繰り返したものとして扱います。 (例:topはtop span-allと同義、 centerはcenter centerと同義。)
3.1.3. <position-area>の算出値とシリアライズ
算出値は、<position-area>値として 各軸で選択されたトラックを示す2つのキーワードです。 長い(block-start)・短い(start)論理キーワードは同義とみなします。 シリアライズ時は上記文法の順序で、論理キーワードは短縮形(例:start start、block-start inline-startではなく)で出力されます。
3.2. アンカー相対インセット: anchor() 関数
絶対配置ボックスは anchor() 関数を insetプロパティの値として使い、 1つ以上のアンカーボックスの位置を参照できます。 anchor() 関数は <length> に解決されます。 insetプロパティでのみ使用でき(それ以外では無効)です。
| Name: | top, left, right, bottom |
|---|---|
| New values: | <anchor()> |
<anchor()> = anchor( <anchor-name>? && <anchor-side>, <length-percentage>? )
<anchor-name> = <dashed-ident>
<anchor-side> = inside | outside
| top | left | right | bottom
| start | end | self-start | self-end
| <percentage> | center
anchor() 関数は3つの引数を取ります:
-
<anchor-name>値 はアンカー要素の探し方を指定します。 値の種類:
- <dashed-ident>
-
検索するアンカー名を指定します。 この名前は ツリー・スコープ参照です。
- 省略
-
可能な場合は ボックスに定義されたデフォルトアンカー要素を選びます。
詳細は ターゲットアンカー要素 を参照。
-
<anchor-side>値 は該当する ターゲットアンカー要素の辺の位置を参照します。 値の種類:
- inside
- outside
-
どの アンカーボックスの辺になるかは どのinsetプロパティで使うかに依存します。 inside は insetプロパティと同じ辺 (位置決めボックスがアンカーボックスの「内側」に接触)、 outside はその反対側を指します。
- top
- right
- bottom
- left
- right
-
指定された アンカーボックス の辺を参照します。
注記: これらは一致する軸のinsetプロパティでのみ使用できます。 例えば、left は left、right、 または水平方向の論理insetプロパティで使えます。
- start
- end
- self-start
- self-end
- end
-
アンカーボックスの 同じ軸の辺を参照します(どの軸かは insetプロパティで決まる)。 キーワードの解決に使う書字モードは 書字モード が self-start・self-end では 位置決めボックス自体、 start・end では 位置決めボックスの包含ブロックの書字モードを使う。
- <percentage>
- center
-
start〜endの辺の間で指定%分進んだ位置。 0%はstart、 100%はend と等価。
center は 50%に相当。
- inside
-
省略可能な<length-percentage>最後の引数は フォールバック値であり、 解決不能なアンカー関数の場合の計算値を指定します。
anchor() が解決可能なアンカー関数を表している場合は 算出値時(スタイル・レイアウト交錯使用)に その関数が現れるプロパティの位置と 指定されたターゲットアンカー要素 のアンカーボックスの辺が揃うような<length>に解決します。 これは inset 修正包含ブロックの辺と アンカー側の辺の位置あわせを意味します。
注記: これは transition や animation でアンカー関数を使ったプロパティも ボックスの動き、アンカーの追加・削除、anchor-nameの変更… など あらゆる状態変化で「直感どおり」に動きます。
.barのblock-start辺を --fooアンカーのblock-start辺と揃える長さとなります。
反対に
.bar { inset-block-end: anchor(--foo block-start); }
では
.barのblock-end辺を
--fooアンカーのblock-start辺と揃える長さとなります。
inset-block-start と inset-block-end の各値は異なる辺(包含ブロックのblock-start/block-end)を値基準にするので 同じanchor() でも解決値は異なる場合が多いです。
よい例を追加すること(この例は anchor-center でもできてしまう)。 [Issue #10776]
たとえば次の例は、 inset修正包含ブロック を アンカーボックス の中央に揃えつつ 包含ブロックからはみ出さない最大幅にします:
.centered-message{ position : fixed; max-width : max-content; justify-self : center; --center : anchor ( --x50 % ); --half-distance : min ( abs ( 0 % -var ( --center)), abs ( 100 % -var ( --center)) ); left : calc ( var ( --center) -var ( --half-distance)); right : calc ( var ( --center) -var ( --half-distance)); bottom : anchor ( --x top); }
このような使い方は たとえば要素のエラーメッセージにも便利です。 中央配置により どの入力へのエラーか分かりやすくなります。
3.2.1. anchor() の解決
anchor() 関数は 解決可能なアンカー関数 となるのは、次のすべてが成立する場合のみです:
-
絶対配置ボックスに適用されている。
-
その <anchor-side> が物理キーワードの場合、 該当軸の inset プロパティで指定されていること (例: left は left、right あるいは水平方向の論理 inset プロパティのみで使える)。
-
対象ボックスと <anchor-name> で ターゲットアンカー要素がある。
これらの条件のいずれかが偽の場合、 anchor() 関数は指定されたフォールバック値に 計算 されます。 フォールバック値が指定されていない場合は、 それが参照される宣言は 計算値時点で無効 となります。
3.3. スクロール考慮
パフォーマンス上の理由から、 実装は通常、スクロールを専用のスクロール/「合成」スレッドで実行します。 これは(単純な移動や変形など)ごく限られた能力しか持たず レイアウトなどの高コスト操作はできませんが、 人間の感覚で「瞬間的」と感じるレベルで スクロールへの反応が高速であることを保証できます。
スクロールによってアンカーポジショニング要素が単純に移動するだけなら、 理論上問題ありません。 移動はスクロールスレッドで処理できるため、 要素もコンテンツとともにスムーズに動きます。 しかし、アンカーポジショニングでは 逆側の端を別々のスクロールコンテキストに依存させることができるため、 スクロールにより片側の端だけが動き要素のサイズも変わる=レイアウトが発生する場合があります。 これはスクロールスレッドでは実行 できません!
この制約のもと、 できるだけ多様なアンカーへの自由な参照を保つために、 アンカーポジショニングは 記憶スクロールオフセット と スクロール補正 を組み合わせて使用します。
-
要素が初めて表示されるとき、もしくは フォールバックを切り替えるときには、 すべての アンカー参照 の 最新状態に従って正しく位置決めが計算されます。
これらアンカー参照が異なるスクロールコンテキストにある場合、 その総スクロールオフセットが記憶され、 以降レイアウト時もこれを使い続けます(アンカーがその後スクロールされても)。 (記憶されるのはスクロールオフセットのみで、ボックスのレイアウト位置自体は毎回再計算・最新です。) 再計算されるのは(要素未表示→表示やフォールバック切替時など)、要素の表示開始またはフォールバック変更時のみです。
-
例外はデフォルトアンカー要素です。 それが記憶スクロールオフセットから スクロールされた場合は、位置決め要素もともに移動します。 これは純粋な位置シフトのみであり、 要素のサイズは変化させず、レイアウトも必要ありません。
この仕組みにより、 アンカーポジショニングは 何をアンカー参照していようと「勝手に動く」ようになりますが、 スクロールへの反応には一部制約があります。
アンカー再計算ポイントは、 当該要素のフォールバックスタイル決定時にも発生し、 適用スタイルが切り替わった場合は新しいフォールバックスタイルの アンカー再計算ポイントを用います。
要素 abspos に アンカー再計算ポイントが発生したときは、 abspos の アンカー参照で 参照されている各要素 anchor に対し、 その時点の全てのscroll container祖先の スクロールオフセットの合計を 記憶スクロールオフセットとして保持します (ただし absposの 包含ブロック未満まで)。 記憶スクロールオフセットには stickyなどスクロール依存の他の位置調整も加味されます。 absposがデフォルトアンカー要素を持つ場合は アンカー参照が無くても必ずそれに対し計算します。
すべてのアンカー参照は すべてのscroll containerが 初期スクロール位置にいるものとして計算し、 その後に記憶スクロールオフセットを加算します。
変形(transform)もスクロール同様の課題があり、 Anchor Positioningは通常それらを考慮しません。 transformの効果もここで取り入れられるか?
この仕組みで、要素は アンカー参照 の スクロール位置の最初の1回には追従できますが、 その後さらにスクロールされても 見た目上アンカーから離れ続けます (ただしスクロール以外の動きには引き続き追従)。 この問題は一般には解決できませんが、 特定の アンカー参照 ―つまり デフォルトアンカー要素― については追従可能です:
-
absposがデフォルトアンカーボックスを持つ。
-
absposがデフォルトアンカーボックスや同じスクロールコンテキストにある何かへの アンカー参照を持つ。 具体的には:
-
absposの該当軸の self-alignment の値が anchor-center である
-
該当軸のnone以外の position-area を持つ
-
absposの該当軸の used insetプロパティ で anchor() 関数が、 absposのデフォルトアンカーボックス と同じ最も近いscroll container祖先を持つ ターゲットアンカー要素を参照している
-
注記: absposが position optionsリスト を持っている場合は、どの軸でスクロール補正するかは 適用中のフォールバックスタイルの影響も受けます。
absposの デフォルトスクロールシフト は 水平・垂直軸ごとの長さペアであり、それぞれ次の計算式:
-
該当軸でabsposがスクロール補正する場合: デフォルトアンカー要素の 記憶スクロールオフセットと 再計算した場合の現在の記憶スクロールオフセットとの差
-
それ以外の場合、長さは 0。
レイアウト終了後、absposは デフォルトスクロールシフトぶんさらに移動されます。 これは他のtransform適用前の transform のように働きます。
スナップショット(スクロール位置記憶)のタイミングを厳密に定義すること: 毎フレーム更新・スタイル再計算前。
記憶スクロールオフセット同様に デフォルトアンカー要素のtransformにも対応できるか?
注記: 記憶スクロールオフセット は anchor() の値に影響しますが、 デフォルトスクロールシフトは 要素自身の移動に直接効きます(insetプロパティ・alignment適用後)。 通常この2つの違いは区別できませんが、 round(anchor(outside), 50px) のようにアンカー座標を非線形に変更するケースでは違いが現れます。
4. アンカー基準の整列
4.1. エリア固有のデフォルト整列
position-area が none でない場合、 used value の normal な 自己整列 は、 <position-area> 値に応じて変化し、ボックスをアンカー側へ揃えます:
-
ある軸で center トラックだけが選択されている場合、その軸のデフォルト整列は center です。
-
3トラックすべてを選択している場合、その軸のデフォルト整列は anchor-center です。
-
それ以外の場合は、その軸における非指定側のトラック方向がデフォルト整列です: たとえば軸の "start" トラックを指定している場合、デフォルト整列は end です、など。
ただし、該当軸の inset プロパティ のうち1つだけが auto の場合、 デフォルト整列は非 auto 側の端へ寄ります。 この際、この整列は unsafe 整列です。
注記: この「1つだけ auto」挙動は、 指定した1つの inset が絶対配置ボックスの位置を制御する従来の挙動を保ちます。
この挙動により、包含ブロックが想定より小さくなっても 位置決めボックスが可視・範囲内に収まりやすくなります。
たとえば position-area: bottom span-right だと ボックスはアンカー左端から包含ブロック右端までストレッチし デフォルトでは左揃えですが、 ボックスがその範囲より大きい(アンカーが画面右端に近い等)場合は左にずれて 可視領域を保ちます。
4.2. アンカー中央揃え: anchor-center 整列値
| Name: | justify-self, align-self, justify-items, align-items |
|---|---|
| New values: | anchor-center |
自己整列プロパティ を使うと、 絶対配置ボックスは inset修正包含ブロック内で自身を整列できます。 既存値や適切な insetプロパティだけでも 多くの場合十分ですが、 アンカーベースの「中央揃え」はこれまでやや複雑な指定が必要でした。
新しい anchor-center 値は、 このケースをとてもシンプルにします: 対象ボックスが デフォルトアンカーボックス を持つなら、 その軸で(可能な限り)デフォルトアンカーボックスに中央揃えされます。 さらに:
-
スクロール可能な包含ブロックが該当時は ローカル包含ブロックの代わりになり、 スクロールオーバーフロー領域全体が位置決め範囲になるようにします。
-
used value の auto な insetプロパティ や auto な marginプロパティ は 0 になります。
ボックスが 絶対配置でなかったり デフォルトアンカーボックスを持たない場合は、 値は center として動作し、 insetプロパティ の 解決方式には影響しません。
注記: anchor-center 使用時、 アンカーがボックスの オリジナル包含ブロックの端に近い場合は 「中央」のままではなく オリジナル包含ブロック内に収まるよう シフトします。 詳細は CSS Box Alignment 3 § 4.4 Overflow Alignment: the safe and unsafe keywords and scroll safety limits を参照。
5. アンカーベースのサイズ指定
絶対配置ボックスは anchor-size() 関数を サイズ指定プロパティで使い、 1つ以上のアンカーボックスのサイズを参照できます。 anchor-size() は <length> へ解決されます。 許容 @position-try プロパティ でのみ 使用でき(それ以外は無効)です。
5.1. anchor-size() 関数
| Name: | width, height, min-width, min-height, max-width, max-height, top, left, right, bottom, margin-top, margin-left, margin-right, margin-bottom |
|---|---|
| New values: | <anchor-size()> |
anchor-size() = anchor-size( [ <anchor-name> || <anchor-size> ]? , <length-percentage>? ) <anchor-size> = width | height | block | inline | self-block | self-inline
anchor-size() 関数は anchor() と似ており、 引数も同じですが、<anchor-side> キーワードの代わりに <anchor-size> キーワードを使い、 2つの辺間の距離を参照します。
物理 <anchor-size> キーワード (width および height) はそれぞれ ターゲットアンカー要素の幅と高さを指します。 anchor()と違い、軸の一致縛りはありません。 たとえば width: anchor-size(--foo height); も有効です。
論理 <anchor-size> キーワード (block、 inline、 self-block、 self-inline) は、boxの書字モード(writing mode、self-block/self-inlineの場合)または box の 包含ブロックの writing mode (block/inlineの場合)に基づいて物理キーワードに変換されます。
<anchor-size> キーワードを省略した場合は、 使用プロパティの軸に合うキーワードとして動作します。 (たとえば width: anchor-size() は width: anchor-size(width) と同じ意味になります。)
anchor-size() が解決可能アンカーサイズ関数 である場合は、 算出値 時(スタイル・レイアウト交錯経由)に 指定軸に対応する2辺(left・rightまたはtop・bottom)の <length>、 すなわち ターゲットアンカー要素の アンカーボックス内の 間隔に解決されます。
5.1.1. anchor-size() の解決
anchor-size() 関数が 解決可能アンカーサイズ関数 となるのは、次のすべてが成立する場合のみ:
-
絶対配置ボックスに適用されていること。
-
対象ボックスと関数指定の <anchor-name> で ターゲットアンカー要素が存在すること。
これらの条件のいずれかが偽の場合、 anchor-size() 関数は指定のフォールバック値へ解決されます。 フォールバック値未指定の場合、その宣言は 計算値時点で無効 となります。
6. オーバーフロー処理
アンカーポジショニングは強力ですが、 予測しづらい場合もあります。 アンカーボックスは ページ上のどこにでもあり得るため、 何らかの特定の位置(アンカーの上や右など)に配置しても、 配置ボックスが包含ブロックから はみ出たり画面外になることがあります。
これを緩和するため、 絶対配置ボックスは position-try-fallbacks プロパティで 予備の position option (既存のスタイルから生成する配置・整列プロパティセットや、@position-try ルールで指定)を ボックスが最初の位置ではみ出した時に試すことができます。 各オプションは position-try-order で指定した順に1つずつ適用され、 最初に 包含ブロックからはみ出さないものが「採用」となります。
いったん選ばれたオプションスタイルは、再度はみ出すまで保たれます。 たとえ先に指定した(望ましい)オプションが「非オーバーフロー」となっても一度確定したものは変わりません。 (詳細は 最後に成功した位置オプションの記憶/クリア を参照。)
#myPopover{ position : fixed; position-anchor : --button; position-area : bottom span-x-end; position-try-fallbacks : flip-x, flip-y, flip-x flip-y, bottom, top; /* The popover is at least as wide as the button */ min-width:anchor-size ( width); /* The popover is at least as tall as 2 menu items */ min-height:6 em ; }
6.1. フォールバック指定:position-try-fallbacksプロパティ
| Name: | position-try-fallbacks |
|---|---|
| Value: | none | [ [<dashed-ident> || <try-tactic>] | <position-area> ]# |
| Initial: | none |
| Applies to: | absolutely positioned boxes |
| Inherited: | no |
| Percentages: | n/a |
| Computed value: | as specified |
| Canonical order: | per grammar |
| Animation type: | discrete |
このプロパティは、絶対配置ボックスが inset‑modified containing blockからはみ出したときに試すための、 代替の位置付けスタイルのリストを提供します。 このposition options listは、 最初は要素のfallback base styles(すなわち computed styles に対して position-try-fallbacks を適用しない場合のスタイル) から生成された単一の position option を含みます。
リスト内の各カンマ区切りのエントリは別個のオプションです: 指定された名前の @position-try ブロックの名前、 またはボックスの既存の computed style を自動的に変換する <try-tactic> です。
値の意味は次の通りです:
- none
-
プロパティは効果を持ちません; ボックスの position options list は空になります。
- <dashed-ident>
-
もし指定された名前の @position-try ルールが存在するなら、 その関連する position option が position options list に追加されます。
それ以外の場合、この値は効果を持ちません。
- <try-tactic>
-
指定された try tactic を 実行して ボックスの base styles に対して自動的に position option を作成し、 構築した position option を ボックスの position options list に追加します。
<try-tactic> = flip-block || flip-inline || flip-start || flip-x || flip-y
- flip-block
-
(例えば margin-block-start と margin-block-end の間で) block 軸の値を入れ替えます。要するに inline 軸に沿って鏡映する操作です。
- flip-inline
-
inline 軸の値を入れ替えます。要するに block 軸に沿って鏡映する操作です。
- flip-x
-
水平方向(例: margin-left と margin-right の間で) の値を入れ替えます。 要するに垂直軸に沿って鏡映する操作です。
- flip-y
-
垂直軸の値を入れ替えます。要するに水平方向の軸に沿って鏡映する操作です。
- flip-start
-
start プロパティ同士を入れ替え、end プロパティ同士を入れ替えます(例えば margin-block-start と margin-inline-start の間で)。 要するに、block-start/inline-start コーナーから block-end/inline-end コーナーへ引いた対角線に沿って鏡映します。
複数のキーワードが与えられた場合、それらの変換は順に合成されて単一の position option を生成します。 論理方向は containing block の writing mode に照らして解決されます。
- <dashed-ident> || <try-tactic>
-
前述の2つのオプションの効果を組み合わせます: 指定された名前の @position-try ルールがある場合、 その position option を base style に適用し、 指定された <try-tactic> に従って変換し、 結果をボックスの position options list に追加します。
それ以外の場合は何もしません。
- <position-area>
-
指定された値の position-area プロパティだけで構成された position option を自動的に作成します。
6.2. フォールバック順序の決定: position-try-order プロパティ
| Name: | position-try-order |
|---|---|
| Value: | normal | <try-size> |
| Initial: | normal |
| Applies to: | absolutely positioned boxes |
| Inherited: | no |
| Percentages: | n/a |
| Computed value: | as specified |
| Canonical order: | per grammar |
| Animation type: | discrete |
このプロパティは、ボックスにとって宣言された position options のうち、 指定された order に厳密に従うよりも「得られる空間を最大化する」ことが重要な場合に、 それらを利用可能な空間に基づいてソートすることを可能にします。
<try-size> = most-width | most-height | most-block-size | most-inline-size
- normal
-
position-try-fallbacks で指定された順に position options を試します。
- most-width
- most-height
- most-block-size
- most-inline-size
- most-height
-
position options list の各エントリについて、 その position option をボックスに適用し、 そのスタイルから生じる inset‑modified containing block のサイズを求めます (auto な inset 値は 0 と扱います)。 これらのサイズに基づいて position options list を安定ソートし、 最も大きいものを先頭にします。
論理方向は containing block の writing mode に照らして解決されます。
例えば、次のスタイルは最初にポップアップリストを アンカーとなるボタンの上または下に配置しますが、 どちらに配置するかはどのオプションが最も多くの空間を与えるかによって決まります。
.anchor{ anchor-name : --foo; } .list{ position : fixed; position-anchor : --foo; position-area : block-end span-inline-end; position-try-fallbacks : --bottom-scrollable, flip-block, --top-scrollable; position-try-order : most-height; } @position-try --bottom-scrollable{ align-self : stretch; } @position-try --top-scrollable{ position-area : block-start span-inline-end; align-self : stretch; }
base styles と --bottom-scrollable オプションは 利用可能な高さが同じです。両者ともアンカーから包含ブロックの端まで伸びる inset‑modified containing block を持つためです。 同様に flip-block オプションと --top-scrollable オプションも同じ利用可能高さを持ちます。 position-try-order が安定ソートを使うため、 これらのペアはそれぞれリスト内で相対位置を保持し、 *-scrollable オプションが後になるでしょう; そして最も多くの空間を持つペアが先頭に来ます。
これにより、ボックスはまず大きい側でアンカーに対して自然な高さで揃えることを試み(base styles または flip-block スタイルを使用)、 しかしそれがオーバーフローを引き起こす場合は、 代わりに同じ空間を埋めてスクロール可能にする(対応する *-scrollable スタイルを使用)ことで オーバーフローを回避し、小さい方の空間に移動しようとすることを防ぎます。
6.3. ショートハンド:position-try
| Name: | position-try |
|---|---|
| Value: | <'position-try-order'>? <'position-try-fallbacks'> |
| Initial: | see individual properties |
| Applies to: | see individual properties |
| Inherited: | see individual properties |
| Percentages: | see individual properties |
| Computed value: | see individual properties |
| Animation type: | see individual properties |
| Canonical order: | per grammar |
このショートハンドは position-try-fallbacks と position-try-order の両方を設定します。 <'position-try-order'> が省略された場合、 そのプロパティの初期値に設定されます。
6.4. @position-try ルール
@position-try ルールは、 与えられた名前で position option を定義し、 その名前を通して position-try-fallbacks 経由でボックスに適用できる 1つ以上の位置指定プロパティのセットを指定します。
@position-try ルールの構文は次の通りです:
@position-try <dashed-ident> {
<declaration-list>
}
Prelude に指定された <dashed-ident> はルールの名前です。 同じ名前の @position-try ルールが複数宣言された場合、 それらは カスケードされ、@keyframe ルールと同様に扱われます。
@position-try ルールは、次に挙げる プロパティのみを 受け付けます:
!important を <declaration-list> 内のプロパティに使用することは無効です。 そのプロパティに !important を付けるとそのプロパティ自体が無効になりますが、 @property-try ルール全体が無効になるわけではありません。
@position-try 内のすべてのプロパティは、 Position Fallback Origin と呼ばれる新しい カスケード起源 においてボックスに適用されます。これは Author Origin と Animation Origin の間に位置します。
revert 値の使用は Animation Origin と似ており、 そのプロパティがあたかも Author Origin の一部であるかのように振る舞い、 代わりに User Origin に戻ります。 (ただし revert-layer には特別な動作はなく、通常どおり動作します。)
注記: accepted @position-try properties は、 ボックス自身のサイズと位置にのみ影響し、その内容や他のスタイルを変更しない最小限のプロパティ群です。 これにより位置フォールバックの実装が大幅に簡素化される一方で、 使用可能な空間に応じてアンカー位置決めボックスを移動するという根本的なニーズに対処します。 これらのルールは Author Origin の通常の宣言を上書きするため、 @position-try 宣言と 他のプロパティの通常のカスケードや継承との悪質な相互作用を制限します。 将来的には container queries の拡張によって、 要素がどの位置フォールバックを使用しているかに基づく条件付きスタイリングが可能になり、 この制限されたプロパティリストによって制約されているような表現が可能になることが期待されます。
注記: 複数の要素が同じ @position-try ルールを 自分のアンカー要素に対してそれぞれ適用したい場合は、 <anchor-name> を anchor() 内で省略し、 各ボックスのアンカーを position-anchor で指定してください。
注記: 最も一般的なフォールバックの型(通常はアンカーの片側に配置し、 必要なら反対側に反転するようなケース)は、 position-try-fallbacks のキーワードだけで 自動的に実現でき、必ずしも @position-try を使う必要はありません。
6.5. 位置フォールバックの適用
位置決めボックスが (任意の default scroll shift を適用した後に) inset-modified containing block からはみ出し、 その position options list に複数の position option が含まれている場合、 位置フォールバックスタイルを決定 して、 はみ出しを回避できるオプションを探します。 決定されたスタイルは インターリービング を通じて要素に適用され、 それによって 算出値 に影響し(トランジション等を引き起こす可能性もあります)、 レイアウトや used values に依存する決定を行います。
実装は、必要となる過剰なレイアウト作業量を制限するために、 position options list の長さに 実装定義の上限を設けることができます。 ただしこの上限は少なくとも 5 以上でなければなりません。
位置フォールバックスタイルを決定する手順は、要素 abspos に対して次の通りです:
-
current styles を abspos の現在の used styles とします (これは以前のフォールバック結果かもしれません)。
-
For each として、position options list 内の各 option について:
-
もし option が現在 abspos の last successful position option であれば、 continue します。
-
adjusted styles を option を abspos に適用した結果とします (apply a position option を参照)。
-
el rect を abspos の margin box のサイズと位置とし、 cb rect を abspos の inset-modified containing block のサイズと位置とします、 これらは adjusted styles でレイアウトしたときのものです。
-
もし cb rect がいずれかの軸で負のサイズになり 0 に修正されていたら、 continue します。
注記: これは負のサイズの cb rect に対して 0 サイズに修正された場合でも、ゼロサイズの el rect が「内部にある」と判断されて 成功オプションに選ばれるのを防ぎます。
-
もし el rect が cb rect に完全に収まっていなければ、 continue します。
-
adjusted styles と、それに対して仮に計算された remembered scroll offsets の集合を返します。
-
-
断言: 前のステップは、オーバーフローを回避する position option を見つけられずに終了したことを示します。
-
current styles を返します。
注記: 子孫要素が el からはみ出していることはこの計算には影響しません。計算対象は el 自身の margin box のみです。
注記: 現在適用中の position option を意図的にスキップするため、 その option に対する remembered scroll offsets は更新されません。 他のフォールバックがどれも機能せず現在のスタイルに留まる場合、 すべての remembered scroll offsets はそのまま維持されます。
フルレイアウトパスの間、ボックスがフォールバックスタイルを決定した(あるいは何も使わないと決めた)後は、 後にレイアウトされるボックスがこの決定を変更することはできません。
例えば、A と B の2つの位置決めボックスがあり、A が B より先にレイアウトされるとします。 もし B がオーバーフローして A の包含ブロックにスクロールバーが発生しても、 これは A がフォールバックスタイルを再決定してオーバーフローを避けようとする原因にはなりません。 (最良の場合でも指数的なレイアウトコストを招く可能性があり、 最悪の場合は循環して決着がつかなくなります。)
言い換えると、レイアウトは「後戻り」しません。
6.5.1. フォールバック選択の維持とクリア
いくつかの変更は 位置フォールバックスタイルの決定 に 特に直接的な影響を与え、特別な挙動を引き起こします。 これらの フォールバック感受性のある変更 には次が含まれます:
-
算出された position 値が変わった場合、 包含ブロックの関連が変わった場合、 またはボックスを生成しなくなった場合。
-
longhand のいずれか、 つまり position-try の構成プロパティの算出値が変わった場合。
-
accepted @position-try property の算出値が変わった場合。
-
参照している任意の @position-try ルールが追加・削除・変更された場合。
レイアウトの安定性をなるべく維持するために、 位置フォールバックスタイルの決定 は 最後に成功した位置オプション を優先します。 これは次のように決定されます:
ResizeObserver イベントが決定され配信される時点で、 ボックスは次の手順で 最後に成功した位置オプションを記録 しなければなりません:
-
もし el が last successful position option を持つなら、 変更に対して last successful position option を削除します。 その後、もし 位置フォールバックスタイルの決定 の結果スタイルが変わるなら、 それを行い、last successful position option を 現在使用している accepted @position-try properties(とその値)に設定します。
-
それ以外の場合、もしボックス el が 絶対配置 であるなら、 その last successful position option を 現在使用している accepted @position-try properties(とその値)に設定します。
注記: この記録/削除のタイミングは、 last remembered sizes の扱いと意図的に同じです。
6.5.2. 位置オプションの適用
ボックスの要素 el に対して、与えられた position option new styles を 適用する 手順:
-
new styles を position fallback origin に挿入してカスケードを解決し、 el の used styles を決定するために十分なレイアウトを行います。
これらのスタイルを計算する目的のために、仮想的な anchor recalculation point が計算され、 それに対応する仮想的な remembered scroll offsets がスタイル決定に用いられます。
-
el の used styles を返します。
try-tactic を実行する 手順は、 ボックスの要素 el のスタイル集合 styles に対して、 方向ペア directions の間で変換したスタイル集合を返すものです:
-
もし directions が同じ軸に沿って互いに反対方向であれば、それらは「opposing(反対)」です。 そうでなければ(異なる軸を指定している場合)、それらは「perpendicular(直交)」です。
-
el 上の accepted @position-try properties の指定値を決定し、 styles をその結果とします。
-
変数の置換、 env() 関数、 および類似の 任意置換関数 を styles 内で解決します。
env() 関数については、参照される環境変数が方向または軸に関連付けられている場合(例: safe-area-inset-top)、 directions に対応する環境変数に切り替えます。
例えば、もし top: env(safe-area-inset-top); が指定され、directions が up と left であれば、 env() はあたかも env(safe-area-inset-left) と指定されたかのように解決されます。 (次のステップで実際に left プロパティに入れ替わります。)
-
styles の値を directions に対応するプロパティ間で入れ替えます。
例えば "top" と "left" を入れ替える場合、 margin-top と margin-left が入れ替わり、 width と height も入れ替わる、等の処理が行われます。
注記: もし directions が同じ軸で反対である場合、 width や align-self のように 自身に対応するプロパティは入れ替わらないことがありますが、 それらの値は次のステップで変更される可能性があります。
-
入れ替えに伴ってプロパティの値を新しい方向に合わせて修正します。修正方法は次の通り:
-
inset プロパティについては、anchor() 関数内の指定側を、 以前の方向に対する相対関係を保つように新しい方向に合わせて変更します。
もし <percentage> が使われ、directions が反対であれば、 それを元の百分率の 100% マイナスに変更します。
例えば "top" と "left" が入れ替わる場合、 margin-top: anchor(bottom) は margin-left: anchor(right) になります。
もし "top" と "bottom" を入れ替える場合、 margin-top: anchor(20%) は margin-bottom: anchor(80%) になります。
-
sizing プロパティについては、anchor-size() 内で指定されている軸を、 以前の方向に対する相対関係を保つように新しい方向に変更します。
例えば "top" と "left" が入れ替わる場合、 width: anchor-size(width) は height: anchor-size(height) になります。
-
self-alignment プロパティについては、もし directions が反対であれば、 指定された <self-position>(または left/right キーワード)があれば、 以前の方向に対する相対関係を保つように新しい方向に変更します。
例えば "top" と "bottom" が入れ替わる場合、 align-self: start は align-self: end になります。
ただし align-self: center は両方向に対して同じ関係を持つため 変更されません。
同様に align-self: first baseline も変更されません。 これは <baseline-position> であって <self-position> ではないためです。
-
position-area については、 選択される position-area グリッドの行/列が、新しい方向でも以前の方向に対する相対関係を維持するように値を変更します。
例えば "top" と "left" が入れ替わる場合、 position-area: left span-bottom は position-area: top span-right になります。
-
-
styles を返します。
6.6. 条件付き非表示:position-visibility プロパティ
| 名前: | position-visibility |
|---|---|
| 値: | always | [ anchors-valid || anchors-visible || no-overflow ] |
| 初期値: | anchors-visible |
| 適用対象: | 絶対配置ボックス |
| 継承: | no |
| パーセント値: | n/a |
| 算出値: | as specified |
| 正規順序: | per grammar |
| アニメーション型: | discrete |
絶対配置のボックスを表示することが適切でないケースがあります。 このプロパティは、一般的によくあるレイアウト条件に応じて、 そのようなボックスを条件付きで表示できるようにします。
- always
-
このプロパティは効果を持ちません。 (アンカーやオーバーフローに関係なくボックスは表示されます。)
- anchors-valid
-
ボックスの 必須アンカー参照 のいずれかが ターゲットアンカー要素 に解決されない場合、 ボックスの visibility プロパティは になります。
必須アンカー参照 とは? フォールバック値を持たない anchor() 関数?デフォルトアンカーも場合によって?詳細要検討。
- anchors-visible
-
ボックスが デフォルトアンカーボックス を持ち その アンカーボックス が 不可視 または 介在ボックスによってクリップ されている場合は、 ボックスの visibility プロパティは になります。
- no-overflow
-
position-try の適用後もボックスが inset‑modified containing block から はみ出している場合、 ボックスの visibility プロパティは になります。
IntersectionObserver
が(デフォルトで)判定するクリッピング効果と同じです。
すなわち clip-path や
overflow、paint
containment などで
オーバーフロークリップエッジへクリッピングされた場合です。
anchor が 介在ボックスによってクリップ されているかどうかは
文書のコンテンツ関連性を更新
(content-visibility)後・
ResizeObserver
実行後、
だが IntersectionObserver
実行前に判定する必要があります。
レスポンス向上のため他のタイミングで判定してもよいです。
注記: これはたとえば abspos が DOM でアンカーと並んでいる場合、 デフォルトアンカーがスクロールアウトしても同じスクロール領域でクリップされているため 可視のままであることを意味します。
この clipped 定義が View Transitions と矛盾しないか確認すること。
注記: 「連鎖アンカー」状況では 1つめの abspos がこのプロパティにより不可視(アンカーがスクロールアウトなど)となった場合、 それをアンカーとする2つめの abspos も不可視となり、無意味な場所に浮かばなくなります。
7. アクセシビリティへの影響
CSSアンカーポジショニングは要素間のアクセシビリティバインディングを作成・削除・変更しません。 著者はそのようなバインディングを制御する適切なマークアップ機能を必ず利用してください。
CSSアンカーポジショニングは多様な使い方・用途が可能なため、 配置ボックスといずれかのアンカー要素の間のセマンティックな関係を 自動的に確立することはありません。 例えば、デザイン上の視覚的なアンカー関係が、 要素とセマンティックアンカーとの間かもしれず、 あるいはセマンティックアンカーの祖先・兄弟・子孫と結ぶ場合もあり、 意図するビジュアル効果により異なります。 同様に、セマンティックな関係があっても視覚的にはアンカー関係を持たない選択や、 その逆もあり得ます。
著者はCSS配置による視覚的つながりだけに頼って、 要素同士をセマンティックに結びついているとみなしてはなりません。 適切なマークアップがなければ、 視覚的にリンクされた要素同士には何の意味的なDOM関係もなく—— もし意味的関係が存在するなら—— スクリーンリーダー等の非視覚エージェントや タブ移動等の非グラフィカル操作で 使いづらくなったり、利用不能となる恐れがあります。
ウェブプラットフォームには既存・今後登場する多くの機能が、 セマンティックな関連付けを明示的に作れるようになっています。 これにより非視覚エージェントでも恩恵が受けられます。 例えばHTMLのPopover APIでは 呼出元ボタンとポップオーバー要素が自動的に接続され、 タブ順序の自動調整も行い、 さらに呼出元ボタンを ポップオーバーの暗黙的アンカー要素にもするので Anchor Positioning を容易に使えます。
より一般的なケースでは、
ARIAの aria-details
や aria-describedby 属性を
アンカー要素側に付けることで、
少し手動になりますが関係が作れます。
配置要素側で
role
属性と組み合わせれば、
非視覚エージェントが要素間の関係をユーザーに伝え、
相互自動移動も提供できます。
ただし、そのような機能も過剰利用せず、 不要・過剰なセマンティック接続があると ページが分かりづらくなることもあるので注意してください。
このセクションの改良案(特に著者向けガイド・代表的ユースケースのベストプラクティス例)は歓迎。 [Issue #10311]
8. DOMインターフェイス
8.1. CSSPositionTryRuleインターフェイス
CSSPositionTryRule
インターフェイスは
@position-tryルールを表します:
[Exposed =Window ]interface :CSSPositionTryRule CSSRule {readonly attribute CSSOMString name ; [SameObject ,PutForwards =cssText ]readonly attribute CSSPositionTryDescriptors style ; }; [Exposed =Window ]interface :CSSPositionTryDescriptors CSSStyleDeclaration {attribute CSSOMString ;margin attribute CSSOMString ;marginTop attribute CSSOMString ;marginRight attribute CSSOMString ;marginBottom attribute CSSOMString ;marginLeft attribute CSSOMString ;marginBlock attribute CSSOMString ;marginBlockStart attribute CSSOMString ;marginBlockEnd attribute CSSOMString ;marginInline attribute CSSOMString ;marginInlineStart attribute CSSOMString ;marginInlineEnd attribute CSSOMString ;margin-top attribute CSSOMString ;margin-right attribute CSSOMString ;margin-bottom attribute CSSOMString ;margin-left attribute CSSOMString ;margin-block attribute CSSOMString ;margin-block-start attribute CSSOMString ;margin-block-end attribute CSSOMString ;margin-inline attribute CSSOMString ;margin-inline-start attribute CSSOMString ;margin-inline-end attribute CSSOMString ;inset attribute CSSOMString ;insetBlock attribute CSSOMString ;insetBlockStart attribute CSSOMString ;insetBlockEnd attribute CSSOMString ;insetInline attribute CSSOMString ;insetInlineStart attribute CSSOMString ;insetInlineEnd attribute CSSOMString ;top attribute CSSOMString ;left attribute CSSOMString ;right attribute CSSOMString ;bottom attribute CSSOMString ;inset-block attribute CSSOMString ;inset-block-start attribute CSSOMString ;inset-block-end attribute CSSOMString ;inset-inline attribute CSSOMString ;inset-inline-start attribute CSSOMString ;inset-inline-end attribute CSSOMString ;width attribute CSSOMString ;minWidth attribute CSSOMString ;maxWidth attribute CSSOMString ;height attribute CSSOMString ;minHeight attribute CSSOMString ;maxHeight attribute CSSOMString ;blockSize attribute CSSOMString ;minBlockSize attribute CSSOMString ;maxBlockSize attribute CSSOMString ;inlineSize attribute CSSOMString ;minInlineSize attribute CSSOMString ;maxInlineSize attribute CSSOMString ;min-width attribute CSSOMString ;max-width attribute CSSOMString ;min-height attribute CSSOMString ;max-height attribute CSSOMString ;block-size attribute CSSOMString ;min-block-size attribute CSSOMString ;max-block-size attribute CSSOMString ;inline-size attribute CSSOMString ;min-inline-size attribute CSSOMString ;max-inline-size attribute CSSOMString ;placeSelf attribute CSSOMString ;alignSelf attribute CSSOMString ;justifySelf attribute CSSOMString ;place-self attribute CSSOMString ;align-self attribute CSSOMString ;justify-self attribute CSSOMString ;positionAnchor attribute CSSOMString ;position-anchor attribute CSSOMString ;positionArea attribute CSSOMString ; };position-area
そのname属性は、
規則プレリュードで宣言された名前を表します。
そのstyle属性は、
規則本体で宣言されたプロパティを
指定順で表します。
取得時には、CSSPositionTryDescriptors
オブジェクトを返します。
@position-tryアトルール用であり、
以下のプロパティを持ちます:
- computed flag
-
未設定
- readonly flag
-
未設定
- declarations
-
規則中で宣言された記述子を指定順で並べたもの。
- parent CSS rule
-
コンテキストオブジェクト
- owner node
-
Null
9. 付録:スタイルとレイアウトのインターリーブ
スタイルとレイアウトのインターリーブとは、 レイアウト処理中にサブツリーにスタイル更新が発生し、 要素の算出スタイルが遡って更新される技法です。
この概念はこの仕様書の正しい場所ではなく、 Cascadeに入るべきですが、 参照用のスケッチが必要なので暫定で記載しています。
注: スタイルとレイアウトのインターリーブは コンテナクエリ やコンテナクエリ長ですでに使われています。 10cqwのような長さは クエリコンテナのサイズ情報を用いて算出長に解決され、 コンテナサイズがレイアウト間で変化すると トランジションが発生します。
許可された@position-tryプロパティも フォールバック解決時にインターリーブされます (position-try参照)。
当然詳細化が必要ですが、 今は「コンテナクエリと同様に振る舞う」で十分です。 この挙動も未定義ですが、少なくともある程度は相互運用されているようです。
10. セキュリティに関する考慮事項
この文書に対してセキュリティ上の問題は報告されていません。
11. プライバシーに関する考慮事項
この文書に対してプライバシー上の問題は報告されていません。
12. 変更点
2025年10月7日作業草案以降の主な変更点:
-
flip-x と flip-y を position-try-fallbacks に追加。 (Issue 12869)
-
anchor-center が scrollable containing block も使用することを明記し、 local containing block 外に配置された場合に overflow alignment が発生しないように。 (Issue 12952)
-
position-area や anchor-center 適用時は auto マージンを 0 に解決することを明記。 これはポップオーバーに関する HTML UA デフォルトスタイルシートによる問題のため。 また、この問題を以前対処しようとした dialog 整列値を削除。 (Issue 10258)
-
position-anchor に none 値を追加し、初期値をそれに設定。 これにより 暗黙的アンカー要素 を持つすべての 絶対配置ボックスが scrollable containing block を使うのを回避。 なお初期値については議論が継続中のため今後再度変更される可能性あり。 (Issue 13067)
-
flip-block、 flip-inline、 flip-start は writing mode が containing block の 書字モードに基づくことを明記。 (Issue 12869、 Issue 13076)
-
auto の inset 値は inset-modified containing block サイズ計算時に0として扱うことを明記。 position-try-order の比較時も含む。 (Issue 12942)
-
clip-path を anchors-visible で考慮するクリッピング効果のリストに追加し、 その判定タイミングを明記。 (Issue 12732)
-
position options list から誤ってベーススタイルが抜けていたエラーを修正。 (Issue 12890)
-
anchors-visible 判定のタイミングを明確化。 (Issue 12732)
-
normal アラインメントの解決方法が position-area値に基づく場合、 それが used value(それに基づいて [CSS-ALIGN-3] でのoverflow処理方式が決まる)を決定することを明記。
-
アンカー名マッチに木のルート一致を要求していたアルゴリズム誤りを修正。シャドウツリー越しのマッチも可能な場合があるため。 (Issue 12941)
-
auto の inset 値は inset-modified containing block サイズ計算時0として扱うことを明記。 position-try-order でも同様。 (Issue 12942)
-
§ 6 オーバーフロー管理 および § 2 アンカーの決定 の記述を整理し、可読性を向上。 (Issue 12818、 Issue 11022)
-
§ 7 アクセシビリティへの影響 のガイダンスとUA要件を改善。 (Issue 10311)
-
例を改良。
前回までの変更点は Previous Changes も参照してください。