CSS 锚点定位模块 第1级

W3C 工作草案,

关于本文档的更多详情
此版本:
https://www.w3.org/TR/2025/WD-css-anchor-position-1-20251222/
最新发布版本:
https://www.w3.org/TR/css-anchor-position-1/
编辑草案:
https://drafts.csswg.org/css-anchor-position-1/
历史记录:
https://www.w3.org/standards/history/css-anchor-position-1/
反馈意见:
CSSWG 问题仓库
规范内反馈
编辑者:
Tab Atkins-Bittner (Google)
Elika J. Etemad / fantasai (Apple)
Ian Kilpatrick (Google)
前任编辑:
Jhey Tompkins (Google)
为本规范建议修订:
GitHub 编辑器

摘要

本规范定义了锚点定位, 允许一个定位元素可以根据页面上的一个或多个“锚点元素”来设置自己的尺寸和位置。

CSS 是用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等介质上如何呈现的语言。

文档状态

本节描述了本文档在发表时的状态。 当前 W3C 出版物列表及本技术报告的最新修订版 可在 W3C 标准与草案索引中找到。

本文档由 CSS 工作组 按照 推荐标准流程 作为工作草案发布。 工作草案的发布并不意味着 W3C 及其成员的认可。

本文件为草案,可能随时被更新、替换或废止。 不应将本文档引用为除“进行中工作”之外的其他用途。

请通过在 GitHub 提交 issue(推荐)反馈, 并在标题中包含规范代码“css-anchor-position”,如: “[css-anchor-position] ……评论摘要……”。 所有 issue 和评论均被归档。 或者,也可将反馈发送至(有归档)公共邮件列表 www-style@w3.org

本文件遵循 2025年8月18日 W3C 流程文档

本文件由遵循 W3C 专利政策的工作组产生。 W3C 维护着 该组相关专利披露的公开列表; 该页面也包含披露专利的说明。 任何个人若实际知晓某项专利且认为该专利包含必要权利要求, 必须依照 W3C 专利政策第6节进行披露。

1. 介绍

CSS 绝对定位允许作者将盒子放置在页面上的任意位置, 并不考虑除其包含块之外其他盒子的布局。 这种灵活性非常有用, 但也有局限——很多时候你希望相对于某个其他盒子进行定位。 锚点定位 (通过 position-anchorposition-area 属性 以及/或者 anchor 函数 anchor()anchor-size()) 让作者能够实现这一点, 即将一个绝对定位盒子“锚定”到页面上的一个或多个其他盒子 (它的锚点引用), 同时也允许尝试多个可能的位置, 以找到能够避免重叠/溢出的“最佳”位置。

例如,作者可能希望将工具提示定位在目标元素正上方且居中, 除非这会导致工具提示超出屏幕, 这种情况下应将其显示在目标元素下方。 这可以用以下 CSS 实现:
.anchor {
  anchor-name: --tooltip;
}
.tooltip {
  /* Fixpos 意味着我们不需要考虑包含块的关系;
     工具提示可以存在于 DOM 的任何地方。 */
  position: fixed;

  /* 所有锚定行为默认都会引用 --tooltip 锚点。 */
  position-anchor: --tooltip;

  /* 让工具提示的底部对齐到锚点顶部;
     这也会默认使工具提示和锚点(在水平方向的书写模式下)水平居中对齐。 */
  position-area: block-start;

  /* 如果工具提示溢出窗口则会自动切换,
     使其顶部对齐到锚点底部。 */
  position-try: flip-block;

  /* 防止过宽 */
  max-inline-size: 20em;
}

注意,使用 Popover API 会自动设置 position 并建立锚定关系, 而无需再设置 anchor-nameposition-anchor 的值 (通过定义隐式锚点元素), 因此这些属性无需显式再次设置。 如果使用正确的标记,这个例子可以简化为:

.tooltip {
  /* 使用 popover + popovertarget 属性会设置 'position: fixed',
     并已自动建立所需的 position-anchor 关系。 */
  position-area: block-start;
  position-try: flip-block;
  max-inline-size: 20em;
}

1.1. 值定义

本规范遵循 CSS 属性定义约定 (见 [CSS2]), 并采用 值定义语法 (见 [CSS-VALUES-3])。 未在本规范定义的值类型,可参见 CSS 值与单位 [CSS-VALUES-3] 规范。 与其它 CSS 模块结合时可能会扩展这些值类型的定义。

除了属性定义中列出的特定值外, 本规范定义的所有属性 还接受 CSS 全局关键字 作为属性值。 为了可读性,本文未重复列出。

如同 CSS 中除选择器匹配以外的大多数操作, 本规范特性在 扁平元素树 上起效。

2. 锚点的确定

本规范的多个特性都涉及 锚点框 的位置与尺寸。 除非另有说明, 此处指相关 边框盒 边界,即相关 主盒锚点元素。 在多数情况下,相关的 锚点元素 通过 默认锚点元素position-anchor 属性指定, 该属性可指向主机语言定义的 隐式锚点元素, 或由 CSS anchor-nameanchor-scope 属性命名的锚点。 (anchor() 函数也可直接引用命名锚点。)

锚点框 的位置和尺寸在布局完成后确定。 此位置和尺寸包含 缩放定位相关的调整 (如 position: relativeposition: sticky), 也包括变换(如 transformoffset-path)。 此类情况下,锚点框绝对定位 元素的 包含块 坐标空间中的轴对齐边界矩形将被采用。 由于变换通常会在不同的线程上优化执行, 因此基于变换的 锚点框 位置更新 可能会延迟几帧。 作者可以在可行情况下用绝对或相对定位来避免该延迟。

如果 锚点框分片, 且引用该 锚点框绝对定位 盒的 包含块 在相关 分片上下文 外部, 将采用其 盒片段 的轴对齐包围矩形。 (如果 绝对定位 盒本身位于 分片上下文 内, 它视 锚点框 为未分片——并且本身可能被 分片上下文 分片。)

出于性能原因, 滚动会被特殊处理,详见 § 3.3 考虑滚动因素。 其它布局后效果(如滤镜) 不会影响 锚点框 的位置。

2.1. 创建锚点:anchor-name 属性

Name: anchor-name
Value: none | <dashed-ident>#
Initial: none
Applies to: 所有产生 主盒 的元素
Inherited:
Percentages: 不适用
Computed value: 同指定值
Canonical order: 按语法
Animation type: 离散

anchor-name 属性声明 该元素是一个 锚点元素, 其 主盒 是一个 锚点框, 并为其指定一组 锚点名称 以供引用。 其值定义如下:

none

该属性不产生效果。

<dashed-ident>#

如果该元素生成 主盒, 则该元素为 锚点元素, 其 锚点名称 列表如指定。 每个 锚点名称 都是 宽松匹配树作用域名称

否则,该属性不产生效果。

锚点名称 不需要唯一。 不是所有元素都可以作为 某个盒子的 目标锚点元素。 因此,如果作用域合适,则一个名称可以复用于多个地方。

注:如果多个元素共享一个 锚点名称, 且对某个定位盒都可见, 那么 目标锚点元素 将为 DOM 顺序中的最后一个。 可以用 anchor-scope 属性进一步限制某个引用盒可见的名称。

锚点名称 默认不受 包含 影响; 即使元素有 样式布局包含 (或类似包含), 其后代的 锚点名称 依然对页面其他元素可见。

注:当元素处于另一个元素的 跳过内容 中时 (例如由 content-visibility: hidden 造成), 它不是 可接受锚点元素, 实际等效于没有名称。

注: Shadow DOM 里的定位元素 可以引用“上级”树中定义的 锚点名称。 目前还不能引用“下级” shadow 树中定义的 锚点名称

2.2. 限定锚点名称作用域:anchor-scope 属性

名称: anchor-scope
值: none | all | <dashed-ident>#
初始值: none
适用元素: 所有元素
是否继承:
百分比: 不适用
计算值: 同指定值
规范顺序: 按语法
动画类型: 离散

该属性将指定的 锚点名称 及其查找限制在此元素的子树内。 见 § 2 锚点的确定

值含义如下:

none
锚点名称 作用域不变。
all
指定该元素或其后代中定义的所有 锚点名称(未被后代自身指定 anchor-scope 的限制除外)只在该元素的后代中可见; 并且限制后代只能在当前子树内匹配 锚点名称锚点元素

此值只影响同一树作用域内的 锚点名称,等价于指定为 严格匹配树作用域名称。 (即 anchor-scope: all 行为与 anchor-scope: --foo, --bar, ... 指定所有相关 锚点名称 相同。)

<dashed-ident>
指定该元素或其后代中定义且未被后代 anchor-scope 限制的匹配 锚点名称,只在该元素的后代中可见; 并且限制后代只能在当前子树内将这些 锚点名称 匹配到 锚点元素

<dashed-ident> 代表 严格匹配树作用域名称, 即只能与同一 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 布局规则根据锚点和定位盒之间的关系(以及它们与包含块的关系), 对此有明确保证。 下方的条件正是将层叠上下文的规则翻译成锚定定位相关的精确约束, 以保证锚点定位不会出现循环引用。

要为查询元素 query el 和可选的 锚点指定符 anchor spec, 确定 目标 锚点元素
  1. 如果未指定 anchor spec,则返回 默认锚点元素(如存在),否则返回空。

  2. anchor specauto

    1. query el 有一个 隐式锚点元素 且为 可接受锚点元素, 则返回其元素。

    2. 否则,返回空。

    注: 未来的 API 也可能定义隐式锚点元素。届时规范会在此处进行明确,保证协调。

  3. 否则,anchor spec<dashed-ident>。 返回树顺序中最后一个满足以下条件的元素 el

    如果没有元素满足上述条件,返回空。

    注: anchor-scope 可限制某些 锚点名称 的可见性, 从而影响能被查找到的 锚点元素

注: 由一个 anchor-name 在某 shadow tree 的样式中定义的 不会被其它 shadow treeanchor 函数 看到,以保证封装性。 但不同 anchor-nameanchor function 都来自同一树范围的样式时,不同 shadow tree 的元素仍可互相锚定,比如用 ::part() 给 shadow 内部元素设样式。 (隐式锚点元素 也不限于单一树,具体细节视 API 实现。)

元素 possible anchor 对于 绝对定位 元素 positioned el, 如果同时满足以下所有条件,则是 可接受锚点元素

2.4. 默认锚点:position-anchor 属性

名称: position-anchor
值: none | auto | <anchor-name>
初始值: none
适用对象: 绝对定位盒
是否继承:
百分比: 不适用
计算值: 同指定值
规范顺序: 按语法
动画类型: 离散

position-anchor 属性指定 默认锚点元素, 该元素可被 position-areaposition-try 以及(默认情况下)应用于该元素的所有 锚点函数引用。 position-anchor仅重置子属性,属于 position 的一部分。

none

该盒没有 默认锚点元素

auto

如果存在,则使用 隐式锚点元素; 否则该盒没有 默认锚点元素

<anchor-name>

由指定 锚点名称 选中的锚点元素,作为该盒的 默认锚点元素

我们可能希望把初始值设得更智能一些, 根据 position-area 是否使用,在 noneauto 之间自动选择。[Issue #13067]

默认锚点元素主盒 即为该盒的 默认锚点框

例如,以下代码中, .foo.bar 元素 都可以使用相同的定位属性, 仅仅通过更改它们分别引用的锚点元素:
.anchored {
  position: absolute;
  top: calc(.5em + anchor(outside));
  /* 未指定 anchor name,
     因此默认会引用
     默认锚点框。 */
}

.foo.anchored {
  position-anchor: --foo;
}
.bar.anchored {
  position-anchor: --bar;
}

2.4.1. 隐式锚点元素

某些规范可以定义,在特定情形下, 某个特定元素为另一个元素的 隐式锚点元素

TODO: 待 HTML 规范正式收录相关内容后,补充 popover 相关新例子

隐式锚点元素 可通过 auto 关键字在 position-anchor 中引用, 或在 锚点函数 中省略锚点引用时引用之。

对于 伪元素,其 隐式锚点元素 是其 起始元素,除非另有说明。

2.5. 锚点相关性

判断元素 el 是否 与用户相关 时, 如果其某个后代作为定位盒的 目标锚点元素 (且该定位盒自身不是 被跳过 的, 且其 包含块 不是 elel 的后代), 则必须认为 el 与用户相关

注: 这意味着,例如, content-visibility: auto 子树里的锚点, 只要依赖它的定位盒本身也不是被跳过的, 就会阻止其子树 被跳过内容。 (除非锚点和定位盒都在同一个 content-visibility: auto 元素之下; 二者不会互相循环保持可见。)

3. 基于锚点的定位

绝对定位盒 可以相对于页面上的一个或多个 锚点框 进行定位。

position-area 属性提供了基于网格的便捷方式以便于相对于 默认锚点框 定位; 如需更复杂或相对于多个盒子的定位, 可在 内边距属性 中通过 anchor() 函数显式引用某锚点框的边。

3.1. position-area 属性

名称: position-area
值: none | <position-area>
初始值: none
适用对象: 具有 默认锚点框 的定位盒
是否继承:
百分比: 不适用
计算值: 关键字 none 或一对关键字,见 § 3.1.3 <position-area> 的计算值与序列化
规范顺序: 按语法
动画类型: TBD

大多数 锚点定位 的常见用例只关注 定位盒的 包含块 边界 及 默认锚点框 的边界。 可以把这些线看作构成了一个 3×3 网格; position-area 让你可以轻松指定 要将定位盒铺放在这个 position-area grid 中的哪个区域。

position-area: top left 示例, 适用于 horizontal-tb ltr 书写模式
none

该属性无效果。

<position-area>

如果该盒没有 默认锚点框 或不是 绝对定位盒, 此值无效果。

否则,选择 position-area grid 的一个区域, 并将其作为该盒的 包含块

注: 这意味着 内边距属性 表示相对 position-area 的偏移, 并且一些属性值(如 max-height: 100%) 也将相对于 position-area。

none 外的值还具有如下效果:

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

对应的单个行或列, 取决于该关键字指定的是哪个轴。

类似于 anchor(), 普通逻辑关键字 (startend 等) 指的是盒子的 包含块的书写模式。 x-start 等在指定物理轴的方向上也是一样。

self-* 逻辑关键字 (self-startself-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-all

对应所有三行或列, 取决于该关键字指定的是哪个轴。

有些关键字对于所属轴是模糊的: centerspan-all, 以及未明确指定块或内联轴的 start 等关键字。 如果另一个关键字对于轴是明确的, 则模糊关键字指的是相反的轴。 (例如 block-start center 中, center 指的是内联轴。) 如果两个关键字都模糊, 则第一个关键字指盒子的 块轴, 第二个指 内联轴。 (例如 span-all start 等价于 span-all inline-start。)

如果只给出一个关键字, 且该关键字对于轴是明确的,则等价于第二个关键字为 span-all; 否则等价于重复该关键字。 (例如 top 等价于 top span-allcenter 等价于 center center。)

3.1.3. <position-area> 的计算值与序列化

计算值为两个关键字,分别指明每个轴选中的区段, 长(block-start)和短(start)逻辑关键字视为等价。 按上方语法顺序序列化, 逻辑关键字用短形式 (如 start start 而不是 block-start inline-start)。

3.2. 锚点相对内边距:anchor() 函数

绝对定位盒 可以在其 内边距属性中 使用 anchor() 函数 以引用一个或多个 锚点框 的位置。 anchor() 函数会被解析为 <length>。 它只能用于内边距属性中 (否则无效)。

名称: topleftrightbottom
新值: <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() 函数有三个参数:

表示 可解析锚点函数anchor()计算值 时(借助 样式与布局交错)解析为 能使定位盒的 内边距修饰包含块 对应边与 目标锚点元素锚点框 指定边对齐的 <length>

注: 这意味着带 过渡动画 的属性只要用上 锚点函数,都能“如预期”随各种变化自动平滑过渡: 如 锚点框 移动、 锚点元素 动态增删、 anchor-name 属性变化等。

例如, .bar { inset-block-start: anchor(--foo block-start); } 中的 anchor() 解析为 使 .bar 元素的 block-start 边和 --foo 锚点的 block-start 边对齐的长度。

.bar { inset-block-end: anchor(--foo block-start); } 会解析为 使 .bar 元素的 block-end 边和 --foo 锚点的 block-start 边对齐的长度。

由于 inset-block-startinset-block-end 分别表示从包含块 block-start 和 block-end 边的内边距, 同一个 anchor() 通常会在两者中解析为不同的长度。

由于 anchor() 函数解析为 <length>, 因此可以像其它长度一样用于 数学函数 中。

需补一个更能体现 anchor() 特色的例子; 现在这个仅用 anchor-center 就可实现。[Issue #10776]

例如如下写法可让元素的 内边距修饰包含块 水平居中到 锚点框, 并自动尽可能铺宽而不溢出 包含块

.centered-message {
  position: fixed;
  max-width: max-content;
  justify-self: center;

  --center: anchor(--x 50%);
  --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);
}

这很适合用于 input 等元素的错误信息提示, 居中能方便用户确认到底在说哪个输入框。

3.2.1. anchor() 的解析

仅当同时满足全部以下条件时,anchor() 函数才是 可解析锚点函数

如有任一条件不成立, anchor() 函数解析为其指定的回退值。如果未指定回退值, 该属性声明在计算值阶段视为无效

3.3. 考虑滚动因素

出于性能考虑, 实现通常会在独立的滚动/“合成”线程上处理滚动, 而该线程仅具有限制的能力(可进行简单移动/变换等,但不能布局或执行高开销操作), 因此可以对滚动反应得足够快,在用户看来近似“即时”。

如果滚动仅导致锚点定位元素移动, 理论上没有问题; 元素的移动完全可在滚动线程中执行, 使定位元素能和滚动内容同步平滑移动。 但锚点定位允许元素 使其对边的位置取决于不同滚动上下文中的内容, 这意味着滚动可能只移动某一边,从而导致尺寸改变,引发布局。 这种操作无法由滚动线程处理!

为兼顾性能与灵活锚定的需求, 锚点定位 结合使用记忆滚动偏移滚动补偿

下面细节略为技术性,总结如下:

最终效果是 锚点定位通常总能“如期工作”, 无论锚点如何锚定,但响应滚动的方式可能受到一定限制。

对于绝对定位元素, 每当此元素开始生成盒(即由display:nonedisplay:contents 切换到其它 display 值),均会发生一个 锚点重算点, 这与 CSS 动画启动时机相同。

锚点重算点还会在该元素 判断位置回退样式时发生; 如果结果样式发生变化, 也会采用对应的 锚点重算点

当元素 abspos 发生锚点重算点时, 对于其所有 anchor(即 abspos 所引用的锚点引用), 均需要关联一个 记忆滚动偏移, 即当前该 滚动容器abspos包含块 往祖先逐级累加求和得到的滚动偏移。 还包括其它依赖滚动的定位变化, 如 position: sticky 等。 若 abspos默认锚点元素, 则也总会为其计算 记忆滚动偏移, 哪怕当前 abspos 实际没有锚点引用它。

所有 锚点引用 都先假定 所有 滚动容器 均位于初始滚动位置, 然后加上相应的 记忆滚动偏移

变换和滚动一样也会有类似问题, 因此锚点定位通常不会实时响应变换。这里是否也要考虑变换的影响?

上述机制允许被定位元素根据其 锚点引用 的滚动位置响应一次, 但后续如果发生滚动,定位元素不会再继续与其保持锚定 (但依然会响应锚元素的非滚动移动)。 这个问题无法彻底解决, 但我们可以选择对一组 锚点引用的滚动做出响应—— 即优先选择 默认锚点元素

abspos绝对定位盒, 若以下两个条件都满足,则该盒被认为在某轴上 对滚动做补偿

注: 如果 abspos位置选项列表, 那么是否在某轴对滚动做补偿,也会受应用回退样式影响。

abspos默认滚动平移 为一对横纵轴长度。 每个长度计算规则如下:

abspos 完成布局后, 还需将其整体平移 默认滚动平移 距离, 就像先应用了一个transform(在其它变换之前)。

需要明确记录快照时机: 每帧刷新,在样式重算之前更新。

类似 记忆滚动偏移, 是否也应同步考虑 默认锚点元素 上的变换?

注: 记忆滚动偏移 影响 anchor() 函数的取值, 默认滚动平移 则是在 内边距属性 计算完毕并完成对齐后统一整体平移。 对用户来说基本没有区别, 但对于如 round(anchor(outside), 50px) 这样对 默认锚点元素 位置做非线性变换的场景, 差异则会显现。

4. 基于锚点的对齐

4.1. 区域特定默认对齐

position-area 不是 none 时, 已用值normal 自对齐 会根据 <position-area> 的值变化, 以便让盒子朝向锚点对齐:

但如果相关轴只有一个 内边距属性auto, 默认对齐则沿着非 auto 的那一边, 且这是 unsafe 对齐。

注: 这种单 auto 行为保持了 指定某一个内边距值即可控制 绝对定位 盒的位置的惯例。

例如,假定为英文等价的书写模式(horizontal-tb, ltr), 值 span-x-start top 会解析为 垂直方向 start 区域(start), 和水平方向的 startcenter 区域, 因此默认对齐将是 align-self: end (使盒子的底部 外边距 正好与 top 区域的下边缘齐平), 以及 justify-self: end (使盒子的 end 侧 外边距 正好与 span-start 区域的 end 侧齐平)。
如果盒子溢出了其 内边距修饰包含块, 但仍可以放入其 原始包含块 内, 默认会“平移”以保持在 原始包含块 内, 即使这样会违反正常的对齐。 详见 CSS Box Alignment 3 § 4.4 Overflow Alignment: the safe and unsafe keywords and scroll safety limits

这种行为可以更好地保证定位盒保持可见, 且位于其预期的边界内, 即使 包含块 的尺寸比预期更小时也是如此。

例如 position-area: bottom span-right, 定位盒会从锚点左侧边缘拉伸到包含块右侧边缘, 默认在其间左对齐。 如果定位盒比这块空间还大 (比如锚点很靠近屏幕右边缘时), 盒子会左移以保持可见。

4.2. 锚点居中对齐:anchor-center 对齐值

名称: justify-selfalign-selfjustify-itemsalign-items
新值: anchor-center

自对齐属性允许绝对定位盒 在其 内边距修饰包含块 内自对齐。 现有的属性值和精心设置的 内边距属性 通常能满足常见的对齐需求, 但锚定定位中一个常见场景——居中覆盖 锚点框——实现起来需要较为复杂的设置。

新增的 anchor-center 值 让这类需求极为简单: 如果定位盒有 默认锚点框, 则尽可能在相关轴上居中于该 默认锚点框。 另外:

如果该盒不是 绝对定位盒, 或没有 默认锚点框, 则该值行为等同于 center, 不会影响 内边距属性 的解析。

注: 采用 anchor-center 时,默认情况下 如果锚点过于靠近盒子的 原始包含块 边缘, 就会从居中位置平移, 以确保仍然处于 原始包含块 内。 详见 CSS Box Alignment 3 § 4.4 Overflow Alignment: the safe and unsafe keywords and scroll safety limits

5. 基于锚点的尺寸

绝对定位盒 可以在其 尺寸属性 中用 anchor-size() 函数 引用一个或多个 锚点框 的尺寸。 anchor-size() 函数会被解析为 <length>。 该函数仅允许用于 可接受的 @position-try 属性 (否则无效)。

5.1. anchor-size() 函数

名称: widthheightmin-widthmin-heightmax-widthmax-heighttopleftrightbottommargin-topmargin-leftmargin-rightmargin-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> 关键字 (widthheight) 分别表示 目标锚点元素 的宽度和高度。 与 anchor() 不同,这里无需轴向对应限制; 比如 width: anchor-size(--foo height); 是合法的。

逻辑方向的 <anchor-size> 关键字 (blockinlineself-blockself-inline) 将按照盒子本身 (对于 self-blockself-inline) 或其 包含块 (对于 blockinline) 的 书写模式 映射到具体物理关键字。

如省略 <anchor-size> 关键字, 则表现为与 anchor-size() 使用的属性轴向一致的关键字。 (比如 width: anchor-size() 相当于 width: anchor-size(width)。)

可解析锚点尺寸函数anchor-size()计算值 阶段(借助 样式与布局交错) 解析为 <length>, 即 目标锚点元素锚点框 的相关两条边(左右或上下)的间距。

5.1.1. anchor-size() 的解析

仅当同时满足以下所有条件时, anchor-size()可解析锚点尺寸函数

如不满足上述任意条件, anchor-size() 解析为其回退值。 无回退值时,引用它的声明在计算值阶段 失效

6. 溢出管理

锚点定位虽然强大, 但也可能引入不可预知性。 锚点框 可能出现在页面任何位置, 因此将盒精确定位(比如放在锚点上方或右侧) 可能导致定位盒溢出其 包含块 或部分超出屏幕。

为解决这个问题, 绝对定位盒 可以用 position-try-fallbacks 属性 指定额外的 定位选项 (这些是根据盒子的现有样式生成的定位/对齐属性组合, 或由 @position-try 规则明确指定), 由 UA 在初始定位溢出时依次尝试。 每个选项会被应用到盒子上, 按 position-try-order 指定的顺序一一尝试, 第一个不导致溢出 包含块 的选项为最终方案。

一旦某个选项被选中, 元素会一直保留这些样式,直到再次溢出, 即使此前更优的选项又变得可用且不会溢出时也不改变。 (见 是否记住上次成功的位置选项。)

例如, 下面的 CSS 会首先把 “popover” 定位在目标元素下方, 如果不适合,则切换到上方。 默认与锚点起始端对齐, 若依然不适合,则换到末端对齐。 如果两边都放不下, 则会占满整个水平空间并尽量锚点居中显示 (受益于 § 4.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;

  /* popover 宽度不少于按钮宽 */
  min-width: anchor-size(width);

  /* popover 高度不少于 2 个菜单项 */
  min-height: 6em;
}

需要插图!

6.1. 提供回退选项:position-try-fallbacks 属性

名称: position-try-fallbacks
值: none | [ [<dashed-ident> || <try-tactic>] | <position-area> ]#
初始值: none
适用对象: 绝对定位盒
是否继承:
百分比: 不适用
计算值: 同指定值
规范序: 按语法
动画类型: 离散

该属性提供了一组可选定位样式, 当 绝对定位盒 溢出其 内边距修饰包含块 时会依次尝试。 这个 定位选项列表 最初只包含由元素的 回退基础样式(即不应用 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-startmargin-block-end)上的属性值, 本质上相当于绕 行轴做镜像。

flip-inline

交换 行轴上的属性值, 本质上相当于绕 块轴做镜像。

flip-x

交换 水平方向 (如 margin-leftmargin-right)上的值, 本质上绕 竖直方向做镜像。

flip-y

交换 竖直方向上的值, 本质上绕 水平方向做镜像。

flip-start

start 类属性互换, end 类属性之间也互换 (比如 margin-block-startmargin-inline-start), 等价于绕从 块起点-行起点块终点-行终点 的对角线做镜像。

若指定多个关键字, 则依次执行各变换,最后形成单一 定位选项。 逻辑方位以 书写模式包含块 解析。

<dashed-ident> || <try-tactic>

结合上述两类选项效果: 如有同名 @position-try 规则, 则先应用其 定位选项 到基础样式, 再依指定 <try-tactic> 变换后 加入到 定位选项列表

否则无效果。

<position-area>

自动创建只包含指定 position-area 属性的 定位选项

6.2. 确定回退顺序:position-try-order 属性

名称: position-try-order
值: normal | <try-size>
初始值: normal
适用对象: 绝对定位盒
是否继承:
百分比: 不适用
计算值: 同指定值
规范序: 按语法
动画类型: 离散

该属性允许元素按可用空间对其 定位选项 重新排序, 若希望盒子获得尽可能大空间而非严格遵循 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

定位选项列表 中的每个条目, 应用该定位选项 到盒子, 并计算依该样式获得的 内边距修饰包含块 的尺寸 (并将 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-fallbacksposition-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. 应用位置回退

当一个定位盒 (应用任何 默认滚动平移 后) 溢出其 内边距修饰包含块, 且 定位选项列表 中有多于一个 定位选项 时, 会确定位置回退样式, 以尝试选出不溢出的选项。 选中的样式通过 样式与布局交错机制应用到元素上, 所以会影响 计算值 (可触发过渡等), 虽然其本身依赖于布局及 已用值

实现可视情况限制 定位选项列表 长度, 以减少多余布局消耗。此限制至少应为五个。

确定位置回退样式算法(对元素 abspos):
  1. current styles 为当前 abspos 的已用样式(可能是此前回退结果)。

  2. 依次 遍历 定位选项列表 中每个 option

    1. option 是当前 abspos上一次成功定位选项,则跳过

    2. adjusted styles应用定位选项 optionabspos

    3. el rectabspos 的 margin 盒位置尺寸,cb rectabspos内边距修饰包含块位置尺寸(采用 adjusted styles 布局)。

    4. cb rect 某轴为负数自动修正为零,跳过

      注: 此举防止零尺寸 el rect 落在负尺寸 cb rect 内被误判为“内含”并被选为成功选项。

    5. el rect 不全集合于 cb rect跳过

    6. 返回 adjusted styles 及为该状态假定计算所得 记忆滚动偏移

  3. 断言:以上循环未找到可避免溢出的 定位选项

  4. 返回 current styles

注: 后代溢出 el 不影响本算法,只判断 elmargin 盒

注: 本算法有意跳过当前已应用的 定位选项,因此其 记忆滚动偏移不会刷新;所有回退都失败时沿用当前样式,则 记忆滚动偏移 保持不变。

在一次完整布局过程中, 一旦盒子确定了其回退样式(或确定无需回退), 后续布局的盒不会更改这一结果。

举例,假如有两个定位盒 A 和 B, 先布局 A,后布局 B。 如果 B 溢出导致 A 的包含块出现滚动条, 这不会导致 A 回过头重新判断自己的回退样式以躲开溢出。 (否则最坏情况下可能死循环甚至布局炸裂。)

换句话说,布局“不向后追溯”。

6.5.1. 回退选项的维护与清除

对盒子的某些更改会直接影响 确定位置回退样式 并触发特殊处理,这些回退敏感更改包括:

为尽量保证布局稳定, 确定位置回退样式 优先考虑 上一次成功定位选项,规则如下:

ResizeObserver 事件确定并派发时, 必须按如下方式记录上一次成功定位选项

注: 记录/移除的时机刻意与 last remembered sizes 处理相同。

6.5.2. 应用位置选项

应用定位选项到盒子的元素 el: 给定 定位选项 new styles
  1. new styles 作为 位置回退源 插入层叠, 计算层叠,完成必要布局以得到 el已用样式

    为计算这些样式,应推算一个假定锚点重算点, 采用所得的假定记忆滚动偏移推敲 el 格式。

  2. 返回 el已用样式

执行 try-tactic 于元素 el 的一组 styles, 在两个方向 directions 之间, 返回变换后的样式集:
  1. directions 同轴而相反,视为“对立”;否则(如是不同轴)为“垂直”。

  2. el@position-try 可接受属性,作为 styles

  3. styles 替换变量、env() 等函数和 任意替代函数

    env() 如引用带方向或轴, (如 safe-area-inset-top), 则变量按 directions 改换。

    例如 top: env(safe-area-inset-top);directions 如为 up, left,则 env()env(safe-area-inset-left) 处理(下一步会替换到 left 属性上)。
  4. 交换 styles 中与 directions 关联的属性值。

    例:swap "top" 与 "left" 时,margin-topmargin-left 交换,widthheight 交换,等等。

    注: 如 directions 为同轴对立,某些属性(如 widthalign-self) 不交换,但其值可能会被下步骤改动。

  5. 按新方向修改属性值具体如下:

  6. 返回 styles

6.6. 条件隐藏:position-visibility 属性

名称: position-visibility
值: always | [ anchors-valid || anchors-visible || no-overflow ]
初始值: anchors-visible
适用对象: 绝对定位盒
是否继承:
百分比: 不适用
计算值: 同指定值
规范序: 按语法
动画类型: 离散

在某些情况下,显示 绝对定位盒 可能没有意义。 此属性允许依据常见布局条件有条件地显示这些盒子。

always

该属性无效果。 (无论锚点或溢出状态如何,盒子都会显示。)

anchors-valid

如果盒子的任一 所需锚点引用 不能解析为 目标锚点元素, 该盒子的 visibility 属性计算为 force-hidden

所需锚点引用 是什么? 指没有回退值的 anchor() 函数; 默认锚点 *有时* 也算在内? 此处待补充更细说明。

是“任一”锚点缺失就隐藏, 还是“全部”锚点缺失才隐藏? 两者皆有用例,是否要定规或允许控制?

anchors-visible

如果盒子有 默认锚点框 但该 锚点框 不可见被中间盒裁剪, 则盒子的 visibility 计算为 force-hidden

no-overflow

如盒子即便应用 position-try 后仍溢出其 内边距修饰包含块, 则其 visibility 计算为 force-hidden

若锚点框 anchor 相对于依赖它的定位盒 abspos, 其 墨水溢出矩形 被一个盒子完全裁剪, 且该盒既是 anchor 的祖先,又是 abspos 的包含块的后代, 则称 anchor 被中间盒裁剪。 这里的裁剪仅指 IntersectionObserver 默认检测的那类裁剪, 即来自 clip-pathoverflow 或其它(如 绘制包含), 会裁剪到 溢出裁剪边缘的效果。

是否 被中间盒裁剪 必须在更新文档内容关联性 (见 content-visibility in [css-contain-2]) 并运行所有 ResizeObserver 后, 但必须在运行 IntersectionObserver 之前检查。 如为提升响应速度,也可在其它时机检查。

注: 这意味着如 abspos 和锚点元素在 DOM 中紧邻, 即使其默认锚被滚动移出,因被同一滚动器裁剪依然可见。

请确认本裁剪定义与 View Transitions 一致(后者有类似需求)。

注: 这保证“链式锚定”时, 若第一个 abspos 因锚点被隐藏导致隐藏, 则把它作锚点的其它 abspos 也会被隐藏,而不会浮到乱七八糟的位置。

7. 可访问性影响

CSS 锚点定位不会创建、删除或变更元素间的可访问性绑定。 作者需用合适标记手段确保可访问性关系。

由于本特性用法极多, CSS 锚点定位 不会自动在定位盒与其锚点间建立任何语义关系。 例如,设计中的视觉锚定关系 可能正好反映语义锚点; 也可能因视觉效果需要,连接到锚点的祖先、兄弟或后代元素; 也可能视觉上无需锚定却语义上绑定,反之亦然。

作者不应依赖 CSS 定位的可见连接 来建立元素间的语义关系。 若无合适标记支持, 这些仅视觉关联的元素在 DOM 层并无任何实际关系——若实际有语义关系缺乏标记支持, 就会导致如屏幕阅读器或键盘模式等非视觉用户代理难于甚至无法使用这些元素。

Web 平台有许多现有与即将到来的方案, 可用来明确表达语义关联,从而便于非视觉用户代理访问。 比如 HTML Popover API 会自动将触发按钮与 popover 元素关联, 并自动调整 Tab 顺序; 同时还会自动把触发按钮 设为该 popover 的 隐式锚点元素, 从而能直接配合锚点定位使用。

补一个 popover 示例。

更一般地, ARIA 特性如 aria-detailsaria-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. 变更记录

2025年10月7日工作草案 以来的主要更改:

另见 先前变更

一致性

文档约定

一致性要求采用描述性断言和 RFC 2119 术语相结合的方式表达。规范性部分中的关键词 “MUST”(必须)、 “MUST NOT”(禁止)、“REQUIRED”(要求)、“SHALL”(应当)、“SHALL NOT”(不得)、 “SHOULD”(应该)、“SHOULD NOT”(不应)、“RECOMMENDED”(推荐)、“MAY”(可以)、“OPTIONAL”(可选) 均按照 RFC 2119 的描述进行解释。 但为方便阅读,本规范未将这些词全部用大写字母表示。

除明确标记为非规范性、示例和注释的部分外,本规范中的所有内容均为规范性内容。[RFC2119]

本规范中的示例以“例如”开头,或通过 class="example" 与规范性文本区分,如下所示:

这是一个信息性示例。

信息性注释以“注意”开头,并通过 class="note" 与规范性文本区分,如下所示:

注意,这是一个信息性注释。

警示内容是规范性章节,会以特殊样式突出显示,并通过 <strong class="advisement"> 区分,如下所示: 用户代理必须(MUST)提供可访问的替代方案。

一致性类别

本规范的一致性定义分为三类:

样式表
CSS 样式表
渲染器
用户代理(UA) 负责解释样式表语义并渲染使用这些样式表的文档。
编辑工具
UA 用于编写样式表。

如果样式表中使用的语法均符合本模块定义的通用 CSS 语法和各功能的专属语法,则该样式表符合本规范。

渲染器符合本规范的条件是,除按相关规范解释样式表外,还能正确解析并渲染本规范定义的所有功能。 但 UA 由于设备限制无法正确渲染文档,并不被视为不符合规范。(例如,UA 不要求在黑白显示器上渲染颜色。)

编辑工具符合本规范的条件是,其编写的样式表在语法上符合通用 CSS 语法和本模块各功能的专属语法, 并符合本模块描述的所有其他样式表一致性要求。

部分实现

为便于作者利用向前兼容的解析规则设置回退值,CSS 渲染器必须 将所有不支持的 at-规则、属性、属性值、关键字及其他语法结构视为无效(并适当忽略)。 特别是,用户代理不得选择性地忽略多值属性声明中的不支持值并保留支持值: 如果任何值被视为无效(即不支持的值),则整个声明会被 CSS 要求忽略。

不稳定和专有特性的实现

为避免与未来稳定的 CSS 特性冲突, CSS 工作组建议遵循最佳实践, 实现不稳定特性和专有扩展

非实验性实现

一旦规范进入候选推荐(CR)阶段,非实验性实现就成为可能,且实现者应在能够证明其正确实现的情况下,发布无前缀的 CR 级特性实现。

为确保和维护 CSS 在各实现间的互操作性,CSS 工作组要求非实验性 CSS 渲染器在发布无前缀实现前向 W3C 提交实现报告(如有必要,还包括用于该报告的测试用例)。 提交给 W3C 的测试用例将由 CSS 工作组审查和修正。

关于提交测试用例和实现报告的进一步信息,可在 CSS 工作组网站 https://www.w3.org/Style/CSS/Test/ 上查阅。 如有问题,请联系 public-css-testsuite@w3.org 邮件列表。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-ALIGN-3]
Elika Etemad;Tab Atkins Jr.。CSS 盒对齐模块 3 级。2025 年 3 月 11 日。WD。URL:https://www.w3.org/TR/css-align-3/
[CSS-ANCHOR-POSITION-1]
Tab Atkins Jr.;Elika Etemad;Ian Kilpatrick。CSS 锚点定位。2025 年 10 月 7 日。WD。URL:https://www.w3.org/TR/css-anchor-position-1/
[CSS-BOX-4]
Elika Etemad。CSS 盒模型模块 4级。2024 年 8 月 4 日。WD。URL:https://www.w3.org/TR/css-box-4/
[CSS-BREAK-4]
Rossen Atanassov;Elika Etemad。CSS 分片模块 4级。2018 年 12 月 18 日。FPWD。URL:https://www.w3.org/TR/css-break-4/
[CSS-CASCADE-5]
Elika Etemad;Miriam Suzanne;Tab Atkins Jr.。CSS 级联与继承 5 级。2022 年 1 月 13 日。CR。URL:https://www.w3.org/TR/css-cascade-5/
[CSS-CASCADE-6]
Elika Etemad;Miriam Suzanne;Tab Atkins Jr.。CSS 级联与继承 6 级。2024 年 9 月 6 日。WD。URL:https://www.w3.org/TR/css-cascade-6/
[CSS-CONTAIN-2]
Tab Atkins Jr.;Florian Rivoal;Vladimir Levin。CSS 包含模块 2级。2022 年 9 月 17 日。WD。URL:https://www.w3.org/TR/css-contain-2/
[CSS-DISPLAY-3]
Elika Etemad;Tab Atkins Jr.。CSS 显示模块 3级。2023 年 3 月 30 日。CR。URL:https://www.w3.org/TR/css-display-3/
[CSS-DISPLAY-4]
Elika Etemad;Tab Atkins Jr.。CSS 显示模块 4级。2025 年 11 月 6 日。WD。URL:https://www.w3.org/TR/css-display-4/
[CSS-ENV-1]
CSS 环境变量模块 1级。2025 年 9 月 23 日。FPWD。URL:https://www.w3.org/TR/css-env-1/
[CSS-LOGICAL-1]
Elika Etemad;Rossen Atanassov。CSS 逻辑属性与属性值模块 1级。2025 年 12 月 4 日。WD。URL:https://www.w3.org/TR/css-logical-1/
[CSS-MASKING-1]
Dirk Schulze;Brian Birtles;Tab Atkins Jr.。CSS 遮罩模块 1级。2021 年 8 月 5 日。CRD。URL:https://www.w3.org/TR/css-masking-1/
[CSS-OVERFLOW-3]
Elika Etemad;Florian Rivoal。CSS 溢出模块 3级。2025 年 10 月 7 日。WD。URL:https://www.w3.org/TR/css-overflow-3/
[CSS-OVERFLOW-4]
David Baron;Florian Rivoal;Elika Etemad。CSS 溢出模块 4级。2023 年 3 月 21 日。WD。URL:https://www.w3.org/TR/css-overflow-4/
[CSS-POSITION-3]
Elika Etemad;Tab Atkins Jr.。CSS 定位布局模块 3级。2025 年 10 月 7 日。WD。URL:https://www.w3.org/TR/css-position-3/
[CSS-POSITION-4]
Elika Etemad;Tab Atkins Jr.。CSS 定位布局模块 4级。2025 年 10 月 7 日。WD。URL:https://www.w3.org/TR/css-position-4/
[CSS-PSEUDO-4]
Elika Etemad;Alan Stearns。CSS 伪元素模块 4级。2025 年 6 月 27 日。WD。URL:https://www.w3.org/TR/css-pseudo-4/
[CSS-SCOPING-1]
Tab Atkins Jr.;Elika Etemad。CSS 作用域模块 1级。2014 年 4 月 3 日。FPWD。URL:https://www.w3.org/TR/css-scoping-1/
[CSS-SIZING-3]
Tab Atkins Jr.;Elika Etemad。CSS 盒尺寸模块 3级。2021 年 12 月 17 日。WD。URL:https://www.w3.org/TR/css-sizing-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.;Simon Sapin。CSS 语法模块 3级。2021 年 12 月 24 日。CRD。URL:https://www.w3.org/TR/css-syntax-3/
[CSS-TRANSFORMS-1]
Simon Fraser 等。CSS 变换模块 1级。2019 年 2 月 14 日。CR。URL:https://www.w3.org/TR/css-transforms-1/
[CSS-VALUES-3]
Tab Atkins Jr.;Elika Etemad。CSS值与单位模块3级。2024 年 3 月 22 日。CRD。URL:https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.;Elika Etemad。CSS值与单位模块4级。2024 年 3 月 12 日。WD。URL:https://www.w3.org/TR/css-values-4/
[CSS-VALUES-5]
Tab Atkins Jr.;Elika Etemad;Miriam Suzanne。CSS值与单位模块5级。2024 年 11 月 11 日。WD。URL:https://www.w3.org/TR/css-values-5/
[CSS-VARIABLES-1]
Tab Atkins Jr.。CSS 可级联变量模块 1级。2022 年 6 月 16 日。CR。URL:https://www.w3.org/TR/css-variables-1/
[CSS-VIEWPORT-1]
Florian Rivoal;Emilio Cobos Álvarez。CSS 视口模块 1级。2024 年 1 月 25 日。FPWD。URL:https://www.w3.org/TR/css-viewport-1/
[CSS-WRITING-MODES-4]
Elika Etemad;Koji Ishii。CSS 书写模式 4级。2019 年 7 月 30 日。CR。URL:https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos 等。层叠样式表2级(CSS 2.1)规范。2011 年 6 月 7 日。REC。URL:https://www.w3.org/TR/CSS2/
[CSSOM-1]
Daniel Glazman;Emilio Cobos Álvarez。CSS 对象模型(CSSOM)。2021 年 8 月 26 日。WD。URL:https://www.w3.org/TR/cssom-1/
[HTML]
Anne van Kesteren 等。HTML 标准。活标准。URL:https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren;Domenic Denicola。Infra 标准。活标准。URL:https://infra.spec.whatwg.org/
[INTERSECTION-OBSERVER]
Stefan Zager;Emilio Cobos Álvarez;Traian Captan。Intersection Observer。2023 年 10 月 18 日。WD。URL:https://www.w3.org/TR/intersection-observer/
[MOTION-1]
Tab Atkins Jr.;Dirk Schulze;Jihye Hong。Motion 路径模块 1级。2024 年 11 月 5 日。WD。URL:https://www.w3.org/TR/motion-1/
[RESIZE-OBSERVER-1]
Aleks Totic;Greg Whitworth。Resize Observer。2020 年 2 月 11 日。FPWD。URL:https://www.w3.org/TR/resize-observer-1/
[RFC2119]
S. Bradner。指示 RFC 中需求级别的关键字。1997 年 3 月。最佳实践。URL:https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad;Tab Atkins Jr.。选择器 4级。2022 年 11 月 11 日。WD。URL:https://www.w3.org/TR/selectors-4/
[STREAMS]
Adam Rice 等。Streams 标准。活标准。URL:https://streams.spec.whatwg.org/
[WEBIDL]
Edgar Chen;Timothy Gu。Web IDL 标准。活标准。URL:https://webidl.spec.whatwg.org/

参考文献(非规范性)

[CSS-CONDITIONAL-5]
Chris Lilley 等。CSS 条件规则模块 5级。2025 年 10 月 30 日。WD。URL:https://www.w3.org/TR/css-conditional-5/
[CSS-SHADOW-PARTS-1]
Tab Atkins Jr.;Fergal Daly。CSS Shadow Parts 模块 1级。2025 年 12 月 16 日。WD。URL:https://www.w3.org/TR/css-shadow-parts-1/
[CSS-SIZING-4]
Tab Atkins Jr.;Elika Etemad;Jen Simmons。CSS 盒尺寸模块4级。2021 年 5 月 20 日。WD。URL:https://www.w3.org/TR/css-sizing-4/
[CSS-TRANSITIONS-1]
David Baron 等。CSS 过渡。2018 年 10 月 11 日。WD。URL:https://www.w3.org/TR/css-transitions-1/
[DOM]
Anne van Kesteren。DOM 标准。活标准。URL:https://dom.spec.whatwg.org/
[WEB-ANIMATIONS-1]
Brian Birtles 等。Web 动画。2023 年 6 月 5 日。WD。URL:https://www.w3.org/TR/web-animations-1/

属性索引

名称 属性值 初始值 适用对象 继承 %ages 动画类型 规范序 计算值 新值
align-items anchor-center
align-self anchor-center
anchor-name none | <dashed-ident># none 所有生成主盒的元素 不适用 离散 按语法 同指定值
anchor-scope none | all | <dashed-ident># none 所有元素 不适用 离散 按语法 同指定值
justify-items anchor-center
justify-self anchor-center
position-anchor none | auto | <anchor-name> none 绝对定位盒 不适用 离散 按语法 同指定值
position-area none | <position-area> none 具有默认锚点框的定位盒 不适用 TBD 按语法 关键词 none 或一对关键字,参见
position-try <'position-try-order'>? <'position-try-fallbacks'> 见各自属性 见各自属性 见各自属性 见各自属性 见各自属性 按语法 见各自属性
position-try-fallbacks none | [ [<dashed-ident> || <try-tactic>] | <position-area> ]# none 绝对定位盒 不适用 离散 按语法 同指定值
position-try-order normal | <try-size> normal 绝对定位盒 不适用 离散 按语法 同指定值
position-visibility always | [ anchors-valid || anchors-visible || no-overflow ] anchors-visible 绝对定位盒 不适用 离散 按语法 同指定值

IDL 索引

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

问题索引

我们或许希望把初始值改得更智能一些, 根据是否使用 position-area 自动选择 noneauto[议题 #13067]
补一个更好的例子;目前这个例子用 anchor-center 就能轻松实现。[议题 #10776]
变换(transform)和滚动有类似的问题, 所以锚点定位通常也不会实时考虑变换的影响。 这个地方能否直接把 transform 效果也纳入?
应精确定义快照时机: 每一帧刷新前,在样式重算之前更新。
类似 记忆滚动偏移, 能否同步考虑 默认锚点元素 上的 transform?
请添加插图!
所需锚点引用 是什么? anchor() 函数未指定回退值的算, 默认锚点有时也算? 这里需要更详细的定义。
到底是 有任意 一个锚点缺失就算(隐藏), 还是 全部 锚点缺失才算? 两种做法都可能有需求, 是要统一规定还是考虑加以控制?
要确保这里对“裁剪”概念的定义 跟 View Transitions 保持一致, 那边有类似需求。
补充一个 popover 示例。
欢迎提出改进本节的建议, 尤其是作者指引与常见用法的最佳实践范例。[议题 #10311]
这个概念不应该放在本规范, 可能更适合放进 Cascade 里, 不过现在需要一份草稿来作引用。
显然这里还需要补充很多细节, 但目前“跟容器查询一样处理”就可以了。 那个行为本来也没明确定义过, 但各实现之间基本能互通吧?