1. 引言
本节内容不具规范性。
CSS布局算法默认情况下,会相互调整盒子的大小和位置,以确保内容不会重叠。
本规范定义了在需要时,打破这些假设的几种方法,将元素移动到其他内容上方,使其重叠:
这些定位方案,由position属性和内边距属性控制,虽然功能强大,但很容易被误用。适当使用可以实现很多有趣且实用的布局,而不依赖标准的布局规则;如果使用不当,则可能导致页面内容混乱且无法使用。
1.1. 模块交互
本模块替代并扩展了定位方案功能,定义于[CSS2]中的以下章节:
- 9.1.2 包含块
- 9.3 定位方案
- 9.4.3 相对定位
- 9.6 绝对定位
- 9.7 display、position 和 float 之间的关系
- 9.8 正常流、浮动和绝对定位的比较
- 10.1 “包含块”的定义
- 10.3.7 绝对定位的非替换元素的宽度
- 10.3.8 绝对定位的替换元素的宽度
- 10.6.4 绝对定位的非替换元素的高度
- 10.6.5 绝对定位的替换元素的高度
它还取代并废除了 [CSS-LOGICAL-1] 中的 inset* 属性定义(CSS 逻辑属性 1 § 4.3 流相对偏移:inset-block-start、inset-block-end、inset-inline-start、inset-inline-end 属性以及 inset-block、inset-inline 和 inset 简写)。
1.2. 值定义
本规范遵循CSS属性定义惯例,定义于[CSS2],并使用值定义语法,定义于[CSS-VALUES-3]。未在本规范中定义的值类型可参考CSS值与单位模块[CSS-VALUES-3]。与其他CSS模块组合使用可能会扩展这些值类型的定义。
除各属性定义中列出的特定值外,本规范中定义的所有属性还接受CSS-wide 关键词作为属性值。为了提高可读性,未在每个定义中显式重复这些关键词。
2. 选择定位方案:position 属性
名称: | position |
---|---|
值: | static | relative | absolute | sticky | fixed |
初始值: | static |
适用于: | 所有元素,除 table-column-group 和 table-column |
继承: | 否 |
百分比: | N/A |
计算值: | 指定的关键字 |
规范顺序: | 依照语法 |
动画类型: | 离散 |
position 属性决定使用哪种定位方案来计算盒子的定位。 除static外的值使盒子成为定位的盒子, 并为其后代建立绝对定位包含块。 这些值具有以下含义:
- static
- 盒子不是定位的盒子, 按照其父级格式化上下文的规则布局。 内边距属性不适用。
- relative
- 盒子的布局类似于static, 然后相对于结果位置进行偏移。 这种偏移仅是视觉效果, 除非另有规定, 否则不会影响其他非后代盒子的大小或位置, 仅在增加其祖先的可滚动溢出区域的情况下例外。 这种定位方案称为相对定位。
- sticky
- 与relative相同, 但其偏移相对于最近的祖先滚动容器的滚动视口(由内边距属性修正), 自动进行调整,以便在用户滚动时尽量保持盒子在其包含块内可见。 这种定位方案称为粘性定位。
- absolute
-
盒子被脱离文档流,
因此不会影响其兄弟和祖先的大小或位置,
并且不参与其父级的格式化上下文。
相反,盒子的定位和大小仅参考 其绝对定位包含块, 由盒子的内边距属性修正, 请参见§ 4 绝对定位布局模型。 它可以与流内内容或其他绝对定位的元素重叠, 并包含在生成其包含块的盒子的可滚动溢出区域中。 这种定位方案称为绝对定位。
- fixed
- 与absolute相同, 不同的是,盒子的定位和大小相对于固定定位包含块(通常是视口在连续媒体中,或者是页面区域在分页媒体中)。 盒子的定位相对于这个参考矩形是固定的: 当附着到视口时,文档滚动时不会移动, 当附着到页面区域时,在文档分页时会在每一页上复制。 这种定位方案称为固定定位,并被视为绝对定位的一个子集。
position 值为 absolute 或 fixed 会将盒子块化,导致 float 计算为 none,并强制盒子建立独立的格式化上下文。
2.1. 定位盒的包含块
static、relative 或 sticky 盒子的包含块由其格式化上下文定义。 对于 fixed 和 absolute 盒子,其定义如下:
- 如果盒子具有 position: absolute:
-
包含块由最近的建立了绝对定位包含块的祖先盒子建立,方式如下:
- 如果祖先不是行内盒子,
- 包含块由祖先的内边距边缘形成, 除非另有规定 (例如,参见 CSS 网格布局 1 § 9.1 以网格容器作为包含块)。
- 如果祖先是行内盒子, 使用该盒子的书写模式,
-
包含块通过以下方式形成:从祖先的第一个盒片段的起始最远内容边缘(双轴)和祖先在每个轴上的结束最远内容边缘的结束最远盒片段形成一个矩形。
如果同一行上有多个片段
(例如,由于 bidi 重排),
则将起始最远的片段
作为第一个片段。
当盒子跨越多行分片时, 形成一个有用的包含块是什么? [问题 #8284]
注意:可能导致盒子建立绝对定位包含块的属性包括 position、transform、will-change、contain……
- 如果盒子具有 position: fixed:
-
包含块由最近的建立了固定定位包含块的祖先盒子建立,
包含块的边界确定方式与绝对定位包含块相同。
注意:可能导致盒子建立固定定位包含块的属性包括 transform、will-change、contain……
如果没有祖先建立, 则固定定位包含块是:
在没有任何定位的情况下,以下文档中的包含块(C.B.):
<!DOCTYPE html> < html > < head > < title > 包含块的示例</ title > </ head > < body id = "body" > < div id = "div1" > < p id = "p1" > 这是第一段中的文本...</ p > < p id = "p2" > 这是文本< em id = "em1" > 在< strong id = "strong1" > 第二段</ strong > 中的</ em ></ p > </ div > </ body > </ html >
如下所建立:
由以下内容生成的盒子 | 由以下内容建立的包含块 |
---|---|
html | 初始包含块(取决于用户代理) |
body | html |
div1 | body |
p1 | div1 |
p2 | div1 |
em1 | p2 |
strong1 | p2 |
如果我们定位 "div1":
#div1{ position : absolute; left : 50 px ; top : 50 px }
它的包含块不再是 "body",而成为初始包含块(因为没有其他已定位的祖先盒子)。
如果我们还定位 "em1":
#div1{ position : absolute; left : 50 px ; top : 50 px } #em1{ position : absolute; left : 100 px ; top : 100 px }
包含块的表格变为:
由以下内容生成的盒子 | 由以下内容建立的包含块 |
---|---|
html | 初始包含块(取决于用户代理) |
body | html |
div1 | 初始包含块 |
p1 | div1 |
p2 | div1 |
em1 | div1 |
strong1 | em1 |
通过定位 "em1",它的包含块成为最近的已定位祖先盒子(即 "div1" 所生成的盒子)。
2.1.1. 进一步调整包含块
某些特性可以改变绝对定位盒子的有效包含块矩形。 这些特性按以下顺序应用, 较早的步骤会修改后续步骤所看到的包含块:
-
其包含块由网格容器生成的绝对定位盒子上的网格放置属性可以将包含块矩形更改为指定的网格区域。 参见 CSS 网格布局 1 § 9.1 以网格容器作为包含块。
-
position-area 和 position-try 属性可以将包含块矩形更改为位置区域网格的指定区域。 参见 CSS 锚点定位 § 3.1 position-area 属性。
元素的原始包含块是应用任何这些效果之前的包含块。
2.2. 绘制顺序和堆叠上下文
z-index 属性适用于所有定位的盒子。 当 z-index 为 auto 时:
有关 z-index、堆叠上下文和绘制顺序的详细信息,请参阅 CSS2 § 9.9 层叠显示和附录 E:堆叠上下文的详细说明。
3. 定位坐标
一个已定位的盒子的精确位置由 插入属性控制: 物理物理方向的插入属性包括 top、right、bottom、 left; 流相对流相对方向的插入属性包括 inset-block-start、inset-inline-start、inset-block-end、inset-inline-end; 以及它们的简写属性,inset-block、inset-inline、 以及inset。
3.1. 盒子插入: top、right、bottom、left、inset-block-start、inset-inline-start、inset-block-end、inset-inline-end 属性
名称: | top、 right、 bottom、 left、 inset-block-start、 inset-inline-start、 inset-block-end、 inset-inline-end |
---|---|
值: | auto | <长度-百分比> |
初始值: | auto |
适用对象: | 已定位元素 |
继承属性: | 否 |
百分比值: | 相对于 包含块 的大小;详见说明 |
计算值: | 关键字 auto 或者计算出的 <长度-百分比> 值 |
规范顺序: | 依据语法 |
动画类型: | 依据计算值类型 |
逻辑属性组: | inset |
这些插入属性 代表在盒子对应边的内向“插入” (相对于盒子的书写模式; 参见 CSS Writing Modes 3 § 6 抽象盒子术语)。 例如,top 代表顶部边缘向下的插入。 物理物理和流相对流相对属性 的交互按 [CSS-LOGICAL-1] 中定义。 各值含义如下:
- <长度>
- 插入距离是相对于参考边的固定距离。 允许负值。
- <百分比>
- 插入距离相对于包含块的大小的百分比 (例如对于left或right 是宽度,对于top和bottom 是高度)。 对于粘性定位的盒子, 插入是相对于相应的滚动视口的大小。 允许负值。
- auto
- 代表未约束的插入; 具体含义取决于定位方案。
注意: 对于固定定位元素, 使用较大的值或负值 可能会轻易将元素移出视口, 导致内容无法通过滚动或其他方式访问。
3.2. 盒子插入简写: inset-block、inset-inline,以及inset 属性
名称: | inset-block、inset-inline |
---|---|
值: | <'top'>{1,2} |
初始值: | auto |
适用对象: | 已定位元素 |
继承属性: | 否 |
百分比值: | 参见单个属性 |
计算值: | 参见单个属性 |
规范顺序: | 依据语法 |
动画类型: | 依据计算值类型 |
inset-block和inset-inline属性是简写属性,用于在一个声明中分别设置inset-block-start + inset-block-end或inset-inline-start + inset-inline-end。 第一个组件值设置起始边, 第二个设置终止边; 如果省略,第二个值默认为第一个。
名称: | inset |
---|---|
值: | <'top'>{1,4} |
初始值: | auto |
适用对象: | 已定位元素 |
继承属性: | 否 |
百分比值: | 参见单个属性 |
计算值: | 参见单个属性 |
规范顺序: | 依据语法 |
动画类型: | 依据计算值类型 |
inset属性是简写属性,用于在一个声明中设置所有插入属性, 将值分配给表示每个边的长名称, 就像margin属性对其长名称所做的那样。
默认情况下,inset属性值 被分配给相应的物理长名称属性——top、right、bottom,以及left——由于历史原因,这些属性没有以inset-前缀开头。 这与其他"4个值分配给边"的属性行为相匹配, 例如margin。
允许此类属性解析为流相对长名称属性的做法 正在[CSS-LOGICAL-1]中讨论。
是的,我们理解这有点令人困惑,即 inset 不会展开为任何 inset-* 属性。
3.3. 相对定位
对于相对定位的盒子, 插入属性 会将盒子从相应边缘向内移动, 而不改变其大小。left将盒子向右移动,right将其向左移动, 等等。 由于盒子不会因相对定位而被分割或拉伸, 在给定轴上的相对使用值必须是互为相反数的:
- 如果某个轴上的相对插入属性都计算为auto(它们的初始值), 它们的使用值为零 (即,盒子在该轴上保持在原位)。
- 如果只有一个为auto, 其使用值变为另一个的相反数, 并且盒子按照指定的数值移动。
- 如果两者都不是auto, 则位置约束过多; (相对于其书写模式的包含块) 计算的终止侧值将被忽略, 其使用值变为起始侧的相反数。
以下三条规则是等价的, 都将盒子向左移动1em:
div.a8{ position : relative; direction : ltr; left : -1 em ; right : auto} div.a8{ position : relative; direction : ltr; left : auto; right : 1 em } div.a8{ position : relative; direction : ltr; left : -1 em ; right : 5 em }
如果指定在 table-row-group、table-header-group、table-footer-group 或 table-row 盒子上,则偏移会影响盒子的所有内容, 包括源自受影响行的所有表格单元格, 但不包括那些不源自受影响行的单元格。
注意:由于 position 不适用于 table-column-group 或 table-column 盒子, 因此它们不受相对定位的影响。
3.4. 粘性定位
粘性定位 类似于相对定位, 只是偏移量是根据最近的滚动视口自动计算的。
对于粘性定位的盒子, 插入属性 表示距离最近的滚动视口 各边缘的插入, 用于定义约束盒子位置的粘性视图矩形。 (为此,auto值表示零插入。) 如果这导致在某个轴上的粘性视图矩形大小 小于该轴上边框盒的大小, 则会减少受影响轴上的有效终止边缘插入值(可能变为负数), 以使该轴上的粘性视图矩形的大小达到 边框盒的大小 (其中终止边缘是相对于书写模式解释的 包含块)。
但如果最近的滚动视口只有100px高, 则有效的底部插入变为-120px, 生成的粘性视图矩形高200px, 足以完全包含粘性盒子的外边距盒。
对于盒子的每一侧, 如果相应的插入属性不是 auto, 并且盒子的相应边框边缘将位于 粘性视图矩形相应边缘之外, 则盒子必须进行视觉位移 (如同相对定位), 以使其位于粘性视图矩形边缘的内部, 只要其定位盒仍然包含在其 包含块内。 定位盒是其 外边距盒, 除非某一侧外边距盒的边缘与包含块相应边缘的距离小于其 外边距, 此时该距离将取代该侧的外边距。
注:具有非auto的 top 值且auto的 bottom 值的粘性定位元素只会因粘性定位而向下推动; 永远不会向上偏移。
注:同一容器中的多个粘性定位盒子独立偏移, 因此它们可能会重叠。
3.4.1. 粘性定位盒子的滚动位置
对于任何针对粘性定位元素(或其后代)滚动位置的操作, 必须将粘性定位元素视为在其偏移位置上。
3.5. 绝对(和固定)定位
对于绝对定位的盒子, 插入属性 实际上减少了其大小和位置的包含块的大小。 结果矩形称为插入修改的包含块。 (为了区别,实际的包含块可以称为绝对定位的包含块。)
3.5.1. 解析“内边距修饰的包含块”的内边距
如果给定轴上的插入属性中只有一个为 auto, 则其值设为零。 如果给定轴上的两个插入属性都为auto,那么根据盒子在相关轴上的 自对齐属性,进行如下处理:
- 对于self-start对齐或其等价方式
- 将起始边的插入属性设置为静态位置, 并将终止边的插入属性设为零。
- 对于self-end对齐或其等价方式
- 将终止边的插入属性 设置为静态位置, 并将起始边的插入属性设为零。
- 对于居中对齐
- 将起始距离定义为从其 静态位置矩形中心到其 包含块起始边的距离, 将终止距离定义为从 静态位置矩形中心到 包含块终止边的距离。 如果起始距离小于或等于终止距离, 则将起始边的插入属性设为零, 并将终止边的插入属性设为 (包含块大小 - 2 × |起始距离|); 否则, 将终止边的插入属性设为零, 并将起始边的插入属性设为 (包含块大小 - 2 × |终止距离|)。
对于上述规则, 忽略溢出对齐, 并将normal视为 start, 并将任何基线或 拉伸对齐值 视为其回退对齐。
如果这些调整导致任何轴上的有效包含块大小小于零, 则受影响轴上的较弱内边距将减少(可能变为负值), 以使该大小达到零。 如果只有一个内边距是 auto, 那么它就是较弱内边距 (其相对的内边距是较强内边距); 否则,较弱内边距是结束边缘的内边距 (其中结束是相对于包含块的书写模式来解释的)。
注意:将 绝对定位盒子 的大小和位置调整为此 插入修改的包含块, 如§ 4 绝对定位布局模型所述。
如果其自对齐属性在某轴上为 normal, 则该轴上 解析值为匹配其 插入修改的包含块 的相应边与其 外边距盒 相匹配的值,在 布局之后。 (否则,解析值为上面描述的 使用值。)
3.5.2. 计算静态位置和“静态位置矩形”
当给定轴上的两个内边距属性均为 auto 时, 它们通过将盒子对齐到其静态位置的静态位置矩形中来解析, 该对齐容器派生自 如果盒子是 position: static(与其际包含块无关),它本应参与的格式化上下文。 静态位置表示 如果盒子是 position: static,它本应具有的位置的近似值。
- 块布局
-
块级盒子的静态位置在 [CSS2] 第 10 章中定义。
静态位置矩形是一个零厚度矩形,
跨越其盒子的静态位置包含块的行内轴两侧,并位于其块起始静态位置处(参见 CSS2§10.6.4)。
注意:在块布局中,静态位置矩形对应于 CSS2.1§10.3.7 中描述的“假设盒子”的位置。 由于它没有对齐属性, CSS2.1 始终在静态位置矩形内对绝对定位的盒子使用块起始 行内起始对齐。
- 行内布局
- 行内级盒子的静态位置在 [CSS2] 第 10 章中定义。 静态位置矩形是一个零厚度矩形, 跨越本应包含其“假设盒子”的行盒的行上/行下两侧 (参见 CSS2§10.3.7); 并位于其行内起始静态位置处。
- 弹性布局
- 弹性容器子元素的静态位置矩形对应于弹性容器在交叉轴上的内容边缘, 以及其在主轴上假设位置的外边缘。 参见 [CSS-FLEXBOX-1] 中的弹性容器子元素的静态位置。
- 网格布局
- 默认情况下,网格容器子元素的静态位置矩形对应于网格容器的内容边缘。 但是,如果该网格容器也建立了盒子的实际包含块, 则由网格放置属性指定的网格区域将改为建立其静态位置矩形。 参见 [CSS-GRID-1] 中的网格容器子元素的静态位置。
查找静态位置和静态位置矩形假设 float 和 clear(以及 position) 都具有其初始值, 因此可能需要为display假设一个不同的假设值。 (在这些条件下元素本应具有的包含块是静态位置包含块。) 在盒对齐属性产生影响的程度上, 它们使用静态位置包含块作为有效的包含块, 包括使用其书写模式来解析对齐轴和方向。 此外,固定定位元素的包含块被假定为初始包含块,而不是视口, 并且所有滚动容器都应假定 已滚动到其初始滚动位置。 最后,盒子本身的所有 auto 外边距 均视为零。
3.5.3. 绝对定位元素的分段
在分段流中,绝对定位盒子相对于其包含块进行定位,忽略任何分段中断(就像流是连续的一样)。 该盒子随后可能会被分割成多个分段容器。
对于在分页媒体中 解析到非当前页面的绝对定位内容, 或者解析到当前页面上已经呈现过的部分, 打印设备可以将内容放置在:
- 当前页面,
- 后续页面,或
- 完全省略。
注意: 被分割在多个页面上的块级元素 在每个页面上可能具有不同的宽度,并且可能有设备特定的限制。
用户代理不得对固定定位盒子的内容进行分页处理。
注意: 用户代理可能以其他方式打印不可见的内容。 参见CSS Paged Media 3 § 3.2 页外内容。
4. 绝对定位布局模型
绝对定位不仅将一个盒子 脱离文档流, 还根据其包含块 (在确定包含块的最终尺寸之后)进行布局, 依照绝对定位布局模型:
- 首先,计算其插入修改后的包含块, 定义其可用空间。 (参见 § 3.5 绝对(和固定)定位。)
- 其次,其宽度和高度相对于该确定的 可用空间进行解析, 作为其首选尺寸,并受其 最大尺寸(如有)和 最小尺寸的限制。 参见§ 4.1 绝对定位盒子的自动尺寸。 但是,百分比是相对于原始的 包含块尺寸进行解析的。
- 接下来,计算任何auto外边距, 参见§ 4.2 绝对定位盒子的自动外边距。
- 最后,其外边距盒在内边距修饰的包含块内对齐, 参见§ 5 绝对定位盒子的自对齐。
4.1. 绝对定位盒子的自动尺寸
- 如果其相关轴上的自对齐属性为 stretch,并且该轴上的内边距属性和外边距都不是 auto
- 或者如果它是 normal 并且盒子是非替换的,不是表格包装盒,并且在相关轴上没有 auto 内边距
- 否则
但是,如果盒子具有宽高比,那么宽高比相关轴上的自动尺寸将改为解析为最大内容尺寸。 当两个轴都具有自动尺寸时,如果只有一个轴具有 auto 内边距,则该轴是宽高比相关轴,否则块轴是宽高比相关轴。 宽高比决定轴上的自动尺寸按上述方式确定。
为了计算这些尺寸,任何 auto 外边距都视为零。
绝对定位盒子的自动最小尺寸始终为零。
注意:在表单控件可以调整大小(并且不直接表示替换元素,例如图像)的程度上,它们在此处应被视为非替换的。
在 HTML 中,除 <input type=image>
之外的所有表单控件都被视为非替换的。
4.2. 绝对定位盒子的自动外边距
如果相关轴上的任一内边距属性为 auto, 则任何 auto 外边距都解析为零。
否则,剩余空间的计算方法是:其相关轴上内边距修饰的包含块的大小减去盒子在相关轴上的已用大小, 然后将此剩余空间分配给相关轴上的任何 auto 外边距。 但是, (所有这些都相对于包含块的书写模式而言), 如果在行内轴上剩余空间为负且两个外边距均为 auto, 则起始外边距解析为零, 而结束外边距接收剩余空间。
注意:与典型的流内布局不同, 在绝对定位中,分配给 auto 外边距的空间可以为负。
在“负尺寸”包含块中应该发生什么? CSS2.1 和此草案目前存在冲突。 [问题 #11478]
5. 绝对定位盒子的自对齐
如果一个轴上任一内边距属性的计算值为 auto, 则其外边距盒将与其较强内边距对应的内边距修饰的包含块的边缘对齐(即使这会溢出其包含块)。
否则,如果任一外边距为 auto, 则其位置根据§ 4.2 绝对定位盒子的自动外边距进行解析。
否则,盒子将根据其相关轴上的自对齐属性(由包含块的书写模式定义)进行对齐, 使用其外边距盒作为对齐主体,并使用内边距修饰的包含块作为对齐容器。 但是,如果未指定显式的溢出对齐, 并且其外边距盒溢出内边距修饰的包含块, 则其对齐方式将调整为最小化溢出, 如CSS 框对齐 3 § 4.4.1.2 绝对定位盒子的自对齐中所述。
6. 旧的绝对定位布局模型
此部分正在被新的§ 4 绝对定位布局模型部分取代。 此处保留它是为了进行比较: 当盒子的自对齐为 normal 时,两种模型在水平书写模式下应产生相同的结果。
6.1. 绝对定位的非替换元素的宽度
确定这些元素使用值的约束是:
left + margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right + right = width of containing block
如果 left、width 和 right 均为 auto: 首先将 margin-left 和 margin-right 的任何 auto 值设置为 0。 然后,如果建立静态位置包含块的元素的 direction 属性为 ltr,则将 left 设置为静态位置并应用下面的规则三; 否则,将 right 设置为静态位置并应用下面的规则一。
如果三者均不为 auto: 如果 margin-left 和 margin-right 均为 auto, 则在两个外边距获得相等值的额外约束下求解方程, 除非这会使它们为负, 在这种情况下,当包含块的方向为 ltr (rtl) 时, 将 margin-left (margin-right) 设置为 0 并求解 margin-right (margin-left)。 如果 margin-left 或 margin-right 中的一个为 auto, 则求解该值的方程。 如果值被过度约束, 则忽略 left 的值(如果包含块的 direction 属性为 rtl) 或 right 的值(如果 direction 为 ltr)并求解该值。
否则, 将 margin-left 和 margin-right 的 auto 值设置为 0, 并选择以下六个适用规则中的一个。
- 如果 left 和 width 为 auto 且 right 不为 auto, 则宽度为收缩以适应。 然后求解 left。
- 如果 left 和 right 为 auto 且 width 不为 auto, 那么如果建立静态位置包含块的元素的 direction 属性为 ltr,则将 left 设置为静态位置, 否则将 right 设置为静态位置。 然后求解 left(如果 direction 为 rtl) 或 right(如果 direction 为 ltr)。
- 如果 width 和 right 为 auto 且 left 不为 auto, 则宽度为收缩以适应。 然后求解 right。
- 如果 left 为 auto,width 和 right 不为 auto, 则求解 left。
- 如果 width 为 auto,left 和 right 不为 auto, 则求解 width。
- 如果 right 为 auto,left 和 width 不为 auto, 则求解 right。
是否为 auto? | 结果 | ||||
---|---|---|---|---|---|
left | width | right | margin-left | margin-right | |
✔ | ✔ | ✔ | 任何 |
|
|
✘ | ✘ | ✘ | ✔ | ✘ | auto 外边距 → 自由空间 |
✘ | ✔ | ||||
✔ | ✔ |
|
|||
✘ | ✘ | 将 right 视为 auto | |||
✔ | ✘ | ✔ | 任何 |
|
|
✔ | ✔ | ✘ | 任何 |
|
|
✘ | ✔ | ✔ | 任何 |
|
|
✔ | ✘ | ✘ | 任何 |
|
|
✘ | ✘ | ✔ | |||
✘ | ✔ | ✘ |
6.2. 绝对或固定定位的替换元素的宽度
如果 height 和 width 都具有 auto 的计算值,并且元素具有内在宽度, 那么该内在宽度就是 width 的使用值。
如果 height 和 width 都具有 auto 的计算值,且元素没有内在宽度, 但具有内在高度和内在比例; 或者如果 width 的计算值为 auto,height 具有其他计算值, 并且元素具有内在比例; 那么 width 的使用值为:
(使用高度) * (内在比例)
如果 height 和 width 的计算值都为 auto,元素具有固有比例但没有固有高度或宽度,并且包含块的宽度本身不依赖于替换元素的宽度,那么 width 的使用值将根据用于块级、非替换元素在常规流中的约束方程计算。
否则,如果 width 的 计算值为 auto, 并且该元素具有内在宽度, 那么该内在宽度就是 width 的使用值。
否则,如果 width 的 计算值为 auto, 但不符合上述条件, 那么 width 的使用值将变为 300px。 如果 300px 对设备来说太宽, 用户代理应使用最大矩形的宽度, 该矩形具有 2:1 的比例并适合设备。
确定了 width 之后, 为了定位替换元素, 根据需要应用以下规则。
- 如果 left 和 right 的值都为 auto, 并且如果建立静态位置包含块的元素的 direction 属性为 ltr, 则将 left 设置为静态位置并求解 right; 否则如果 direction 为 rtl, 则将 right 设置为静态位置并求解 left。
- 如果 left 为 auto 且 right 不为 auto, 则将 margin-left 或 margin-right 上的任何 auto 替换为 0, 然后求解 left。
- 如果 right 为 auto 且 left 不为 auto, 则将 margin-left 或 margin-right 上的任何 auto 替换为 0, 然后求解 right。
- 如果此时 margin-left 和 margin-right 仍然为 auto, 则在两个外边距必须获得相等值的额外约束下求解方程, 除非这会使它们为负, 在这种情况下,当包含块的方向为 ltr (rtl) 时, 将 margin-left (margin-right) 设置为 0 并求解 margin-right (margin-left)。
- 如果此时仍有 auto 剩余, 则求解该值的方程。
- 如果此时值被过度约束, 则忽略 left 的值(如果包含块的 direction 属性为 rtl) 或 right 的值(如果 direction 为 ltr) 并求解该值。
6.3. 绝对定位的非替换元素的高度
对于绝对定位的元素, 垂直维度的使用值必须满足以下约束:
top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = 包含块的高度
如果 top、height 和 bottom 均为 auto: 首先将 margin-top 和 margin-bottom 的任何 auto 值设置为 0, 然后将 top 设置为静态位置, 最后应用下面的规则三。
如果三者均不为 auto: 如果 margin-top 和 margin-bottom 均为 auto, 则在两个外边距获得相等值的额外约束下求解方程。 如果 margin-top 或 margin-bottom 中的一个为 auto, 则求解该值的方程。 如果值被过度约束, 则忽略 bottom 的值并求解该值。
否则, 将 margin-top 和 margin-bottom 的 auto 值设置为 0, 并选择以下六个适用规则中的一个。
-
如果 top 和 height 为 auto 且 bottom 不为 auto, 则高度基于块格式化上下文根的自动高度, 并求解 top。
-
如果 top 和 bottom 为 auto 且 height 不为 auto, 则将 top 设置为静态位置, 然后求解 bottom。
-
如果 height 和 bottom 为 auto 且 top 不为 auto, 则高度基于块格式化上下文根的自动高度, 并求解 bottom。
6.4. 绝对定位的替换元素的高度
如果 height 和 width 的计算值都为 auto 并且元素也具有固有高度, 则该固有高度即为 height 的使用值。
否则,如果 height 的计算值为 auto 并且元素具有固有比例, 则 height 的使用值为:
(使用宽度)/(固有比例)
否则,如果 height 的计算值为 auto 并且元素具有固有高度, 则该固有高度即为 height 的使用值。
否则,如果 height 的计算值为 auto, 但以上条件均不满足, 则 height 的使用值必须设置为 具有 2:1 比例、高度不大于 150px 且宽度不大于设备宽度的最大矩形的高度。
在确定 height 后, 为了定位替换元素, 请酌情应用以下规则。
-
如果 bottom 为 auto, 则将 margin-top 或 margin-bottom 上的任何 auto 替换为 0。
-
如果此时 margin-top 和 margin-bottom 仍然为 auto, 则在两个外边距必须获得相等值的额外约束下求解方程。
-
如果此时只剩下一个 auto, 则求解该值的方程。
-
如果此时值被过度约束, 则忽略 bottom 的值并求解该值。
7. 正常流、浮动和定位的比较
本节不具有规范性。
为了说明常规流、相对定位、浮动和绝对定位之间的差异,我们提供了一系列基于以下 HTML 的示例:
<!DOCTYPE html> < html > < head > < title > 定位方案的比较</ title > < style > body { display : block ; font-size : 12 px ; line-height : 200 % ; width : 400 px ; height : 400 px } p { display : block } span { display : inline } </ style > </ head > < body > < p > p元素内容开始。< span id = "outer" > 外层内容开始。< span id = "inner" > 内层内容。</ span > 外层内容结束。</ span > p元素内容结束。</ p > </ body > </ html >
每个示例中生成的 outer 和 inner 元素的最终位置各不相同。在每个图示中, 图示左侧的数字表示双倍行距的正常流 位置,以便于说明。
注意:本节的图表仅为示例,并不按比例绘制。它们的目的是突出不同定位方案之间的差异,而不是作为给定示例的参考渲染。
7.1. 正常流示例
考虑以下用于 outer 和 inner 的 CSS 声明,它们不会改变盒子的正常流:
P 元素包含所有行内内容:匿名行内文本和两个 SPAN 元素。因此,所有内容都将在行内格式化上下文中布局,在由 P 元素建立的包含块内,产生类似如下的效果:

7.2. 相对定位示例
为了查看相对定位的效果,我们指定了以下样式:
#outer{ position : relative; top : -12 px ; color : red} #inner{ position : relative; top : 12 px ; color : blue}
文本正常流动到 outer 元素。outer 文本首先按照其正常流的位置和尺寸在第 1 行的末尾呈现。然后,包含文本的内联框(分布在三行上)作为一个整体被向上移动 -12px。
作为 outer 的子元素,inner 的内容通常会紧随“outer 内容”之后(在 1.5 行)。然而,inner 的内容相对于 outer 内容向下偏移了 12px,返回到原始的第 2 行位置。
注意,outer 之后的内容不受 outer 相对定位的影响。

还要注意,如果 outer 的偏移值为 -24px,则 outer 文本和正文文本将会重叠。
7.3. 浮动示例
现在考虑通过以下规则将 inner 元素的文本向右浮动的效果:
文本正常流动到 inner 框,该框被移出流并浮动到右外边距(其 width 已被显式分配)。浮动框左侧的行框被缩短,文档的其余文本流入其中。

为了显示 clear 属性的效果,我们向示例中添加一个同级元素:
<!DOCTYPE html> < html > < head > < title > 定位方案比较 II</ title > < style > #inner{ float : right; width : 130 px ; color : blue} #sibling{ clear : right; color : red}
这些样式使得 inner 框向右浮动,与之前一样,文档其余的文本流入空出的空间:

但是,如果同级元素上的 clear 属性设置为 right(即,生成的同级框将不接受其右侧浮动框旁边的位置),则同级内容将开始在浮动框下方流动:

7.4. 绝对定位示例
接下来,我们考虑绝对定位的效果。以下是为 outer 和 inner 设置的 CSS 声明:
#outer{ position : absolute; top : 200 px ; left : 200 px ; width : 200 px ; color : red; } #inner{ color : blue}
这导致 outer 框的顶部相对于其包含块进行定位。定位框的包含块由最近的已定位祖先(或者,如果不存在,则为初始包含块,如我们的示例所示)建立。outer 框的顶边位于包含块顶部下方 200px 处,左边距离左边 200px。outer 的子框相对于其父框正常流动。

下面的示例展示了作为相对定位框子元素的绝对定位框的效果。虽然父 outer 框实际上没有偏移,但将其 position 属性设置为 relative 意味着它可以作为已定位后代元素的包含块。由于 outer 框是一个跨越多行的内联框,第一个内联框的顶部和左侧边缘(如下图中的粗虚线)作为 top 和 left 偏移的参考点。
#outer{ position : relative; color : red} #inner{ position : absolute; top : 200 px ; left : -100 px ; height : 130 px ; width : 130 px ; color : blue; }
其结果如下图所示:

如果我们不对 outer 框进行定位:
#outer{ color : red} #inner{ position : absolute; top : 200 px ; left : -100 px ; height : 130 px ; width : 130 px ; color : blue; }
inner 的包含块将变为初始包含块(在我们的示例中)。下图显示了在这种情况下 inner 框最终的位置。

相对和绝对定位可以用来实现修改条的效果,如下例所示。以下片段:
< p style = "position: relative; margin-right: 10px; left: 10px;" > 我用了两个红色破折号来作为修改条。它们将“浮动”到包含THIS一词的行的左侧< span style = "position: absolute; top: auto; left: -1em; color: red;" > --</ span > 一词旁边。</ p >
可能产生如下效果:

首先,段落(其包含块的各边如图所示)正常流动。然后它从包含块的左边缘偏移 10px(因此,为预期的偏移保留了 10px 的右外边距)。充当变更标记的两个连字符被移出流,并定位在当前行(由于 'top: auto'),距离其包含块(由 P 在其最终位置建立)左边缘 -1em 的位置。结果是变更标记似乎“浮动”到当前行的左侧。
8. 致谢
本模块的实现离不开许多人的帮助和支持。特别感谢 Rossen Atanassov、Bert Bos、Oriol Brufau、Tantek Çelik、Arron Eicholz、Sylvain Galineau、John Jansen、Chris Jones、Ian Kilpatrick 和 Anton Prowse。
变更
自2024年8月10日工作草案以来,进行了以下重大更改:
- 无。仅编辑更新(截至2025年3月10日)。
自 2023年4月3日工作草案以来的重大变更如下:
- 调整了绝对定位盒子的对齐方式,默认情况下将其约束到其包含块。 请参阅 § 4 绝对定位布局模型。 (问题 10316)
- 指定了顶层盒子的静态位置矩形为初始包含块。 (问题 9939)
- 阐明了在连续媒体中,固定定位包含块(明确地)对应于布局视口。 (问题 6453)
自 2023年2月17日工作草案以来的重大变更如下:
- 更新了由跨越多行的分段行内框形成的包含块,以在每个轴上使用所有分段的最末端边缘;然而,此提议的定义仍在讨论中。 (问题 8284)
自2022年9月1日工作草案以来,进行了以下重大更改:
- 添加了 § 2.2 绘制顺序和堆叠上下文,并定义了粘性定位框始终形成堆叠上下文。 (问题 1053)
- 更新了粘性定位,以将其偏移定位用于滚动操作。 (问题 7930)
- 修复了 CSS2 中关于在存在 bidi 的情况下形成包含块的分段行内框边缘的不正确/模糊翻译。 (问题 7917)
- 定义了由分段行内框边缘形成的包含块以匹配 Blink 实现 (问题 609) 同时就最佳做法展开讨论 (问题 8284)
- 从 CSS2 导入了静态位置包含块的定义。
- 阐明了用于计算静态位置的书写模式。 (问题 7599, 问题 7612)
- 添加了一条注释,说明为了绝对定位的目的,将 HTML 表单控件视为非替换元素。 (问题 6789)
- 纠正了 position 的重复、冲突的“动画类型”行。 (问题 6846)
- 阐明了“等效对齐”。 (问题 6607)
自2021年12月16日工作草案以来,进行了以下重大更改:
自2020年5月19日工作草案以来,进行了以下重大更改:
-
定义了具有宽高比的非替换绝对定位盒子的自动尺寸调整。
(问题 5151
但是,如果盒子具有宽高比,则宽高比相关轴中的自动尺寸将改为解析为最大内容尺寸。 当两个轴都具有自动尺寸时,如果只有一个轴具有 auto 内边距,则该轴是宽高比相关轴,否则块轴是宽高比相关轴。宽高比决定轴中的自动尺寸按上述方式确定。
-
将定位框的自动外边距和自动尺寸的解析与 [CSS2] 对齐。
(问题 5374, 问题 5077, 问题 5327)
如果这导致任何轴上的粘性视图矩形尺寸小于该轴上粘性框的边框盒尺寸, 则受影响轴上的有效结束边缘内边距将减小 (可能变为负值) 以使粘性视图矩形的尺寸达到该轴上边框盒的尺寸 (其中结束是相对于包含块的书写模式来解释的) 。
如果两者都不是 auto, 则位置被过度约束; (相对于其包含块的书写模式) 结束边的计算值将被忽略, 其使用值将成为开始边的负值。
但是, (所有这些都相对于包含块的书写模式而言), 如果在行内轴上 剩余空间为负 且两个外边距均为 auto, 则起始外边距解析为零 而结束外边距接收剩余空间。
自 2016年5月17日工作草案以来的重大变更如下:
- 为编辑清晰度、技术精确性以及与 [CSS-ALIGN-3],[CSS-WRITING-MODES-3],[CSS-BREAK-3] 和 [CSS-DISPLAY-3] 的兼容性重写了整个规范。
隐私考量
本规范未引入新的隐私考量。
安全考量
如果攻击者能够注入任意CSS,定位布局可能会使攻击者更容易将其控制的元素定位于页面的其他任意元素上,从而可能欺骗页面的用户。 (有很多种实现这种攻击的方法:例如负 外边距,变换,等等。不要让人们对你页面的部分应用任意CSS。)
position: fixed 可以允许页面模拟模式对话框,从而可能欺骗用户以为他们在与用户代理进行交互,并输入敏感信息,而页面可以捕获这些信息。用户代理必须确保其原生对话框以页面无法模拟的方式定位,特别是确保至少有一部分对话框位于网页内容可以绘制的"有毒像素"之外。