1. 介绍
CSS 绝对定位允许作者将盒子放置在页面上的任意位置, 并不考虑除其包含块之外其他盒子的布局。 这种灵活性非常有用, 但也有局限——很多时候你希望相对于某个其他盒子进行定位。 锚点定位 (通过 position-anchor 和 position-area 属性 以及/或者 anchor 函数 anchor() 和 anchor-size()) 让作者能够实现这一点, 即将一个绝对定位盒子“锚定”到页面上的一个或多个其他盒子 (它的锚点引用), 同时也允许尝试多个可能的位置, 以找到能够避免重叠/溢出的“最佳”位置。
.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 值与单位 [CSS-VALUES-3] 中定义。 与其他 CSS 模块组合时,可能会扩展这些值类型的定义。
除了属性定义中列出的特定值外, 本规范定义的所有属性 还接受 CSS 全局关键字 作为属性值。 为了可读性,本文未重复列出。
如同 CSS 中除选择器匹配以外的大多数操作, 本规范特性在 扁平元素树 上起效。
2. 锚点的确定
本规范的多个特性都涉及 锚点框 的位置与尺寸。 除非另有说明, 此处指相关 边框盒 边界,即相关 主盒 的 锚点元素。 在多数情况下,相关的 锚点元素 通过 默认锚点元素 由 position-anchor 属性指定, 该属性可指向主机语言定义的 隐式锚点元素, 或由 CSS anchor-name 与 anchor-scope 属性命名的锚点。 (anchor() 函数也可直接引用命名锚点。)
锚点框 的位置和尺寸在布局完成后确定。 此位置和尺寸包含 缩放 与 定位相关的调整 (如 position: relative 或 position: sticky), 也包括变换(如 transform 或 offset-path)。 此类情况下,锚点框 在 绝对定位 元素的 包含块 坐标空间中的轴对齐边界矩形将被采用。 由于变换通常会在不同的线程上优化执行, 因此基于变换的 锚点框 位置更新 可能会延迟几帧。 作者可以在可行情况下用绝对或相对定位来避免该延迟。
如果 锚点框 被 分片, 且引用该 锚点框 的 绝对定位 盒的 包含块 在相关 分片上下文 外部, 将采用其 盒片段 的轴对齐包围矩形。 (如果 绝对定位 盒本身位于 分片上下文 内, 它视 锚点框 为未分片——并且本身可能被 分片上下文 分片。)
出于性能原因, 滚动会被特殊处理,详见 § 3.3 考虑滚动因素。 其它布局后效果(如滤镜) 不会影响 锚点框 的位置。
2.1. 创建锚点:anchor-name 属性
| 名称: | anchor-name |
|---|---|
| 取值: | none | <anchor-name># |
| 初始值: | none |
| 适用元素: | 所有生成 主框 的元素 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 按指定值 |
| 规范顺序: | 依语法 |
| 动画类型: | 离散型 |
<anchor-name> = <dashed-ident>
anchor-name 属性声明 元素为一个锚元素, 其 主框 为一个 锚框, 并赋予其要被定位的 锚名称 列表。 取值定义如下:
锚名称 不要求唯一。 并非所有元素都能成为 某个盒子的 目标锚元素。 因此如果作用域合适,某个名称可以复用在不同地方。
注: 如果多个元素共享同一个 锚名称, 且都对某个定位盒可见, 则 目标锚元素 为最近的祖先(如存在) 否则为 DOM 顺序里的最后一个。 可用 anchor-scope 属性进一步限制 某个引用盒可见的名称。
锚名称 默认不会 受 包含 作用域限制; 即使元素有 样式或布局包含 (或类似的包含方式), 其后代的 锚名称 依然对页面其他元素可见。
注: 当一个元素位于另一个元素的 跳过内容内 (例如由于content-visibility: hidden), 该元素不会成为可接受的锚元素, 实际上相当于没有任何名称。
注: Shadow DOM 树内的定位元素 可以引用更高层树定义的 锚名称。 当前还不能引用“更低层” shadow 树里的 锚名称。
2.2. 限定锚点名称作用域:anchor-scope 属性
| 名称: | anchor-scope |
|---|---|
| 取值: | none | all | <anchor-name># |
| 初始值: | none |
| 适用元素: | 所有元素 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 与指定相同 |
| 规范顺序: | 遵循语法 |
| 动画类型: | 离散型 |
该属性将指定的 锚点名称 及其查找限制在此元素的子树内。 见 § 2 锚点的确定。
值含义如下:
- none
- 锚名称 的作用域无变化。
- all
-
指定由该元素或其后代定义的所有 锚名称
(只要其作用域未被后代通过 anchor-scope 限制)都只对该元素的后代可见;
并且限定后代只能匹配该子树内 锚名称
的锚元素。
该值仅影响同一树作用域内的 锚名称, 就像是 严格匹配 的 树域名。 (也就是说,anchor-scope: all 的效果等同于 anchor-scope: --foo, --bar, ..., 即列出所有相关的 锚名称。)
- <anchor-name>
-
指定由该元素或其后代定义的匹配 锚名称
(只要其作用域未被后代通过 anchor-scope 限制)只对该元素的后代可见;
并限定后代只能匹配这些 锚名称
的锚元素
(在此子树内)。
<anchor-name> 表示一个 严格匹配的 树域名, 即只能与同一 shadow tree 里的 锚名称 匹配。[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>。
如果 query el 的某个祖先 满足下述条件, 则返回距离 query el 最近的该元素。 否则,返回树顺序中最后一个满足条件的元素 el。
-
el 对于 query el 是一个 可接受的锚元素。
若无元素满足上述条件, 则返回空。
注: anchor-scope 可限制特定 锚名称 的可见性, 从而影响哪些元素可被用作 锚元素。
注: 由一个 anchor-name 定义在某个 shadow tree 中, 该名称不会被不同 shadow tree 的 anchor 函数 样式所看到,以保证封装性。 但不同 shadow tree 中的元素 仍可互相锚定, 只要 anchor-name 和 anchor 函数 都来自同一树内的样式,比如用 ::part() 给 shadow 里的元素加样式。 (隐式锚元素 理论上也不限于单一树,但细节依赋值API而定。)
-
possible anchor 对 positioned el 处于可见作用域内, 具体由 anchor-scope 及其祖先对 possible anchor 的影响决定。
-
possible anchor 的布局严格早于 positioned el, 即下列之一成立:
-
若 possible anchor 处于 另一个元素的 跳过内容内, 则 positioned el 也需处于 同一元素的 跳过内容内。
注: 换句话说,positioned el 只有在与 possible anchor 同属于同一跳过“叶节点”时才能锚定该元素; 不可跨叶节点锚定。 这意味着跳过一个同时包含两者的元素, 不会导致 positioned el 锚定到别的地方, 但页面其它位置的定位元素依然无法锚定跳过的元素。
2.4. 默认锚点:position-anchor 属性
| 名称: | position-anchor |
|---|---|
| 取值: | normal | none | auto | <anchor-name> | match-parent |
| 初始值: | normal |
| 适用元素: | 绝对定位框 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 按指定值 |
| 规范顺序: | 依语法 |
| 动画类型: | 离散型 |
position-anchor 属性指定 默认锚元素, 该元素被 position-area、 position-try, 以及(默认情况下)应用于此元素的所有 锚函数 所使用。 position-anchor 是 仅重置子属性(reset-only sub-property), 属于 position 属性的一部分。
- normal
-
如 position-area 为 none, 则表现为 none。 否则, 等同于 auto。
- none
-
该框没有 默认锚元素。
- auto
- <anchor-name>
-
由指定 <anchor-name> 选中的 目标锚元素 即为该盒子的 默认锚元素。
- 匹配父元素
-
使用与父元素相同的默认锚元素——如果这是一个伪元素,则使用起始元素——如果有的话,并且如果该元素是可接受的锚元素。 否则,该盒子没有默认锚元素。
该 主框 (principal box) 是 默认锚元素 的 默认锚盒(default anchor box)。
.anchored{ position : absolute; top : calc ( .5 em +anchor ( outside)); /* 未指定锚名称, 因此自动引用默认锚盒。 */ } .foo.anchored{ position-anchor : --foo; } .bar.anchored{ position-anchor : --bar; }
2.4.1. 隐式锚点元素
某些规范可以定义,在特定情形下, 某个特定元素为另一个元素的 隐式锚点元素。
TODO: 待 HTML 规范正式收录相关内容后,补充 popover 相关新例子
隐式锚点元素 可通过 auto 关键字在 position-anchor 中引用, 或在 锚点函数 中省略锚点引用时引用之。
2.5. 锚点相关性
判断元素 el 是否 与用户相关 时, 如果其某个后代作为定位盒的 目标锚点元素 (且该定位盒自身不是 被跳过 的, 且其 包含块 不是 el 或 el 的后代), 则必须认为 el 与用户相关。
注: 这意味着,例如, content-visibility: auto 子树里的锚点, 只要依赖它的定位盒本身也不是被跳过的, 就会阻止其子树 被跳过内容。 (除非锚点和定位盒都在同一个 content-visibility: auto 元素之下; 二者不会互相循环保持可见。)
3. 基于锚点的定位
绝对定位盒 可以相对于页面上的一个或多个 锚点框 进行定位。
position-area 属性提供了基于网格的便捷方式以便于相对于 默认锚点框 定位; 如需更复杂或相对于多个盒子的定位, 可在 内边距属性 中通过 anchor() 函数显式引用某锚点框的边。
3.1. position-area 属性
| 名称: | position-area |
|---|---|
| 取值: | none | <position-area> |
| 初始值: | none |
| 适用元素: | 拥有 默认锚盒 的定位框 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 关键字 none,或一对关键字,详见§ 3.1.3 <position-area> 的计算值与序列化 |
| 规范顺序: | 依语法 |
| 动画类型: | 离散 |
大多数 锚点定位 的常见用例只关注 定位盒的 包含块 边界 及 默认锚点框 的边界。 可以把这些线看作构成了一个 3×3 网格; position-area 让你可以轻松指定 要将定位盒铺放在这个 position-area grid 中的哪个区域。
- none
-
该属性无效果。
- <position-area>
-
如果该盒没有 默认锚点框 或不是 绝对定位盒, 此值无效果。
否则,选择 position-area grid 的一个区域, 并将其作为该盒的 包含块。
注: 这意味着 内边距属性 表示相对 position-area 的偏移, 并且一些属性值(如 max-height: 100%) 也将相对于 position-area。
除 none 外的值还具有如下效果:
-
当 绝对定位包含块 由 滚动容器 生成时, 可滚动包含块 会替代 本地包含块, 以便整个 可滚动溢出区域(通常)都可用于定位。
-
任何 auto 内边距属性 及 auto margin 属性 的 used value 均解析为 0。
-
normal 值的 自对齐属性 解析为指定值,详见 § 4.1 区域默认对齐方式。
3.1.1. 解析 Position Area 网格
position-area 网格是一个 3×3 的网格, 每个轴由四条网格线组成。 顺序如下(使用 包含块的书写模式):
注意: 当 默认锚点盒子 部分或全部在修改前的 包含块之外时, position-area 网格的某些行或列可能为零尺寸。
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> 取值通过如下方式指定所选区域占据的网格行和列,从而选中 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
-
对应两个相邻的行或列, 取决于该关键字指定的是哪个轴: 包含中心行/列, 及与该关键字另一半相对应的行/列(参考单轨关键字)。
(例如 span-top 跨越前两行——中心行和顶部行。)
- span-all
-
对应所有三行或列, 取决于该关键字指定的是哪个轴。
有些关键字对于所属轴是模糊的: center、span-all, 以及未明确指定块或内联轴的 start 等关键字。 如果另一个关键字对于轴是明确的, 则模糊关键字指的是相反的轴。 (例如 block-start center 中, center 指的是内联轴。) 如果两个关键字都模糊, 则第一个关键字指盒子的 块轴, 第二个指 内联轴。 (例如 span-all start 等价于 span-all inline-start。)
如果只给出一个关键字, 且该关键字对于轴是明确的,则等价于第二个关键字为 span-all; 否则等价于重复该关键字。 (例如 top 等价于 top span-all, center 等价于 center center。)
3.1.3. <position-area> 的计算值与序列化
计算值为两个关键字,分别指明每个轴选中的区段, 长(block-start)和短(start)逻辑关键字视为等价。 按上方语法顺序序列化, 逻辑关键字用短形式 (如 start start 而不是 block-start inline-start)。
3.2. 锚点相对内边距:anchor() 函数
绝对定位盒 可以在其 内边距属性中 使用 anchor() 函数 以引用一个或多个 锚点框 的位置。 anchor() 函数会被解析为 <length>。 它只能用于内边距属性中 (否则无效)。
| 名称: | top、 left、right、bottom |
|---|---|
| 新值: | <anchor()> |
<anchor()> = anchor( <anchor-name>? && <anchor-side>, <length-percentage>? )
<anchor-side> = inside | outside
| top | left | right | bottom
| start | end | self-start | self-end
| <percentage> | center
anchor() 函数有三个参数:
-
<anchor-name> 的值 用于指定如何查找要提供定位信息的 锚元素。 其可选值包括:
- <dashed-ident>
- 省略
-
选择该盒子定义的 默认锚元素 (如有)。
详细说明见 目标锚元素。
-
<anchor-side> 值 指定了引用 目标锚点元素 的哪一侧位置。 其可能的值有:
- inside
- outside
-
解析为 锚点框 的一侧, 具体是哪一侧取决于函数出现在哪个 内边距属性 中。 inside 表示和当前内边距属性同侧(即将定位盒“吸附”在该 锚点框 该侧内), outside 表示相反。
- top
- right
- bottom
- left
- right
-
引用 锚点框 的指定侧。
注: 这些值只能用于对应轴向的 内边距属性。 例如 left 只能用于 left、right 或其它表示水平方向的逻辑 内边距属性 中。
- start
- end
- self-start
- self-end
- end
-
引用 锚点框 同轴上的某一侧, 该侧由函数出现的 内边距属性 所在轴与 当前定位盒(对于 self-start 和 self-end) 或包含块(对于 start 和 end)的书写方向决定。
- <percentage>
- center
-
引用 start 与 end 两侧之间的一个百分比位置, 其中 0% 等同于 start, 100% 等同于 end。
center 等价于 50%。
- inside
-
可选的 <length-percentage> 最后参数为回退值, 指定当 函数无法解析 时应取的值。
表示 可解析锚点函数 的 anchor() 在 计算值 时(借助 样式与布局交错)解析为 能使定位盒的 内边距修饰包含块 对应边与 目标锚点元素 的 锚点框 指定边对齐的 <length>。
注: 这意味着过渡或 动画 只要属性里用到了锚函数, 面向各种可能的变化都会“如预期”生效: 锚盒移动、 锚元素被加入或移出文档、 锚上的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() 通常会在两者中解析为不同的长度。
例如,在下方的图表中, 三个条形被设置为可用作锚的元素, 最小值/最大值线和提示框则使用 min() 和 max() 将引用所有三个条的 anchor() 函数组合在一起, 来确定它们自身的定位。 你可以使用每一列下方的范围输入来调整条形的高度, 并观察锚定的线和提示框会动态地根据最高/最低的条进行调整。
实现此功能的重要代码片段如下:
#bar-1{ anchor-name : --anchor-1; } #bar-2{ anchor-name : --anchor-2; } #bar-3{ anchor-name : --anchor-3; } .line{ position : absolute; left : anchor ( --chart left); right : anchor ( --chart right); &.max{ bottom : max ( anchor ( --anchor-1 top), anchor ( --anchor-2 top), anchor ( --anchor-3 top) ); } &.min{ bottom : min ( anchor ( --anchor-1 top), anchor ( --anchor-2 top), anchor ( --anchor-3 top) ); } }
3.2.1. anchor() 的解析
仅当同时满足全部以下条件时,anchor() 函数才是 可解析锚点函数:
-
它应用于绝对定位框。
-
如果它的 <anchor-side> 指定了物理关键字, 则它必须在适用于该轴的 内边距属性(inset property) 中指定。 (例如,left 只能用于 left、right 或用于水平方向的逻辑 内边距属性 中。)
-
对其应用的盒子存在 目标锚元素, 且函数中指定了 <anchor-name> 值。
如有任一条件不成立, anchor() 函数解析为其指定的回退值。如果未指定回退值, 该属性声明在计算值阶段视为无效。
3.3. 考虑滚动因素
出于性能考虑, 实现通常会在独立的滚动/“合成”线程上处理滚动, 而该线程仅具有限制的能力(可进行简单移动/变换等,但不能布局或执行高开销操作), 因此可以对滚动反应得足够快,在用户看来近似“即时”。
如果滚动仅导致锚点定位元素移动, 理论上没有问题; 元素的移动完全可在滚动线程中执行, 使定位元素能和滚动内容同步平滑移动。 但锚点定位允许元素 使其对边的位置取决于不同滚动上下文中的内容, 这意味着滚动可能只移动某一边,从而导致尺寸改变,引发布局。 这种操作无法由滚动线程处理!
为兼顾性能与灵活锚定的需求, 锚点定位 结合使用记忆滚动偏移 与滚动补偿。
-
当定位元素首次显示/变化到需回退时, 它的位置会根据所有最新的 锚点引用 正确计算。
如果这些 锚点引用 处于不同的滚动上下文里, 它们的滚动偏移会被记忆, 并且后续布局都会继续使用该偏移,即使这些元素后来发生滚动。 (仅滚动偏移被记录,实际布局位置每次都重新计算并保持准确。) 只有定位元素不再显示、再次出现或发生回退改变时才会重新计算。
-
唯一的例外是 默认锚点元素; 如果它相对于其记忆滚动偏移发生滚动, 定位元素会随之移动。 由于这仅是位置的变化, 定位元素的尺寸等不会因此改变或引发重新布局。
最终效果是 锚点定位通常总能“如期工作”, 无论锚点如何锚定,但响应滚动的方式可能受到一定限制。
元素在 确定回退定位样式时, 也会产生一次 锚重算点; 如果结果导致回退样式发生变化, 则被选择的回退样式关联的 锚重算点 作为结果使用。
当元素 abspos 发生一次 锚重算点, 那么对其所有 锚引用引用到的元素 anchor , 都会记录一个 记忆滚动偏移量(remembered scroll offset), 数值等于当前所有 滚动容器祖先的 滚动偏移量之和, 向上直至(但不包括) abspos 的 包含块。 记忆滚动偏移量 还应计入其它依赖滚动的定位变动, 如 position: sticky。 如果 abspos 有 默认锚元素, 无论它是否对该元素有 锚引用, 都要计算其 记忆滚动偏移量。
上述机制允许定位元素对它的 锚引用的滚动(scroll) 仅响应一次, 但任何一个被滚动后, 该定位元素将不再看似锚定于它们 (但它仍会响应它们非滚动引起的移动)。 这个问题一般无法彻底解决, 但对一个 锚引用的滚动是可以响应的: 即 默认锚元素:
-
abspos 有 默认锚盒。
-
abspos 对它的 默认锚盒 有 锚引用,或至少有指向相同滚动上下文中对象的锚引用, 即满足以下之一:
-
abspos 在该轴的 自身对齐属性 的用值为 anchor-center;
-
abspos 的 position-area 的值非 none
-
至少有一个 anchor() 函数作用于 abspos 的该轴 用值的 内边距属性, 且锚定的 目标锚元素 与 abspos 的 默认锚盒 有相同最近的 滚动容器祖先。
-
注: 如果 abspos 有 定位选项列表, 是否在某轴 补偿滚动 也会被选定的回退样式所影响。
abspos 的 默认滚动偏移(default scroll shift) 是一对分别表示水平轴和垂直轴的长度。 每个长度计算如下:
完成 abspos 的布局后, 还要根据 默认滚动偏移 进行额外移动, 效果如同施加了一个 transform (在其它变换之前)。
类似于 记忆滚动偏移量, 是否也可考虑 默认锚元素上的 transform?
注: 记忆滚动偏移量 会影响 anchor() 函数的值, 默认滚动偏移 则会在计算 内边距属性、 应用对齐等操作之后 直接移动该元素。 这通常是不可区分的, 但如 round(anchor(outside), 50px) 这类 非线性变换 默认锚元素位置的情况, 就会暴露出行为差异。
4. 基于锚点的对齐
4.1. 区域特定默认对齐
当 position-area 不是 none 时, 已用值 的 normal 自对齐 会根据 <position-area> 的值变化, 以便让盒子朝向锚点对齐:
-
如果某轴上只选中了 center 轨道, 则该轴上的默认对齐为 center。
-
如果三条轨道都被选中, 则该轴上的默认对齐为 anchor-center。
-
否则,默认对齐则朝向未被选中的那一侧轨道: 如果指定了轴的 “start” 轨道, 则该轴的默认对齐为 end 等等。
但如果相关轴只有一个 内边距属性 取 auto, 默认对齐则沿着非 auto 的那一边, 且这是 unsafe 对齐。
注: 这种单 auto 行为保持了 指定某一个内边距值即可控制 绝对定位 盒的位置的惯例。
此行为增加了定位盒子保持可见,并位于其预期范围内的可能性, 即便其 包含块 最终比预期的小。
举例来说,position-area: bottom span-right 值 让定位盒子可以从其锚点的左边缘 一直到包含块的右边缘拉伸, 并在该空间中默认左对齐。 但如果定位盒子大于该空间 (比如锚点非常靠近屏幕右侧时), 它会向左移动以保证可见。
4.2. 锚点居中对齐:anchor-center 对齐值
| 名称: | justify-self,align-self |
|---|---|
| 新增值: | anchor-center |
自对齐属性允许绝对定位盒子 在其插入修改后的包含块内对齐自身。 现有的取值, 以及精心选择的插入属性, 通常已足够实现常用的对齐, 但对于锚定定位中常见的需求——居中覆盖锚定盒——则需要细致且略为复杂的设置。
新的 anchor-center 值 极大地简化了这种场景: 如果定位盒有默认锚定盒, 那么会将盒子(在可能范围内) 居中于默认锚定盒 在相关的轴线上。 另外:
如果该盒子不是绝对定位, 或者没有默认锚定盒, 此值则表现为center ,并且对插入属性的解析没有其他影响。
注意: 使用anchor-center时,默认 如果锚点距离盒子的 原始包含块边缘太近, 盒子会“移动”而不是完全居中, 以保证位于原始包含块之内。 详见 CSS 盒对齐 3 § 4.4 溢出对齐:safe 和 unsafe 关键字及滚动安全限制。
5. 基于锚点的尺寸
绝对定位盒 可以在其 尺寸属性 中用 anchor-size() 函数 引用一个或多个 锚点框 的尺寸。 anchor-size() 函数会被解析为 <length>。 该函数仅允许用于 可接受的 @position-try 属性 (否则无效)。
5.1. anchor-size() 函数
| 名称: | width、height、min-width、min-height、max-width、max-height、top、 left、right、bottom、margin-top、margin-left、margin-right、margin-bottom |
|---|---|
| 新值: | <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>, 用于表示两个对立边之间的距离。
物理 <anchor-size> 关键字 (width 和 height) 分别表示 目标锚元素 的宽度和高度。 与 anchor() 不同,不要求轴线必须匹配; 例如,width: anchor-size(--foo height); 这样的写法也是合法的。
逻辑 <anchor-size> 关键字 (block、 inline、 self-block、 以及 self-inline) 会根据盒子的 书写模式 (对于 self-block 和 self-inline 而言) 或盒子的 包含块 的 书写模式 (对于 block 和 inline)映射到某个物理关键字。
如果省略了 <anchor-size> 关键字, 则默认按 anchor-size() 所在属性所对应的轴线的关键字行为。 (例如,width: anchor-size() 等价于 width: anchor-size(width)。)
表示 anchor-size() 的可解析锚尺寸函数 会在 计算值 阶段 (通过 样式与布局交错) 解析为分隔指定轴线上相关边 (无论是左右,还是上下) 的 <length>, 这些边属于 目标锚元素 的 锚定盒。
5.1.1. anchor-size() 的解析
仅当同时满足以下所有条件时, anchor-size() 是 可解析锚点尺寸函数:
-
应用于 绝对定位盒。
-
其用到的盒存在 目标锚点元素, 并且函数内指定的 <anchor-name> 能找到该元素。
如不满足上述任意条件, anchor-size() 解析为其回退值。 无回退值时,引用它的声明在计算值阶段 失效。
6. 溢出管理
锚定定位非常强大, 但也可能带来不可预测的效果。 锚定盒 可能出现在页面任意位置, 所以将一个盒子以特定方式定位 (比如在锚点上方或右侧) 可能会导致定位元素溢出其 包含块 ,甚至部分出现在屏幕之外。
为了解决这个问题, 绝对定位 的盒子 可以使用 position-try-fallbacks 属性 指定额外的 定位方案 (这些定位/对齐属性的变体集合可由盒子的现有样式生成, 或者通过 @position-try 规则显式指定) ,以便当盒子溢出其初始位置时,UA 可以尝试。 每个方案会依次应用到盒子上, 顺序按照 position-try-order 指定的顺序, 第一个不会导致盒子 溢出其 包含块 的方案即为最终结果。
一旦选择某个方案, 元素就会保持这个样式(直到再次溢出), 即使之后某个更优先的方案重新变得可用但不会溢出时, 也不会主动切换回去。 (见 记录上一次成功的位置方案。)
#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; /* 浮层最小宽度与按钮一致 */ min-width:anchor-size ( width); /* 浮层最小高度等于2个菜单项 */ min-height:6 em ; }
6.1. 提供回退选项:position-try-fallbacks 属性
| 名称: | position-try-fallbacks |
|---|---|
| 取值: | none | [ [<dashed-ident> || <try-tactic>] | <position-area> ]# |
| 初始值: | none |
| 适用元素: | 绝对定位盒子 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 按指定 |
| 规范顺序: | 基于语法 |
| 动画类型: | 离散 |
该属性提供一个可选定位样式列表, 当绝对定位盒子 溢出其 插入修改后的包含块 时进行尝试。 此 定位选项列表 初始包含一个来自元素 回退基础样式 生成的 定位选项,即 未应用 position-try-fallbacks 时的 计算样式。
列表中各个逗号分隔项为独立选项: 可以是 @position-try 代码块的名称, 也可以是代表盒子当前计算样式自动变换的 <try-tactic>。
取值含义如下:
- none
-
该属性无效; 盒子的 定位选项列表 为空。
- <dashed-ident>
-
如果存在以给定名称的 @position-try 规则, 其关联的 定位选项 会被加入 定位选项列表。
否则,该值无效。
- <try-tactic>
-
自动通过对盒子的 基础样式 执行指定 try tactic 创建 定位选项, 并将生成的 定位选项 添加到盒子的 定位选项列表。
<try-tactic> = flip-block || flip-inline || flip-start || flip-x || flip-y
- flip-block
-
交换块轴方向的属性取值 (如 margin-block-start 和 margin-block-end), 本质是在 行内轴 上做镜像。
- flip-inline
- flip-x
-
交换水平轴 的属性取值 (如 margin-left 与 margin-right), 本质是在 垂直轴 上做镜像。
- flip-y
- flip-start
-
交换start 属性之间的值, 以及 end 属性之间的值 (比如 margin-block-start 和 margin-inline-start 之间), 本质是沿着 start-start 角 到 end-end 角的对角线做镜像。
如果给出多个关键字, 则会按顺序组合这些转变以生成单个 定位选项。 逻辑方向会基于 书写模式 解析为 包含块 的物理方向。
- <dashed-ident> || <try-tactic>
-
结合前两种方式: 如果存在以该名称命名的 @position-try 规则, 则将其 定位选项 应用于基础样式, 然后再根据指定的 <try-tactic> 进行转换,并将结果加入 盒子的 定位选项列表。
否则不做任何操作。
- <position-area>
-
自动创建一个仅包含 position-area 属性的 定位选项。
6.2. 确定回退顺序:position-try-order 属性
| 名称: | position-try-order |
|---|---|
| 取值: | normal | <try-size> |
| 初始值: | normal |
| 适用元素: | 绝对定位盒子 |
| 继承性: | no |
| 百分比: | n/a |
| 计算值: | 按指定 |
| 规范顺序: | 基于语法 |
| 动画类型: | 离散 |
该属性允许元素根据对应 定位选项 可用空间进行排序, 适用于更关注盒子拥有尽可能多空间的场景, 而非严格遵循 position-try-fallbacks 声明顺序的情况。
<try-size> = most-width | most-height | most-block-size | most-inline-size
- normal
-
按照 定位选项 在 position-try-fallbacks 指定的顺序依次尝试。
- most-width
- most-height
- most-block-size
- most-inline-size
- most-height
-
对于 定位选项列表 的每一项, 应用该定位选项 至盒子, 并计算这些样式下 插入修改后的包含块的可用尺寸 (将 auto inset 值视为 0)。 按该尺寸大小对 定位选项列表 稳定排序, 最大的排前面。
.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; }
基础样式 和 --bottom-scrollable 选项可用高度相同, 因为这两种情况下 插入修改后的包含块都从锚点延伸到包含块边缘。 同理,flip-block 选项与 --top-scrollable 选项可用高度也一致。 因为 position-try-order 使用稳定排序, 所以这两组会保持各自相对顺序, *-scrollable 选项会排在后面; 而有更多可用空间的一组会排在最前面。
这会导致盒子首先以自己的自然高度, 在锚点更大空间的一侧对齐 (用 基础样式 或 flip-block 样式), 如果导致溢出,则回退为填满同一空间并变为可滚动 (用对应 *-scrollable 样式), 从而不会溢出并且不会去更小的空间。
6.3. position-try 速记
| 名称: | position-try |
|---|---|
| 值: | <'position-try-order'>? <'position-try-fallbacks'> |
| 初始值: | 见各自属性 |
| 适用对象: | 见各自属性 |
| 是否继承: | 见各自属性 |
| 百分比: | 见各自属性 |
| 计算值: | 见各自属性 |
| 动画类型: | 见各自属性 |
| 规范序: | 按语法 |
该速记属性同时设置 position-try-fallbacks 和 position-try-order。 如果省略了 <'position-try-order'>, 则该属性设置为其初始值。
6.4. @position-try 规则
@position-try 规则 定义一个具有指定名称的 定位选项, 其中可指定一组或多组可通过 position-try-fallbacks 应用于盒子的定位属性。
@position-try 规则的语法为:
@position-try <dashed-ident> {
<declaration-list>
}
前导符指定的 <dashed-ident> 是该规则的名称。 如果声明了多个同名的 @position-try 规则, 它们会像 @keyframe 规则一样层叠。
@position-try 规则仅接受 以下 属性:
在 <declaration-list> 里的属性不得使用 !important。 若使用会使该属性无效,但不会导致整个 @property-try 规则无效。
所有 @position-try 中的属性 都以 Position Fallback Origin 的身份应用到盒子上, 这是一个新的 层叠源, 介于 作者源 与 动画源 之间。
类似 动画源, 若值为 revert, 则视为该属性属于 作者源, 因此将回退到 用户源。 (和 动画源 一样, revert-layer 无特殊行为,按原样处理。)
注: @position-try 可接受属性 是仅影响盒子自身尺寸和定位的最小属性集合,不会影响其内容和其他样式。 这显著简化了位置回退的实现,并确保可根据可用空间移动锚定定位盒。 由于这些规则会覆盖 作者源 中的正常声明, 所以也降低了 @position-try 对其他属性层叠与继承的干扰。 未来扩展 容器查询 预计会支持基于所用位置回退条件查询元素, 以实现本文限制列表中不支持的条件样式。
注: 若多个元素要共用同一 @position-try 规则, 但各自锚点不同, 可省略 <anchor-name>,在 anchor() 中省略锚点名称, 并分别用 position-anchor 指定。
注: 最常用的回退定位方式(如初步将定位盒放在锚点某一侧,溢出时自动切到另一侧) 可直接用 position-try-fallbacks 关键字自动完成, 无需编写 @position-try。
6.5. 应用位置回退
当一个定位盒 (应用任何 默认滚动平移 后) 溢出其 内边距修饰包含块, 且 定位选项列表 中有多于一个 定位选项 时, 会确定位置回退样式, 以尝试选出不溢出的选项。 选中的样式通过 样式与布局交错机制应用到元素上, 所以会影响 计算值 (可触发过渡等), 虽然其本身依赖于布局及 已用值。
实现可视情况限制 定位选项列表 长度, 以减少多余布局消耗。此限制至少应为五个。
-
令 current styles 为 abspos 当前的用值样式, 即来自 已计算基础样式 (可能是先前回退的结果)。
-
依次遍历 position options list(定位选项列表)里的每个 option:
-
如果 option 就是当前 abspos 的上一次成功的位置选项, 跳过。
-
令 adjusted styles 为 应用位置选项 option 于 abspos 的结果。
-
令 el rect 为 abspos 的 margin box 大小和位置, cb rect 为以 adjusted styles 布局后的 abspos 的 已修正内嵌包含块 的大小和位置。
-
如果 cb rect 某个轴为负尺寸且被修正为零尺寸, 跳过。
注: 这样可防止零尺寸的 el rect 被当作落入负尺寸的 cb rect 内 并被错误选为成功选项。
-
如果 el rect 并未完全包含在 cb rect 内, 跳过。
-
返回 adjusted styles, 以及相应假设已计算的 记忆滚动偏移量集合。
-
-
断言:上一步未找到可避免溢出的 位置选项。
-
返回 current styles。
注: 后代溢出 el 不影响本算法,只判断 el 的 margin 盒。
注: 本算法有意跳过当前已应用的 定位选项,因此其 记忆滚动偏移不会刷新;所有回退都失败时沿用当前样式,则 记忆滚动偏移 保持不变。
在一次完整布局过程中, 一旦盒子确定了其回退样式(或确定无需回退), 后续布局的盒不会更改这一结果。
换句话说,布局“不向后追溯”。
6.5.1. 回退选项的维护与清除
对盒子的某些更改会直接影响 确定位置回退样式 并触发特殊处理,这些回退敏感更改包括:
-
其 长属性 中任何一个的计算值 (属于 position-try) 发生了变化。
-
其任何 被接受的 @position-try 属性 计算值发生变化。
-
任意被其引用的 @position-try 规则被添加、移除或修改。
为此只考虑 已计算基础样式 的变化, 即已计算样式 忽略所有来自 Transitions 或 Animations 级联来源的声明。
6.5.1.1. 记录上一次成功的位置选项
为了尽可能保持布局稳定, 确定回退定位样式时会优先考虑 上一次成功的位置选项, 其算法如下:
ResizeObserver
事件时,
应按如下方式
记录上一次成功的位置选项:
-
如果 el 拥有 上一次成功的位置选项, 且有任何与回退相关的变化, 就移除其上一次成功的位置选项。 然后为 el 确定回退定位样式, 并将其上一次成功的位置选项 设为它当前采用的 已接受的 @position-try 属性 (及其值)的集合。
-
否则,如果盒 el 是绝对定位, 则将其 上一次成功的位置选项 设为它当前采用的 已接受的 @position-try 属性 (及其值)的集合。
注: 该记录/移除的时机 特意与上次记忆尺寸的处理方式一致。
6.5.2. 应用位置选项
-
如 directions 同轴而相反,视为“对立”;否则(如是不同轴)为“垂直”。
-
取 el 的 @position-try 可接受属性,作为 styles。
-
对 styles 替换变量、env() 等函数和 任意替代函数。
env() 如引用带方向或轴, (如 safe-area-inset-top), 则变量按 directions 改换。
例如 top: env(safe-area-inset-top);,directions 如为 up, left,则 env() 按 env(safe-area-inset-left) 处理(下一步会替换到 left 属性上)。 -
交换 styles 中与 directions 关联的属性值。
注: 如 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%)。
-
对于 尺寸属性, 修改 anchor-size() 函数中指定的轴线, 以保持其与新方向的相对关系与原方向一致。
-
对于 自对齐属性, 如果 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 网格 所选的行/列 与新方向的相对关系与原方向保持一致。
-
-
返回 styles。
6.6. 条件隐藏:position-visibility 属性
| 名称: | position-visibility |
|---|---|
| 值: | always | [ anchors-valid || anchors-visible || no-overflow ] |
| 初始值: | anchors-visible |
| 适用对象: | 绝对定位盒 |
| 是否继承: | 否 |
| 百分比: | 不适用 |
| 计算值: | 同指定值 |
| 规范序: | 按语法 |
| 动画类型: | 离散 |
在某些情况下,显示绝对定位盒子可能并不合理。 该属性允许这些盒子根据常见的布局条件按条件可见。
- always
-
该属性无影响。 (无论锚定状态或是否溢出,盒子都显示。)
- anchors-valid
-
如果盒子的任何所需锚引用 无法解析为目标锚元素, 则该盒子的visibility 属性计算值为 。
什么是 所需锚引用? 即无回退值的 anchor() 函数; 默认锚点有时也算? 这里还需补充细节。
- anchors-visible
-
如果盒子有默认锚定盒, 但该锚定盒已不可见或被中间盒裁剪, 该盒子的visibility 计算值为 。
- no-overflow
-
如果该盒子,即使应用了position-try, 仍溢出其 插入修改后的包含块, 则其 visibility 属性计算值为 。
IntersectionObserver
检查的裁剪效果,
即由于 clip-path、
overflow,
或其他类似(如 绘制包含)
剪裁到 overflow 剪裁边缘。
若 anchor 区域非零,
它还必须有非零交集面积,
才视为未被完全裁剪。
是否 anchor 被中间盒裁剪
,必须在更新文档内容相关性后
(参见 content-visibility,[css-contain-2])
及运行任何 ResizeObserver
后,
在执行任何 IntersectionObserver
之前进行检查。
也可以在其他时刻检查以提升响应性。
注意: 这意味着如果 abspos 在 DOM 中紧邻其锚点, 即使锚点默认被滚动移出, 其仍可见,因为它会被相同的滚动器裁剪。
请确保此处关于裁剪的定义 和 View Transitions 的用法一致(因其有类似概念)。
注意: 这保证在“链式锚定”场景下, 若第一个 abspos 因本属性被隐藏 (如其锚点被滚落消失), 那么使用其为锚的另一个 abspos 也会被隐藏, 而不会还漂浮到无意义的位置。
7. 可访问性影响
CSS Anchor Positioning 不会在元素间创建、删除或更改可访问性绑定。 作者必须利用合适的标记特性控制这些绑定。
由于其用途多样, CSS Anchor Positioning 不会自动为定位盒和其锚点间建立任何语义关系。 例如,设计中的可视锚定关系 可能是元素与其语义锚之间, 也可能连接到锚点的祖先、兄弟或子代, 视需求决定视觉效果。 同样,有时即使有语义锚, 但未做视觉绑定,或反之亦然。
作者不得仅依赖 CSS 定位表现出来的视觉连接去建立元素间的语义关系。 没有合适标记,视觉上关联的元素在 DOM 中没有实际语义关系; 如果本应有,反而会导致在非视觉代理(如屏幕阅读器) 或非图形导航方式(如 tab)下难以操作。
Web 平台上很多现有和新特性 都可以显式建立语义关联,让非视觉代理也能受益。 例如,HTML 的 Popover API 会自动关联触发按钮与浮层元素, 并自动管理 tab 顺序; 它还自动设定触发按钮为浮层的 隐式锚元素, 也方便配合 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 属性
表示规则体中声明的属性,按指定顺序排列。
获取时,必须返回该 @position-try 规则的 CSSPositionTryDescriptors
对象,
其属性如下:
- computed flag
-
未设置
- readonly flag
-
未设置
- declarations
-
规则中声明的描述符,按指定顺序排列。
- parent CSS rule
-
上下文对象
- owner node
-
Null
9. 附录:样式与布局交错
样式与布局交错 是一种技术, 在布局过程中允许对子树进行样式更新, 从而可对元素的 计算样式进行追溯性更新。
此概念并非本规范的正确定义, 可能应移至 Cascade, 但此处需要一个可引用的草稿。
注意: 样式与布局交错 已用于 容器查询 和 容器查询长度。 如 10cqw 这类长度,会根据查询容器的尺寸布局信息解析为 计算长度, 因此当容器在布局间改变尺寸时可触发 过渡。
被接受的 @position-try 属性 在解析回退时也会 交错 (见 position-try)。
显然还需补充更多细节, 但目前“像容器查询一样处理”即可。 该行为本身也未定义, 但至少在一定程度上已实现互操作。
10. 安全性考虑
本文件尚未发现安全性问题。
11. 隐私性考虑
本文件尚未发现隐私问题。
12. 变更记录
自 2026年1月30日工作草案 以来的主要变更:
-
为 position-area 增加了 match-parent 值。 (Issue 8913)
-
将 position-area 标记为离散可动画。 (Issue 13577)
-
移除了 anchor-center 在 align-items 和 justify-items 的支持,因为这些属性对绝对定位盒子无效。 (Issue 13514)
自 2025年12月22日工作草案 以来的主要变更:
-
明确 position fallback 与过渡和动画的交互过程。 (Issue 13048)
-
明确对于 anchors-visible,若锚定盒非零,则交集也必须非零。 (Issue 13176)
-
锚元素查找先查祖先,失败时再查其它元素,这与 timeline 名称查找方式更一致。 (Issue 13364)
-
新增 position-anchor: normal 作为新的初始值。 (Issue 13067)
自 2025年10月7日工作草案 以来的主要变更:
-
为 position-try-fallbacks 添加 flip-x 和 flip-y。 (Issue 12869)
-
定义 anchor-center 也会使用 scrollable containing block, 以避免元素定位在本地包含块外部时触发溢出对齐。 (Issue 12952)
-
当 position-area 或 anchor-center 起作用时,将 auto 外边距解析为 0,因 HTML UA 默认样式对 popover 的影响。 同时移除了 dialog 对齐值(之前用于解决此问题的方式)。 (Issue 10258)
-
为 position-anchor 新增 none 值,并使其为初始值,避免所有具有隐式锚元素的绝对定位盒都自动使用 scrollable containing block。 注意初始值以后可能还会改,目前讨论仍未结束… (Issue 13067)
-
明确 flip-block、flip-inline 和 flip-start 使用包含块的书写模式。 (Issue 12869, Issue 13076)
-
明确在比较 inset-modified containing block 的尺寸时,auto inset 的值按零处理, 以用于 position options 的 position-try-order。 (Issue 12942)
-
为 clip-path 添加到 anchors-visible 考虑的裁剪效果列表,并明确检查时机。 (Issue 12732)
-
修复基本样式被意外从 position options list 中遗漏的错误。 (Issue 12890)
-
明确 anchors-visible 检查的时机。 (Issue 12732)
-
明确 normal 对齐的解析基于 position-area 的值, 并影响 使用值(进而影响溢出处理,见 [CSS-ALIGN-3])。
-
修复锚名称匹配必须根节点相同的算法错误,因为支持跨 Shadow DOM 匹配。 (Issue 12941)
-
明确在 inset-modified containing block 尺寸比较及 position-try-order 时,auto inset 按零处理。 (Issue 12942)
-
重组 § 6 溢出管理 和 § 2 锚点确定 的文字表述,使其更易读。 (Issue 12818, Issue 11022)
-
完善 § 7 可访问性影响 指南并澄清 UA 要求。 (Issue 10311)
-
优化示例。
另见 历史变更。