1. 引言
本节非规范性内容。
CSS 2.1 定义了四种布局模式——这些算法根据元素与其兄弟和祖先盒子的关系确定盒子的大小和位置:
-
块布局,设计用于文档布局
-
内联布局,设计用于文本布局
-
表格布局,设计用于以表格形式布局二维数据
-
定位布局,设计用于非常精确的定位,不太考虑文档中其他元素
本模块引入了一种新的布局模式,弹性布局,其设计用于布局更复杂的应用程序和网页。
1.1. 概述
本节非规范性内容。
弹性布局在表面上类似于块布局。 它缺少许多可以在块布局中使用的与文本或文档相关的复杂属性,例如浮动和列。 作为交换,它获得了简单而强大的工具, 用于分配空间和对齐内容, 这是Web应用程序和复杂网页通常需要的。 弹性容器的内容:
-
该目录使用弹性布局来水平排列项目的行, 并确保行内的项目具有相同的高度。 每个条目本身也是一个列式弹性容器, 垂直排列其内容。
-
在每个条目中,源文档内容的顺序是按逻辑排列的, 首先是标题,其次是描述和照片。 这为语音渲染和非CSS浏览器提供了合理的顺序。 然而,为了提供更引人注目的视觉呈现,使用了order 将图片从内容后面的逻辑顺序拉到顶部, 并使用align-self 将其水平居中。
-
auto 边距在购买按钮上方自动添加, 使其在每个条目框中推到底部, 无论该项目描述的高度如何。
#deals { display : flex; /* 弹性布局,确保项目具有相同高度 */ flex-flow : row wrap; /* 允许项目换行排列成多行 */ } .sale-item { display : flex; /* 使用弹性布局排列每个项目 */ flex-flow : column; /* 垂直排列项目内容 */ } .sale-item > img { order : -1 ; /* 在视觉顺序上将图片移到其他内容之前 */ align-self : center; /* 水平居中图片 */ } .sale-item > button { margin-top : auto; /* 自动上边距将按钮推到框底部 */ }
< section id = "deals" > < section class = "sale-item" > < h1 > 电脑初学者套装</ h1 > < p > 这是你能买到的最好的电脑,适合预算有限的人。</ p > < ul > < li > 电脑< li > 显示器< li > 键盘< li > 鼠标</ ul > < img src = "images/computer.jpg" alt = "你将获得:一台配有匹配外设的白色电脑。" > < button > 立即购买</ button > </ section > < section class = "sale-item" > …</ section > …</ section >

电脑初学者套装
这是你能买到的最好的电脑, 适合预算有限的人。
- 电脑
- 显示器
- 键盘
- 鼠标

打印机
只能打印ASCII艺术。
- 不含纸和墨水。
1.2. 模块交互
本模块扩展了display 属性的定义[CSS21], 添加了新的块级和内联级显示类型, 并定义了一种新的格式化上下文类型, 以及用于控制其布局的属性。 本模块定义的任何属性均不适用于::first-line或::first-letter伪元素。
CSS盒子对齐模块扩展并取代了 此处引入的对齐属性的定义 (justify-content、align-items、align-self、align-content)。
2. 弹性布局盒模型与术语
弹性容器是由具有 计算后的display 属性为flex 或inline-flex的元素生成的盒子。 弹性容器中的流内子元素称为弹性项目,它们使用弹性布局模型进行布局。
与偏向于块和内联流方向的块布局和内联布局不同, 弹性布局偏向于弹性方向。 为了更容易讨论弹性布局, 本节定义了一组与弹性流动相关的术语。 flex-flow值和 书写模式确定了这些术语如何映射到 物理方向(上/右/下/左)、轴线(垂直/水平)和尺寸(宽度/高度)。
- 主轴
- 主维度
- 弹性容器的主轴是沿着弹性项目布局的主要轴线。 它在主维度上延伸。
- 主开始
- 主结束
- 弹性项目放置在容器内, 从主开始侧开始, 并朝向主结束侧延伸。
- 主尺寸
- 主尺寸属性
- 弹性容器或 弹性项目的宽度或高度, 无论哪个位于主维度, 都是该盒子的主尺寸。 其主尺寸属性 是其宽度或 高度属性, 无论哪个位于主维度。 类似地,其最小主尺寸属性和 最大主尺寸属性是其 最小宽度/ 最大宽度或 最小高度/ 最大高度属性, 无论哪个位于主维度, 并确定其最小/ 最大主尺寸。
- 交叉轴
- 交叉维度
- 与主轴垂直的轴线称为交叉轴。 它在交叉维度上延伸。
- 交叉开始
- 交叉结束
- 弹性行填充项目并放置在容器中, 从弹性容器的交叉开始侧开始, 并朝向交叉结束侧延伸。
- 交叉尺寸
- 交叉尺寸属性
- 弹性容器或 弹性项目的宽度或高度, 无论哪个位于交叉维度, 都是该盒子的交叉尺寸。 其交叉尺寸属性 是其宽度或 高度属性, 无论哪个位于交叉维度。 类似地,其最小交叉尺寸属性和 最大 交叉尺寸属性是其最小宽度/ 最大宽度或 最小高度/ 最大高度属性, 无论哪个位于交叉维度, 并确定其最小/ 最大交叉尺寸。
本规范中使用的其他尺寸术语在CSS 内在和外在尺寸中定义。 [CSS-SIZING-3]
3. 弹性容器:flex 和 inline-flex display 值
名称: | display |
---|---|
新值: | flex | inline-flex |
- flex
- 该值使元素生成一个弹性容器盒, 当它位于流布局中时,是块级盒。
- inline-flex
- 该值使元素生成一个弹性容器盒, 当它位于流布局中时,是内联级盒。
弹性容器为其内容建立一个新的 弹性格式化上下文。 这与建立块格式化上下文相同, 只是使用弹性布局代替了块布局。 例如,浮动不会侵入弹性容器, 并且弹性容器的边距不会与其内容的边距合并。弹性容器为其内容形成一个包含块, 与块容器一样。[CSS21] overflow属性适用于弹性容器。
弹性容器不是块容器, 因此某些假设块布局的属性在弹性布局的上下文中不适用。 特别是:
-
vertical-align对弹性项目无效。
-
::first-line和 ::first-letter伪元素不适用于弹性容器, 弹性容器不会为其祖先贡献第一格式化行或 第一个字母。
如果元素的指定display值为 inline-flex, 那么在某些情况下,它的display属性会计算为 flex: CSS 2.1 第9.7节中的表格 将添加一行, 其中“指定值”列中为inline-flex, “计算值”列中为flex。
4. 弹性项目
大致而言,弹性项目是弹性容器的盒子, 它们代表了其文档流中的内容。
每个弹性容器的文档流子元素都变成弹性项目, 并且每个连续的子文本运行被包裹在一个 匿名 块容器 弹性项目中。 但是,如果整个子文本运行序列只包含 空白(即 可以受white-space属性影响的字符), 则该序列不会被渲染(就像其文本节点的display:none一样)。
弹性项目示例:
< div style = "display:flex" > <!-- 弹性项目:块子元素 --> < div id = "item1" > block</ div > <!-- 弹性项目:浮动元素;浮动被忽略 --> < div id = "item2" style = "float: left;" > float</ div > <!-- 弹性项目:围绕内联内容的匿名块框 --> 匿名项目3<!-- 弹性项目:内联子元素 --> < span > 项目4<!-- 弹性项目不会 围绕块 拆分 --> < q style = "display: block" id = not-an-item > 项目4</ q > 项目4</ span > </ div >
请注意,元素之间的空白消失了: 它不会成为自己的弹性项目, 尽管元素间的文本确实会被包裹在匿名弹性项目中。
还要注意,匿名项目的框是不可样式化的, 因为没有元素可以为其分配样式规则。 但其内容会继承弹性容器的样式(如字体设置)。
弹性项目为其内容建立了独立的格式化上下文。 然而,弹性项目本身是弹性级盒,而不是块级盒: 它们参与的是容器的弹性格式化上下文, 而不是块格式化上下文。
注意: 阅读本规范的作者可能希望跳过以下框生成和静态位置的详细信息。
display值为 弹性项目的元素是块化的: 如果生成弹性容器的元素的文档流子元素的指定display值是内联级值, 则其会计算为块级等效值。 (有关这种display值转换的详细信息,请参见 CSS2.1第9.7节 [CSS21] 和CSS Display [CSS3-DISPLAY])。
注意:某些display值通常会在原始盒子周围触发匿名盒的创建。 如果这样的盒子是弹性项目, 它首先会被块化, 因此不会发生匿名盒的创建。 例如,两个连续的弹性项目,其display:table-cell会变成两个单独的 display: block 弹性项目, 而不是被包裹成一个匿名表。
对于display:table的弹性项目, 表包装盒成为弹性项目, order和 align-self属性适用于它。 任何标题盒的内容都会影响表包装盒的最小内容和最大内容大小的计算。 然而,类似于width和 height,flex长手写适用于表盒如下: 通过执行布局计算出弹性项目的最终大小, 就像表包装盒的边缘与表盒的内容边缘之间的距离都属于表盒的边框+内边距区域一样, 并且表盒是弹性项目。
4.1. 绝对定位的弹性子元素
由于它是脱离文档流的,弹性容器的绝对定位子元素不会参与弹性布局。
绝对定位子元素的静态位置由以下方式决定: 该子元素被视为是弹性项目的唯一成员, 并且假设子元素和弹性容器 都是固定尺寸的盒子,其大小为使用过的尺寸。 为此目的,auto的外边距被视为零。
(在块布局中,静态位置矩形对应于CSS2.1§10.3.7中描述的“假想盒子”的位置。 由于没有对齐属性,CSS2.1总是使用绝对定位盒在 块起始和 行内起始 的对齐方式。 请注意,这一定义最终将被移至CSS定位模块。)
然而,由于绝对定位盒被视为“固定大小”, 因此stretch的值将被视为与flex-start相同。
4.2. 弹性项目的边距和内边距
与块盒子上的百分比边距和内边距类似, 弹性项目的百分比边距和内边距 是相对于其包含块的 内联尺寸来解析的, 例如,左/右/上/下的百分比都根据其包含块 的宽度在水平书写模式中解析。
自动边距会扩展以吸收相应维度上的额外空间。 它们可用于对齐, 或者将相邻的弹性项目推开。 请参见使用auto边距对齐。
4.3. 弹性项目的Z轴排序
弹性项目的绘制方式与内联块类似 [CSS21], 只是使用了经过order修改的文档顺序来代替原始文档顺序, 并且z-index 除了auto以外的值都会创建一个堆叠上下文, 即使position的值是 static (表现得完全像position是 relative一样)。
注意: 定位在弹性项目之外的后代元素仍然会参与由弹性项目建立的任何堆叠上下文。
4.4. 折叠的项目
在弹性项目上指定 visibility:collapse 会导致其成为 折叠的弹性项目, 产生类似于 visibility:collapse 在表行或表列上的效果: 折叠的弹性项目将完全从渲染中移除, 但留下一个“支撑”,保持弹性行的交叉尺寸稳定。 因此,如果弹性容器只有一条弹性行, 动态折叠或展开项目可能会改变弹性容器 的主尺寸, 但保证不会影响其交叉尺寸,也不会导致页面其余布局“晃动”。 不过,折叠后会重新执行弹性行换行,因此具有多行的弹性容器的交叉尺寸可能会改变。
尽管折叠的弹性项目不会被渲染, 但它们确实会出现在格式化结构中。 因此,与display:none的项目不同 [CSS21], 依赖于框出现的效果(例如计数器递增或运行动画和过渡)仍然会对折叠的项目起作用。
@media ( min-width: 60em) { /* 两列布局仅在足够宽时使用 (相对于默认文本大小) */ div { display: flex; } #main { flex: 1; /* 主区域占据所有剩余空间 */ order: 1; /* 将其放在导航之后(右侧) */ min-width: 12em; /* 优化主内容区域的尺寸 */ } } /* 菜单项使用弹性布局,以便visibility:collapse生效 */ nav > ul > li { display: flex; flex-flow: column; } /* 动态折叠菜单项,如果未被选中或悬停 */ nav > ul > li:not(:target):not(:hover) > ul { visibility: collapse; }
< div > < article id = "main" > 有趣的阅读内容</ article > < nav > < ul > < li id = "nav-about" >< a href = "#nav-about" > About</ a > …< li id = "nav-projects" >< a href = "#nav-projects" > Projects</ a > < ul > < li >< a href = "…" > Art</ a > < li >< a href = "…" > Architecture</ a > < li >< a href = "…" > Music</ a > </ ul > < li id = "nav-interact" >< a href = "#nav-interact" > Interact</ a > …</ ul > </ nav > </ div > < footer > …
要计算支撑的大小,首先使用未折叠的项目执行弹性布局, 然后重新运行,将每个折叠的项目替换为支撑,以保持项目原始行的交叉尺寸。 参见弹性布局算法以获取 visibility:collapse 与弹性布局交互的规范定义。
注意: 在任何弹性项目上使用 visibility:collapse 将导致弹性布局算法在部分过程中重复,重新运行最昂贵的步骤。 如果项目不会被动态折叠和展开,建议作者继续使用 display:none 来隐藏项目, 因为这对于布局引擎来说更高效。 (然而,由于 visibility 改变时只需重复部分步骤, 因此在动态情况下仍建议使用 'visibility: collapse')。
4.5. 弹性项目的自动最小尺寸
注意: auto 关键字,代表一个 自动最小尺寸, 是 min-width 和 min-height 属性的新初始值。 该关键字以前在本规范中定义,但现在在 CSS 尺寸 模块中定义。
为了为 弹性项目 提供更合理的默认 最小尺寸, 非 滚动容器 上的 主轴 自动最小尺寸 的使用值是一个基于内容的最小尺寸; 对于 滚动容器,自动最小尺寸 通常为零。
通常,基于内容的最小尺寸 是 弹性项目 的 内容尺寸建议 和 指定尺寸建议 中较小的值。 但是,如果该框具有纵横比且没有 指定尺寸, 则其 基于内容的最小尺寸 是其 内容尺寸建议 和其 转移尺寸建议 中较小的值。 如果该框既没有 指定尺寸建议 也没有纵横比, 则其 基于内容的最小尺寸 为 内容尺寸建议。
内容尺寸建议,指定尺寸建议 和 转移尺寸建议 会根据相关的最小/最大/首选尺寸属性计算, 以防止 基于内容的最小尺寸 干扰任何作者提供的约束, 并且它们定义如下:
- 指定尺寸建议
- 如果项目的计算主尺寸属性是确定的, 那么 指定尺寸建议 就是该尺寸 (如果它是 确定的,则由其 最大主尺寸属性 限制)。 否则,它是未定义的。
- 转移尺寸建议
- 如果项目具有内在纵横比, 并且其计算的 交叉尺寸属性 是 确定的, 则 转移尺寸建议 就是该尺寸 (如果它们是 确定的,则由其 最小和最大交叉尺寸属性 限制), 通过纵横比转换。 否则,它是未定义的。
- 内容尺寸建议
- 内容尺寸建议 是 最小内容尺寸 在 主轴上, 如果它具有纵横比,则由任何 确定的 最小和最大交叉尺寸属性 限制, 然后再由 最大主尺寸属性 限制,如果该属性是 确定的。
为了计算框的内在尺寸 (例如框的 最小内容尺寸), 基于内容的最小尺寸 使该轴上的框的尺寸变得不确定 (即使其 宽度 属性指定了 确定的 尺寸)。 请注意,这意味着根据此尺寸计算的百分比将 表现为自动。
尽管如此,尽管这可能需要在某些情况下进行额外的布局传递以重新解析百分比, 但该值 (如 最小内容,最大内容 和 适合内容 值 在 [CSS-SIZING-3] 中定义) 并不会阻止项目内百分比尺寸的解析。
特别是,如果弹性尺寸用于文档的主要内容区域, 最好设置一个明确的字体相关最小宽度,例如 min-width: 12em。 基于内容的最小宽度可能会导致大表格或大图像 将整个内容区域的尺寸拉伸到溢出区域, 从而使文本行过长且难以阅读。
另外,使用基于内容的尺寸时,如果项目内容较多, 布局引擎必须遍历所有这些内容才能找到其最小尺寸, 而如果作者设置了明确的最小值,则不需要这样做。 (然而,对于内容较少的项目, 这种遍历是微不足道的,因此不是性能问题。)
5. 排序和方向
弹性容器的内容可以按任何方向和顺序排列。 这使得作者可以轻松实现以前需要复杂或不稳定方法的效果, 例如使用 浮动 和 清除 属性的技巧。 该功能通过 flex-direction、flex-wrap 和 order 属性暴露出来。
注意: 弹性布局的重排序功能有意只影响 视觉渲染, 并保持基于源代码顺序的语音顺序和导航顺序。 这使得作者可以在保留源代码顺序的同时操纵视觉呈现,以便为非 CSS 的用户代理以及语音和顺序导航等线性模型提供支持。 请参见 重排序和可访问性 以及 弹性布局概述, 其中的例子使用了这种二分法来改善可访问性。
作者 不得 使用 order 或 *-reverse 值作为 flex-flow/flex-direction 的替代来进行正确的源代码排序, 因为这可能会破坏文档的可访问性。
5.1. 弹性流方向:flex-direction 属性
名称: | flex-direction |
---|---|
值: | row | row-reverse | column | column-reverse |
初始值: | row |
适用于: | 弹性容器 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 指定的关键字 |
规范顺序: | 按语法 |
动画类型: | 离散 |
flex-direction 属性指定 弹性项目 在弹性容器中的放置方式, 通过设置弹性容器的 主轴 方向。 这决定了弹性项目的排列方向。
- row
- 弹性容器的 主轴 与当前 内联轴 的方向相同 在当前的 书写模式 中。 主起始 和 主结束 方向分别等同于 当前书写模式中的 内联起始 和 内联结束 方向。
- row-reverse
- 与 row 相同, 只是 主起始 和 主结束 方向是反转的。
- column
- 弹性容器的 主轴 与当前书写模式中的 块轴 方向相同。 主起始 和 主结束 方向分别等同于 当前 块起始 和 块结束 方向。
- column-reverse
- 与 column 相同, 只是 主起始 和 主结束 方向是反转的。
注意: 反向值不会反转框顺序: 像 writing-mode 和 direction [CSS3-WRITING-MODES], 它们只改变流动方向。 绘制顺序、语音顺序和顺序导航顺序不受影响。
5.2. 弹性行换行:flex-wrap 属性
名称: | flex-wrap |
---|---|
值: | nowrap | wrap | wrap-reverse |
初始值: | nowrap |
适用于: | 弹性容器 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 指定的关键字 |
规范顺序: | 按语法 |
动画类型: | 离散 |
flex-wrap 属性控制弹性容器是 单行 还是 多行, 以及 交叉轴 的方向, 决定了新行的堆叠方向。
- nowrap
- 弹性容器为 单行。
- wrap
- 弹性容器为 多行。
- wrap-reverse
- 与 wrap 相同。
对于不是 wrap-reverse 的值, 交叉起始 方向等同于当前 内联起始 或 块起始 方向(取决于哪个在 交叉轴 中), 交叉结束 方向与 交叉起始 方向相反。 当 flex-wrap 为 wrap-reverse 时, 交叉起始 和 交叉结束 方向将被交换。
5.3. 弹性方向和换行:flex-flow 速记属性
名称: | flex-flow |
---|---|
值: | <‘flex-direction’> || <‘flex-wrap’> |
初始值: | 参见各个属性 |
适用于: | 参见各个属性 |
继承: | 参见各个属性 |
百分比: | 参见各个属性 |
计算值: | 参见各个属性 |
动画类型: | 离散 |
规范顺序: | 按语法 |
flex-flow 属性是用于设置 flex-direction 和 flex-wrap 的速记属性, 它们共同定义了弹性容器的主轴和交叉轴。
| |
| |
|
英语 | 日语 |
---|---|
flex-flow: row wrap; |
flex-flow: row wrap; |
5.4. 显示顺序:order 属性
弹性项目 默认情况下按照它们在源文档中的出现顺序显示和布局。 可以使用 order 属性更改此顺序。
名称: | order |
---|---|
值: | <integer> |
初始值: | 0 |
适用于: | 弹性项目 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 指定的整数 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
order 属性控制 弹性项目在弹性容器中的显示顺序, 通过将它们分配到不同的序号组。 它接受一个 <integer> 值, 指定弹性项目所属的序号组。
弹性容器按照 修改后的文档顺序 布局其内容, 从最低的序号组开始依次排列。 具有相同序号组的项目按照它们在源文档中的出现顺序布局。 这也影响 绘制顺序 [CSS21], 正如弹性项目在源文档中重新排序一样。 弹性容器的绝对定位子项目视为具有 order: 0, 用于确定它们相对于弹性项目的绘制顺序。

可以使用以下 CSS 来实现(仅展示相关代码):
.tabs { display : flex; } .tabs > .current { order : -1 ; /* 低于默认值 0 */ }
除非未来的规范另有规定, 否则该属性对非弹性项目的盒子没有影响。
5.4.1. 重新排序和可访问性
order
属性不影响非视觉媒体中的排序
(如语音)。
同样,order 也不会影响
顺序导航模式的默认遍历顺序
(例如通过链接循环,参见 tabindex
[HTML])。
作者必须仅将order 用于视觉内容的重新排序,而不是逻辑排序。 使用 order 进行逻辑重排的样式表是非合规的。
注意: 这样做是为了使非视觉媒体和非 CSS 用户代理 (通常线性地呈现内容), 可以依赖于逻辑的源顺序, 而 order 用于调整视觉顺序。 (由于视觉感知是二维的且非线性的, 所以所需的视觉顺序并不总是逻辑的。)
<!DOCTYPE html> < header > ...</ header > < main > < article > ...</ article > < nav > ...</ nav > < aside > ...</ aside > </ main > < footer > ...</ footer >
这个布局可以通过弹性布局轻松实现:
main { display : flex; } main > article { order : 2 ; min-width : 12 em ; flex : 1 ; } main > nav { order : 1 ; width : 200 px ; } main > aside { order : 3 ; width : 200 px ; }
额外的好处是, 所有列默认都是等高的, 并且主内容会根据需要扩展至填满屏幕。 此外, 还可以将其与媒体查询结合使用,在狭窄的屏幕上切换为全垂直布局:
@media all and( max-width: 600px) { /* 过于狭窄,无法支持三列布局 */ main { flex-flow: column; } main > article, main > nav, main > aside { /* 将它们恢复到文档顺序 */ order: 0; width: auto; } }
(进一步使用多行弹性容器来实现更智能的包装,留给读者作为练习。)
为了在所有展示模式下保留作者的预期顺序,
作者工具(包括所见即所得编辑器以及基于 Web 的创作工具)
由于大多数情况下,重新排序应影响所有屏幕范围 以及导航和语音顺序, 因此工具应在 DOM 层进行拖放式重新排序。 然而,在某些情况下,作者可能希望在每个屏幕尺寸上有不同的视觉顺序。 该工具可以通过使用order结合媒体查询提供此功能, 但也将最小屏幕尺寸的排序与底层 DOM 顺序关联 (因为这最有可能是一个逻辑线性呈现顺序) 同时在其他尺寸范围内使用order确定视觉展示顺序。
此工具是符合规范的,而仅使用order来处理 拖放式重新排序的工具 (尽管从实现的角度来看这可能很方便) 则不符合规范。
注意: 用户代理,包括浏览器、辅助技术和 扩展, 可能提供空间导航功能。 本节不排除在确定这些空间导航模式中的元素顺序时尊重 order 属性; 实际上,为了使这样的功能正常工作,它是需要考虑的。 但是 order 并不是此类空间导航功能需要考虑的唯一(或主要)CSS 属性。 一个良好实现的空间导航功能需要考虑 所有修改空间关系的 CSS 布局特性。
6. 弹性行
弹性项目 在一个 弹性容器 中进行布局和对齐, 它们位于 弹性行 中,这些是假想的容器,用于由布局算法进行分组和对齐。 弹性容器可以是 单行 或 多行, 这取决于 flex-wrap 属性:
-
一个 单行弹性容器(即具有 flex-wrap: nowrap 的容器) 会将所有子元素布局在一条线上, 即使这样会导致其内容溢出。
-
一个 多行弹性容器(即具有 flex-wrap: wrap 或 flex-wrap: wrap-reverse) 会将其 弹性项目 分成多行, 类似于当文本太宽而无法适应现有行时会被换行。 当创建其他行时, 它们会根据 交叉轴 沿着弹性容器进行堆叠,具体取决于 flex-wrap 属性。 每一行至少包含一个 弹性项目, 除非弹性容器本身完全为空。
#flex { display : flex; flex-flow : row wrap; width : 300 px ; } .item { width : 80 px ; }
< div id = "flex" > < div class = "item" > 1</ div > < div class = "item" > 2</ div > < div class = "item" > 3</ div > < div class = "item" > 4</ div > </ div >
由于容器宽度为 300px,只有三个项目可以放在一行上。 它们占用了 240px,还剩下 60px 的空间。 由于 flex-flow 属性指定了 多行弹性容器 (因为在其值中出现了 wrap 关键字), 弹性容器将创建一个额外的行来容纳最后一个项目。
一旦内容被分成多行, 每一行会独立布局; 弹性长度以及 justify-content 和 align-self 属性仅考虑每次一行中的项目。
在一个 多行弹性容器 中(即使只有一行), 每一行的 交叉尺寸 是容纳该行中 弹性项目 的最小尺寸 (在 align-self 对齐后), 并且这些行会根据 align-content 属性在弹性容器内对齐。 在一个 单行 弹性容器 中, 该行的 交叉尺寸 是弹性容器的 交叉尺寸, 并且 align-content 没有影响。 该行的 主尺寸 总是与弹性容器内容框的 主尺寸 相同。
7. 灵活性
弹性布局的定义特性是使 弹性项目“弹性化”, 调整它们的宽度/高度以填充 主轴 中的可用空间。 这是通过 flex 属性来完成的。 一个弹性容器会将可用空间分配给它的项目(按其 弹性增长因子 的比例), 或者缩小它们(按其 弹性收缩因子 的比例)以防止溢出。
如果 弹性项目 的 flex-grow 和 flex-shrink 值都为零, 则它是 完全不可伸缩的, 否则是 可伸缩的。
7.1. flex 简写
名称: | flex |
---|---|
值: | none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ] |
初始值: | 0 1 auto |
适用于: | 弹性项目 |
继承: | no |
百分比: | 参见各个属性 |
计算值: | 参见各个属性 |
动画类型: | 按计算值类型 |
规范顺序: | 按语法 |
flex 属性指定了 弹性长度 的组成部分: 包括 弹性因子(增长 和 收缩) 以及 弹性基准。 当一个框是 弹性项目 时,会使用 flex 来代替 主尺寸属性 来确定该框的 主尺寸。 如果一个框不是 弹性项目,flex 则不起作用。
- <‘flex-grow’>
-
该 <number> 组件设置 flex-grow 长写形式并指定 弹性增长因子,
它决定了当分配正的可用空间时,弹性项目 将相对于同容器中的其他
弹性项目 增长的程度。
如果省略,则设置为 1。
0 和 1 之间的弹性值有一些特殊的行为:当行内弹性值总和小于 1 时,它们将占据少于 100% 的可用空间。
项目的 flex-grow 值实际上是对部分可用空间的请求,1 意味着“100% 的可用空间”;如果行内项目请求的总量超过 100%,则这些请求会被重新平衡,保持相同比例但正好使用 100% 的可用空间。然而,如果项目请求的总量少于全部空间(例如三个项目的 flex-grow: .25),那么每个项目会正好获得所请求的空间(每个获得 25% 的可用空间,最终剩余 25% 的空间未被使用)。详见 §9.7 解决弹性长度 了解可用空间的具体分配细节。
此模式是为了在 flex-grow 值接近零时实现连续的行为(意味着项目不希望占据任何可用空间)。没有此行为时,flex-grow: 1 项目将占据所有的可用空间;同样,flex-grow: 0.1 和 flex-grow: 0.01 项目也是如此,直到最终值小到下溢为零,项目突然不占据任何可用空间。通过这种行为,项目会随着 flex-grow 值小于 1 时逐渐占据更少的可用空间,平滑地过渡到不占据任何可用空间的状态。
除非 明确 希望实现这种“部分填充”行为,否则作者应坚持使用 ≥ 1 的值;例如,使用 1 和 2 通常比使用 .33 和 .67 更好,因为这样在项目被添加、删除或换行时,它们更可能按预期工作。
- <‘flex-shrink’>
-
该 <number> 组件设置 flex-shrink 长写形式并指定 弹性收缩因子,
它决定了当分配负的可用空间时,弹性项目 相对于同容器中的其他 弹性项目 收缩的程度。
如果省略,则设置为 1。
注意: 弹性收缩因子会与 弹性基准大小 相乘来分配负的空间。这样,较小的项目不会在较大的项目显著缩小之前就缩小到零。
- <‘flex-basis’>
-
该组件设置 flex-basis 长写形式,
指定 弹性基准:
在根据弹性因子分配可用空间之前,弹性项目 的初始 主尺寸。
<‘flex-basis’> 接受与 width 和 height 属性相同的值(除了 auto 被视为不同),加上 content 关键字:
- auto
- 当在 弹性项目 上指定时,auto 关键字会检索 主尺寸属性 的值作为使用的 flex-basis。 如果该值本身为 auto,则使用的值为 content。
- content
-
表示基于 弹性项目 内容的 自动尺寸。
(它通常等效于 最大内容尺寸,但会调整以处理纵横比、固有大小约束和正交流;详见 详情 在 §9 弹性布局算法 中。)
注意: 该值在弹性盒布局的初始版本中不存在,因此一些旧的实现可能不支持它。等效效果可以通过使用 auto 并将主尺寸(width 或 height)设置为 auto 来实现。
- <‘width’>
- 对于所有其他值,flex-basis 解析方式与 width 和 height 相同。
当省略 flex 简写时,其指定值为 0。
- none
- 关键字 none 展开为 0 0 auto。
flex 组件的初始值相当于 flex: 0 1 auto。
注意: flex-grow 和 flex-basis 的初始值与它们在省略 flex 简写时的默认值不同。这样做是为了让 flex 简写更好地适应最 常见情况。
如果一个无单位的零前面没有两个弹性因子,则必须将其解释为弹性因子。为了避免误解或无效声明,作者必须为零的 <‘flex-basis’> 组件指定一个单位,或在其前面加上两个弹性因子。
7.1.1. 基本 flex 值
本节为信息性内容。
下面的列表总结了四种 flex 值的效果, 它们代表了大多数常见的需求:
- flex: initial
- 等效于 flex: 0 1 auto。(这是初始值。) 基于 width/height 属性调整项目的大小。 (如果项目的 主尺寸属性 计算为 auto, 这将根据项目内容调整弹性项目的大小。) 当有正的可用空间时,使弹性项目不可伸展, 但当空间不足时允许它收缩到最小尺寸。 可以使用 对齐能力 或 auto margin 沿 主轴 对齐弹性项目。
- flex: auto
- 等效于 flex: 1 1 auto。 基于 width/height 属性调整项目的大小, 但使它们完全灵活,这样它们就可以吸收沿 主轴 的任何可用空间。 如果所有项目要么是 flex: auto,要么是 flex: initial 或 flex: none, 则在项目调整大小后,任何正的可用空间将平均分配给使用 flex: auto 的项目。
- flex: none
- 等效于 flex: 0 0 auto。 该值根据 width/height 属性调整项目的大小, 但使弹性项目 完全不可伸缩。 这类似于 initial, 不同之处在于弹性项目即使在溢出情况下也不允许收缩。
- flex: <positive-number>
- 等效于 flex: <positive-number> 1 0。 使弹性项目灵活并将 弹性基准 设置为零, 这样项目将获得弹性容器中可用空间的指定比例。 如果弹性容器中的所有项目都使用此模式, 它们的大小将与指定的弹性因子成比例。
默认情况下,弹性项目不会收缩到小于其最小内容大小(最长单词或固定大小元素的长度)。 要更改此设置,请设置 min-width 或 min-height 属性。 (请参阅 §4.5 弹性项目的自动最小大小。)
7.2. 灵活性的组成部分
可以通过独立的长写属性来控制灵活性的各个组件。
建议作者使用 flex 简写来控制灵活性, 而不是直接使用其长写属性, 因为简写会正确重置任何未指定的组件, 以适应 常见用法。
7.2.1. flex-grow 属性
名称: | flex-grow |
---|---|
值: | <number> |
初始值: | 0 |
适用于: | 弹性项目 |
继承性: | 无 |
百分比: | 不适用 |
计算值: | 指定的数字 |
规范顺序: | 按照语法 |
动画类型: | 按计算值类型 |
建议作者使用 flex 简写 来控制灵活性,而不是直接使用 flex-grow, 因为简写可以正确重置未指定的组件,以适应 常见用途。
flex-grow 属性将 弹性增长因子 设置为提供的 <number>。 负数是无效的。
7.2.2. flex-shrink 属性
名称: | flex-shrink |
---|---|
值: | <number> |
初始值: | 1 |
适用于: | 弹性项目 |
继承性: | 无 |
百分比: | 不适用 |
计算值: | 指定值 |
规范顺序: | 按照语法 |
动画类型: | 数字 |
建议作者使用 flex 简写 来控制灵活性,而不是直接使用 flex-shrink, 因为简写可以正确重置未指定的组件,以适应 常见用途。
flex-shrink 属性将 弹性收缩因子 设置为 提供的 <number>。 负数是无效的。
7.2.3. flex-basis 属性
名称: | flex-basis |
---|---|
值: | content | <‘width’> |
初始值: | auto |
适用于: | 弹性项目 |
继承性: | 无 |
百分比: | 相对于 弹性容器 内部的 主尺寸 |
计算值: | 指定的关键字或计算后的 <length-percentage> 值 |
规范顺序: | 按照语法 |
动画类型: | 按计算值类型 |
建议作者使用 flex 简写 来控制灵活性,而不是直接使用 flex-basis, 因为简写可以正确重置未指定的组件,以适应 常见用途。
flex-basis 属性设置 弹性基础值。 它接受与 width 和 height 属性相同的值, 另外还有 content。
对于 auto 和 content(在上文中定义)以外的所有值, flex-basis 的解析方式与水平方向的 width 相同 [CSS21], 除非该值会解析为 auto, 在这种情况下,它将解析为 content。
例如,flex-basis 的百分比值是根据弹性项目的包含块(即其 弹性容器)来解析的; 如果该包含块的大小是 不确定的, 则用于 flex-basis 的值是 content。 作为另一个推论,flex-basis 决定内容框的大小, 除非另有规定, 例如通过 box-sizing [CSS3UI]。
8. 对齐
当弹性容器的内容完成弹性调整后,所有弹性项目的尺寸已最终确定, 它们可以在弹性容器内对齐。
margin 属性可以用来对齐项目, 类似于块布局中的边距对齐,但功能更强大。弹性项目 还遵循 CSS Box Alignment 中的对齐属性, 这些属性允许通过关键字轻松地在 主轴 和 交叉轴 上对齐项目。 这些属性使许多常见的对齐类型变得非常简单, 包括一些在 CSS 2.1 中非常困难的对齐方式,比如水平和垂直居中。
注意: 虽然对齐属性是在 CSS Box Alignment 中定义的 [CSS-ALIGN-3], 弹性盒布局在此重现了相关的定义, 以避免创建可能延缓规范进展的规范性依赖。 这些属性仅适用于弹性布局, 直到 CSS Box Alignment Level 3 完成, 并定义它们对其他布局模式的影响。 此外,Box Alignment 模块中定义的任何新值将适用于弹性盒布局; 换句话说,Box Alignment 模块一旦完成, 将取代这里的定义。
8.1. 使用 auto 边距对齐
本节为非规范性内容。 关于边距如何影响弹性项目的规范定义在 弹性布局算法 部分。
弹性项目上的 auto 边距的效果与块流中的 auto 边距非常相似:
-
在计算弹性基准和弹性长度期间,auto 边距被视为 0。
-
在通过 justify-content 和 align-self 对齐之前, 任何正的空闲空间都分配给该维度上的 auto 边距。
-
溢出的框忽略其 auto 边距,并向 末端 方向溢出。
注意: 如果空闲空间被分配给 auto 边距, 那么对齐属性在该维度上将不起作用, 因为边距将占据弹性调整后剩余的所有空闲空间。
nav > ul { display : flex; } nav > ul > #login { margin-left : auto; }
< nav > < ul > < li >< a href = /about > 关于</ a > < li >< a href = /projects > 项目</ a > < li >< a href = /interact > 互动</ a > < li id = "login" >< a href = /login > 登录</ a > </ ul > </ nav >
8.2. 轴对齐:justify-content 属性
名称: | justify-content |
---|---|
值: | flex-start | flex-end | center | space-between | space-around |
初始值: | flex-start |
适用范围: | 弹性容器 |
是否继承: | 否 |
百分比: | n/a |
计算值: | 指定的关键字 |
规范顺序: | 按语法 |
动画类型: | 离散 |
justify-content 属性沿着 主轴 对当前弹性容器行中的 弹性项目 进行对齐。 这是在解决任何弹性长度和 auto 边距 之后完成的。 通常,它有助于分配剩余的空闲空间, 例如当行中的所有 弹性项目 都是不可弹性, 或者它们是弹性的但已达到最大尺寸。 它还对项目在行溢出的情况下的对齐方式施加一些控制。
- flex-start
- 弹性项目 会朝行的起始方向排列。 第一个 弹性项目 的 主轴起点 边距紧贴行的 主轴起点 边缘, 每个后续的 弹性项目 都紧贴在前一个项目之后。
- flex-end
- 弹性项目 会朝行的末尾方向排列。 最后一个 弹性项目 的 主轴终点 边距紧贴行的 主轴终点 边缘, 每个前一个 弹性项目 都紧贴后一个项目。
- center
- 弹性项目 会朝行的中心排列。 行中的 弹性项目 紧贴排列, 并居中对齐, 在行的 主轴起点 边缘与行上的第一个项目之间, 以及行的 主轴终点 边缘与行上的最后一个项目之间留有相等的空间。 (如果剩余的空闲空间为负数, 则 弹性项目 将在两个方向上均匀溢出。)
- space-between
- 弹性项目 会均匀分布在行中。 如果剩余的空闲空间为负数或行中只有一个 弹性项目, 则此值与 flex-start 相同。 否则, 行上的第一个 弹性项目 的 主轴起点 边距紧贴行的 主轴起点 边缘, 最后一个 弹性项目 的 主轴终点 边距紧贴行的 主轴终点 边缘, 行上的其他 弹性项目 均匀分布, 相邻项目之间的间距相同。
- space-around
- 弹性项目 会均匀分布在行中, 两端留有半个尺寸的空间。 如果剩余的空闲空间为负数或行中只有一个 弹性项目, 则此值与 center 相同。 否则,行上的 弹性项目 均匀分布, 相邻 弹性项目 之间的间距相同, 第一个和最后一个 弹性项目 与 弹性容器 边缘之间的间距是项目之间间距的一半。
五个 justify-content 关键字及其对包含三个彩色项目的弹性容器的影响示意图。
8.3. 交叉轴对齐:align-items 和 align-self 属性
名称: | align-items |
---|---|
值: | flex-start | flex-end | center | baseline | stretch |
初始值: | stretch |
适用范围: | 弹性容器 |
是否继承: | 否 |
百分比: | n/a |
计算值: | 指定的关键字 |
规范顺序: | 按语法 |
动画类型: | 离散 |
名称: | align-self |
---|---|
值: | auto | flex-start | flex-end | center | baseline | stretch |
初始值: | auto |
适用范围: | 弹性项目 |
是否继承: | 否 |
百分比: | n/a |
计算值: | 指定的关键字 |
规范顺序: | 按语法 |
动画类型: | 离散 |
弹性项目 可以在当前弹性容器行的 交叉轴 上对齐, 类似于 justify-content,但在垂直方向上。align-items 为所有弹性容器的 项目 设置默认对齐方式, 包括匿名的 弹性项目。align-self 允许为单个 弹性项目 覆盖此默认对齐方式。 (对于匿名弹性项目,align-self 始终匹配其相关弹性容器上的 align-items 值。)
如果 弹性项目 的任何交叉轴边距为 auto,则 align-self 无效。
各值含义如下:
- auto
- 将 交叉轴 对齐控制 转移给父级框上的 align-items 值。 (这是 align-self 的初始值。)
- flex-start
- 弹性项目 的 交叉起点 边缘 放置于行的 交叉起点 边缘。
- flex-end
- 弹性项目 的 交叉终点 边缘 放置于行的 交叉终点 边缘。
- center
- 弹性项目 的边距框在行内的 交叉轴 上居中。 (如果弹性行的 交叉尺寸 小于 弹性项目 的尺寸, 它会向两个方向溢出。)
- baseline
- 弹性项目 参与基线对齐: 行上所有参与对齐的 弹性项目 都会对齐基线, 并且基线与 交叉起点 边缘之间距离最大的项目 放置在行的 交叉起点 边缘。 如果项目在必要的轴上没有基线, 则会从该 弹性项目 的边框框中 合成 一个基线。
- stretch
-
如果 交叉尺寸属性 的
弹性项目
计算为 auto,
并且两个 交叉轴 边距均不为 auto,
则该 弹性项目 会被 拉伸。
其使用的值是使项目的 交叉尺寸 尽可能接近行的尺寸的长度,
同时仍尊重 最小高度、最小宽度、最大高度 和 最大宽度 等约束。
注意: 如果弹性容器的高度受到约束, 则此值可能会导致 弹性项目 的内容溢出该项目。
五个 align-items 关键字及其对包含四个彩色项目的弹性容器的影响示意图。
8.4. 在 Flex 行中打包:align-content 属性
名称: | align-content |
---|---|
值: | flex-start | flex-end | center | space-between | space-around | stretch |
初始值: | stretch |
应用于: | 多行 flex 容器 |
是否继承: | 否 |
百分比: | 不适用 |
计算值: | 指定的关键字 |
规范顺序: | 按语法规则 |
动画类型: | 离散型 |
align-content 属性用于在 flex 容器中对齐其行 ,当在 交叉轴中有多余空间时起作用,类似于 justify-content 在主轴上对齐 flex 项的作用。此属性对单行 flex 容器 无效。含义如下:
- flex-start
- 各行向 flex 容器的起始方向打包。 第一行的 cross-start 边缘与 flex 容器的 cross-start 边缘对齐,每个后续行与前一行对齐。
- flex-end
- 各行向 flex 容器的末尾方向打包。 最后一行的 cross-end 边缘与 flex 容器的 cross-end 边缘对齐,每个前一行与后一行对齐。
- center
- 各行向 flex 容器的中央打包。各行在 flex 容器中彼此对齐,并居中排列。cross-start 内容边缘与第一行之间,以及 cross-end 内容边缘与最后一行之间的空隙相等。(如果剩余空间为负数,各行将会平均溢出两边。)
- space-between
- 各行在 flex 容器中均匀分布。如果剩余空间为负数,或 flex 容器中只有一行 flex 行,此值等同于 flex-start。否则,第一行的 cross-start 边缘与 flex 容器的 cross-start 内容边缘对齐,最后一行的 cross-end 边缘与 flex 容器的 cross-end 内容边缘对齐,其余各行均匀分布。
- space-around
- 各行在 flex 容器中均匀分布,两端留有半个空隙。如果剩余空间为负数,此值等同于 center。否则,各行均匀分布,相邻两行之间的空隙相等,第一行与最后一行与 flex 容器边缘的空隙为相邻行之间空隙的一半。
- stretch
- 各行伸展以占据剩余空间。如果剩余空间为负数,此值等同于 flex-start。否则,剩余空间在所有行之间平均分配,增加其交叉尺寸。
注意: 只有 多行 flex 容器 才有交叉轴上的空余空间用于对齐各行,因为单行 flex 容器 的唯一一行会自动伸展以填充空间。
图解 align-content 关键字及其对 多行 flex 容器的效果。
8.5. Flex 容器的基线
为了使 flex 容器 自身 参与基线对齐(例如当 flex 容器 自身是外部 flex 容器 中的 flex 项时), 它需要提交最能代表其内容的基线位置。 为此,flex 容器的基线如下确定 (在使用 order 重新排序并考虑 flex-direction 之后):
- 第一个/最后一个 主轴基线集
- 当 内联轴 与 flex 容器 的 主轴 匹配时, 基线如下确定:
- 第一个/最后一个 交叉轴基线集
- 当 内联轴 与 flex 容器 的 交叉轴 匹配时, 基线如下确定:
根据上述规则计算基线时, 如果提供基线的盒子的 overflow 值允许滚动, 则在确定其基线时,必须将该盒子视为处于初始滚动位置。
在 确定表格单元的基线 时, flex 容器提供的基线与行框或表行相同。 [CSS21]
有关基线的更多信息,请参见 CSS Writing Modes 3 §4.1 基线介绍 和 CSS Box Alignment 3 §9 基线对齐细节。
9. 弹性布局算法
本节包含规范算法,详细描述了弹性容器及其内容的确切布局行为。此处的算法旨在优化可读性和理论简洁性,可能不一定是最有效的实现方式。实现者可以使用任何实际的算法,但必须生成与此处描述的算法相同的结果。
注意:本节主要面向实现者。编写网页的作者通常可以通过个别属性描述获得帮助,除非他们对理解CSS布局的复杂细节有强烈的兴趣,否则不需要阅读本节内容。
以下部分定义了为弹性容器及其内容布局的算法。
注意:弹性布局根据弹性项目的顺序修改文档顺序工作,而不是它们的原始文档顺序。
9.1. 初始设置
- 生成匿名弹性项目,如§4 弹性项目中所述。
9.2. 行长度确定
- 确定弹性项目的可用主轴和交叉轴空间。对于每个维度, 如果该维度的弹性容器的内容框是确定大小,则使用该值; 如果该维度的弹性容器在最小内容约束或最大内容约束下被调整大小,则该维度的可用空间是该约束; 否则,从该维度中为弹性容器提供的可用空间中减去弹性容器的外边距、边框和填充,并使用该值。这可能导致一个无限值。
-
确定每个项目的弹性基础大小和
假设主尺寸:
- 如果项目具有确定的使用的弹性基础,则该值即为弹性基础大小。
-
如果弹性项目具有...
- 固有的纵横比,
- 使用的flex basis为content,并且
- 确定的交叉尺寸,
- 如果使用的flex basis是content或取决于其可用空间,并且弹性容器正在最小或最大内容约束下调整大小(例如执行自动表布局[CSS21]), 则根据该约束调整项目大小。弹性基础大小是项目的主尺寸。
- 否则, 如果使用的flex basis是content或取决于其可用空间,可用的主尺寸是无限的,并且弹性项目的内联轴与主轴平行,按正交流中盒子的规则[CSS3-WRITING-MODES]布局项目。 弹性基础大小是项目的最大内容主尺寸。
- 否则, 使用其使用的flex basis代替其主尺寸,将项目调整为可用空间,将content值视为max-content。 如果需要交叉尺寸来确定主尺寸(例如,当弹性项目的主尺寸在其块轴中时),并且弹性项目的交叉尺寸为auto且不是确定的, 则在此计算中使用fit-content作为弹性项目的交叉尺寸。 弹性基础大小是项目的结果主尺寸。
在确定弹性基础大小时, 会忽略项目的最小和最大主尺寸 (不会发生任何限制操作)。 此外,在应用box-sizing时, 将内容框尺寸向下限制为零的大小计算也会被忽略。 (例如,一个指定大小为零、正填充,并且具有 box-sizing: border-box的项目将具有外部弹性基础大小为零——因此其内部 弹性基础大小将为负值。)
- 根据其参与的格式化上下文规则确定弹性容器的主尺寸。 在此计算中,弹性项目上的auto外边距视为0。
9.3. 主尺寸确定
-
将弹性项目收集到弹性行中:
- 如果弹性容器是单行的, 将所有弹性项目收集到一个弹性行中。
-
否则,从第一个未收集的项目开始,一个接一个地收集连续的项目,直到第一次遇到下一个收集的项目无法放入弹性容器的内部主尺寸(或遇到强制换行,请参见第10节
弹性布局的分片)。如果第一个未收集的项目不能适应,只收集它到行中。
在此步骤中,弹性项目的大小是其外部假设主尺寸。(注:这可能是负数。)
重复直到所有弹性项目都被收集到弹性行中。
请注意,“收集尽可能多的项目”这一行将会把零大小的弹性项目收集到前一行的末尾,即使最后一个非零项目完全“填满”了这一行。
- 解决所有弹性项目的弹性长度,以找到它们的使用主尺寸。参见第9.7节 解决弹性长度。
9.4. 副尺寸确定
- 通过使用主尺寸和可用空间来确定每个项目的假设副尺寸,将自动视为fit-content。
-
计算每个弹性行的副尺寸。
如果弹性容器是单行的,并且具有明确的副尺寸,则弹性行的副尺寸是弹性容器的内部副尺寸。
否则,对于每个弹性行:
- 处理'align-content: stretch'。如果弹性容器具有明确的副尺寸,align-content为stretch,并且弹性行的副尺寸总和小于弹性容器的内部副尺寸,则通过增加每个弹性行的副尺寸,使它们的总和正好等于弹性容器的内部副尺寸。
-
折叠visibility:collapse的项目。如果有弹性项目具有visibility: collapse,请记录它们所在行的副尺寸作为该项目的支柱尺寸,并从头开始重新布局。
在第二次布局中,当将项目收集到行中时,将折叠的项目视为具有零主尺寸。在接下来的算法步骤中,完全忽略这些折叠的项目(就像它们是display:none一样),但在计算行的副尺寸之后,如果任何行的副尺寸小于该行中所有折叠项目的最大支柱尺寸,则将该行的副尺寸设置为该支柱尺寸。
跳过第二次布局中的此步骤。
-
确定每个弹性项目的实际使用副尺寸。如果一个弹性项目的align-self:
stretch,其计算的副尺寸属性为自动,并且其副轴两侧的边距都不是自动,则使用的外部副尺寸为该弹性行的使用副尺寸,根据该项目的最小和最大副尺寸进行限制。
否则,使用的副尺寸是该项目的假设副尺寸。
如果弹性项目的align-self: stretch,则为其内容重新布局,视该使用尺寸为其确定的副尺寸,以便可以解析百分比大小的子元素。
请注意,此步骤不会影响弹性项目的主尺寸,即使它具有固有的宽高比。
9.5. 主轴对齐
-
分配剩余的可用空间。
对于每个弹性行:
- 如果剩余的可用空间为正值,并且该行上至少有一个主轴边距是自动,则将可用空间均匀分配给这些边距。否则,将所有自动边距设置为零。
- 根据justify-content沿主轴对齐项目。
9.6. 副轴对齐
- 解决副轴上的自动边距。 如果弹性项目具有自动副轴边距:
- 根据align-self沿副轴对齐所有弹性项目,如果项目的副轴边距均不是自动。
- 确定弹性容器的使用副尺寸:
- 根据align-content对齐所有弹性行。
9.7. 解决弹性长度
要解决弹性行中项目的弹性长度:
- 确定使用的弹性因子。 将行上所有项目的外部假设主尺寸相加。如果总和小于弹性容器的内部主尺寸,则在本算法中使用弹性增长因子;否则,使用弹性收缩因子。
- 调整非弹性项目的大小。 冻结,将其目标主尺寸设置为其假设主尺寸...
- 计算初始可用空间。 将行上所有项目的外部尺寸相加,并从弹性容器的内部主尺寸中减去。对于冻结的项目,使用它们的外部目标主尺寸;对于其他项目,使用它们的外部弹性基准尺寸。
-
循环:
- 检查弹性项目。 如果行上的所有弹性项目都已冻结,则可用空间已分配完毕;退出此循环。
- 如上所述,计算剩余可用空间。 如果未冻结的弹性项目的弹性因子总和小于1,将初始可用空间乘以此总和。如果该值的大小小于剩余可用空间的大小,则使用此值作为剩余可用空间。
- 按弹性因子分配可用空间。
- 修复最小/最大限制的违规情况。 将每个未冻结项目的目标主尺寸限制在其使用的最小和最大主尺寸范围内,并将其内容框大小限制为不小于零。如果项目的目标主尺寸变小,则是最大值违规。如果项目的目标主尺寸变大,则是最小值违规。
-
冻结过度调整的项目。 总违规量是上一步调整的总和
∑(限制后的大小 - 未限制的大小)
。如果总违规量为:- 零
- 冻结所有项目。
- 正值
- 冻结所有最小值违规的项目。
- 负值
- 冻结所有最大值违规的项目。
- 返回到此循环的开头。
- 将每个项目的使用主尺寸设置为其目标主尺寸。
9.8. 确定和不确定的尺寸
尽管 CSS 尺寸 [CSS-SIZING-3] 定义了确定的和不确定的长度,Flexbox 有一些额外的情况,使得一个长度可以被视为确定的:
- 如果一个单行弹性容器有一个确定的副尺寸,任何拉伸的弹性项目的外部副尺寸是弹性容器的内部副尺寸(限制在该弹性项目的最小和最大副尺寸范围内),并被视为确定的。
- 如果弹性容器有一个确定的主尺寸,一个弹性项目的弹性调整后的主尺寸也被视为确定的,即使它依赖于同一行中任何弹性项目的不确定尺寸。
- 一旦弹性行的副尺寸确定,对于布局目的,自动大小的弹性容器中的项目也被视为确定的;参见步骤11。
注意:具有确定的弹性基准尺寸的完全非弹性项目的主尺寸,根据定义,是确定的。
9.9. 固有尺寸
固有尺寸用于生成基于内容的各种自动尺寸,比如收缩适合的逻辑宽度(使用fit-content公式)和基于内容的逻辑高度(使用最大内容尺寸)。
请参见[CSS-SIZING-3],以获取本节中术语的定义。
9.9.1. 弹性容器的固有主尺寸
最大内容主尺寸 是弹性容器可以采用的最小尺寸,同时保持其最大内容贡献,在项目的灵活性允许范围内:
- 对于每个弹性项目,从其弹性基准尺寸中减去其最大内容贡献尺寸。如果结果为正,则除以其弹性增长因子(最小值为1);如果为负,则除以其缩放弹性收缩因子(将弹性收缩因子最小值设为1)。这是项目的最大内容弹性分数。
- 将所有弹性项目放入无限长度的行中。
- 在每行内,找到所有弹性项目中最大的最大内容弹性分数。将每个项目的弹性基准尺寸与其弹性增长因子(如果选择的最大内容弹性分数为负,则为缩放弹性收缩因子)的乘积相加,然后将结果限制在最大主尺寸和最小主尺寸之间。
- 弹性容器的最大内容尺寸是所有项目在单行内计算出的尺寸的最大总和。
最小内容主尺寸 的单行弹性容器的计算方式与最大内容主尺寸相同,只是使用了最小内容贡献而非最大内容贡献。然而,对于多行容器,它仅是最小内容贡献中的最大值。
当弹性和的值小于1时,此算法的影响
上述算法旨在为两个特殊情况提供正确的行为,并在这两种情况之间转换时使得弹性容器的大小连续:
-
如果所有项目都是非弹性的,弹性容器的大小将调整为其弹性基准尺寸之和。(非弹性的弹性基准尺寸基本上取代了宽度/高度,而当指定时,它就是最大内容贡献在块布局中的基础。)
-
当所有项目的弹性因子≥ 1 时,弹性容器的大小将调整为其项目的最大内容贡献之和(或稍大的尺寸,使得每个弹性项目至少具有其最大内容贡献的大小,但也具有其尺寸与其他项目尺寸的正确比例,按照其弹性决定)。
例如,如果一个弹性容器有一个弹性项目,其flex-basis: 100px;,但最大内容尺寸为200px,则当该项目的flex-grow: 0时,弹性容器(以及弹性项目)的宽度为100px,但当该项目的flex-grow: 1或更高时,弹性容器(及弹性项目)的宽度为200px。
有几种方法可以在这些两种情况之间实现整体行为的连续性,尤其是在一行上的弹性总和在0到1之间时,但所有方法都有其缺点。我们选择了一种我们认为影响最小的方法;不幸的是,当弹性总和小于1时,它会"重复应用"弹性。在上述示例中,如果项目的弹性增长: .5,则弹性容器的宽度最终为150px,但项目随后在可用空间中正常调整大小,最终宽度为125px。
9.9.2. 弹性容器的固有副尺寸
最小内容/最大内容副尺寸 的 单行弹性容器是其最小内容贡献/最大内容贡献(分别)的最大值。
对于多行弹性容器, 最小内容/最大内容副尺寸是根据在副轴方向上的最小内容约束/最大内容约束(分别)调整弹性容器大小后,所有弹性行副尺寸的总和。 然而,如果弹性容器的flex-flow: column wrap;, 那么首先找到所有最小内容/最大内容副尺寸贡献中的最大值(分别),然后在布局期间将该尺寸作为每个弹性项目在副轴上的可用空间。
注意:此用于 column wrap弹性容器的启发式方法提供了对弹性容器应该尺寸的合理近似,每个弹性项目最终为 min(项目自身的最大内容, 所有项目中的最大最小内容),且每个弹性行不大于其最大的弹性项目。 在某些情况下,它不是一个完美的匹配,但完全正确的处理是非常昂贵的,而这个方法表现得相当不错。
9.9.3. 弹性项目的固有尺寸贡献
最小内容贡献的主尺寸弹性项目是其外部最小内容尺寸和外部首选尺寸(适用时为其宽度或高度)中较大的一个, 如果该值不是auto,则按其弹性基准尺寸作为最大值(如果不可增长)和/或作为最小值(如果不可收缩)进行限制,然后再进一步按其最小主尺寸/最大主尺寸进行限制。
最大内容贡献的主尺寸弹性项目是其外部最大内容尺寸和外部首选尺寸(适用时为其宽度或高度)中较大的一个,按其弹性基准尺寸作为最大值(如果不可增长)和/或作为最小值(如果不可收缩)进行限制,然后再进一步按其最小主尺寸/最大主尺寸进行限制。
10. 分片弹性布局
弹性容器可以在页面间断开,断开位置可以在项目之间、项目的行之间(在多行模式下)以及项目内部。 break-*属性对弹性容器的应用与块级或内联级框相同。 本节定义了它们如何应用于弹性项目及其内容。 有关更多上下文,请参阅CSS 分片模块[CSS3-BREAK]。
以下断开规则将分片容器称为“页面”。 同样的规则适用于任何其他分片上下文。 (根据需要,将“页面”替换为适当的分片容器类型。) 为了可读性,本节中的术语“行”和“列”指的是弹性容器相对于分片上下文的块流方向的相对方向,而不是相对于弹性容器本身。
在此级别的弹性盒布局中,未定义分片弹性容器的精确布局。 然而,弹性容器内部的断开遵循以下规则(使用修改后的文档顺序解释):
- 在行弹性容器中,弹性项目上的break-before和break-after值会传播到弹性行。 第一行上的break-before值和最后一行上的break-after值会传播到弹性容器。
- 在列弹性容器中,第一个项目上的break-before值和最后一个项目上的break-after值会传播到弹性容器。 其他项目上的强制断开仅应用于该项目本身。
- 弹性项目内部的强制断开会有效增加其内容的大小;它不会在兄弟项目内部触发强制断开。
- 在行弹性容器中,A类断开机会发生在兄弟弹性行之间,C类断开机会发生在第一/最后一弹性行与弹性容器内容边缘之间。 在列弹性容器中,A类断开机会发生在兄弟弹性项目之间,C类断开机会发生在第一/最后一个弹性项目与弹性容器内容边缘之间。[CSS3-BREAK]
- 当弹性容器在断开后继续时,其弹性项目在分片上下文的块流方向上的可用空间将减少,减少量为前几页上弹性容器片段所占用的空间。 弹性容器片段所占用的空间是其内容框在该页面上的大小。 如果由于此调整导致可用空间变为负数,则将其设置为零。
- 如果弹性容器的第一个片段不在页面顶部,并且没有一个弹性项目适合页面上的剩余空间,则整个片段将移到下一页。
- 当一个多行列弹性容器断开时,每个片段都有自己的一“堆”弹性行,就像多列容器的每个片段都有自己的一排列框一样。
- 除了前一点强加的项目重排外,UA 应尽量减少弹性容器相对于未分片流的失真。
10.1. 示例弹性分片算法
本信息性部分展示了一个可能的弹性容器分片算法。 鼓励实现者改进该算法,并向CSS工作组提供反馈。
该算法假设分页总是仅在前进方向上进行; 因此,在下面的算法中,分页前的大部分对齐都被忽略。 高级布局引擎可能能够在跨片段时保持对齐。
- 单行列弹性容器
-
- 运行弹性布局算法(不考虑分页) 直到副尺寸确定。
- 布局尽可能多的连续弹性项目或项目片段 (至少一个或其片段), 从第一个开始, 直到页面没有更多空间 或遇到强制中断。
- 如果上一步耗尽了空间 且剩余空间为正, UA可以减少当前页面上的分配剩余空间 (减至零,但不超过), 以便为下一个不可断开的弹性项目或片段腾出空间。 否则, 不适合的项目或片段将被推到下一页。 如果剩余空间中有超过50%的片段可以放下, UA应当将其拉上,反之则推到下一页。
- 如果有任何弹性项目或片段未被上一步布局, 则重新运行弹性布局算法, 从行长度确定到副尺寸确定, 使用下一页的大小和所有内容(包括已布局的内容), 并返回上一步, 但从第一个尚未布局的项目或片段开始。
- 对于每个弹性容器片段, 从主轴对齐继续弹性布局算法,直到完成。
本算法的目的是使列方向的单行弹性容器 分页行为与块流非常相似。 为测试该目的, 带有justify-content:start且没有弹性项目的弹性容器应当与 具有相同内容、相同已使用大小和相同已使用边距的块内流子元素的分页完全相同。
- 多行列弹性容器
-
- 运行弹性布局算法考虑分页 (将弹性容器的最大行长度限制为页面剩余空间) 直到副尺寸确定。
- 布局尽可能多的弹性行 (至少一行), 直到弹性容器在副尺寸方向上没有更多空间 或遇到强制中断:
- 如果上一步没有布局所有弹性项目, 则重新运行弹性布局算法, 从行长度确定到副尺寸确定, 使用下一页的大小和仅未布局的项目, 并返回上一步, 但从第一个未布局的项目开始。
- 对于每个弹性容器片段, 从主轴对齐继续弹性布局算法,直到完成。
如果一个弹性项目不能完全适应单个页面, 它将不会在多行列弹性容器中分页。
- 单行行弹性容器
-
- 运行整个弹性布局算法(不考虑分页), 但将任何align-self值(非flex-start或baseline)视为flex-start。
- 如果不可断开的项目不适合页面剩余空间, 且弹性容器未位于页面顶部, 则将弹性容器移至下一页 并重新开始整个弹性容器布局。
-
对于每个项目,
布局尽可能多的内容以适应页面剩余空间,
并将剩余内容分页到下一页,
重新运行弹性布局算法,
从行长度确定到主轴对齐,适应新页面大小,
使用所有内容(包括已完成的项目)。
任何完全适合先前片段的弹性项目 仍会在后续片段的主轴上占据空间。
- 对于每个弹性容器片段, 从副轴对齐继续运行弹性布局算法直到完成。 对于除第一个以外的所有片段, 将align-self和align-content视为flex-start,适用于所有项目片段和行。
- 如果任何项目, 按照其原始align-self值对齐 适应所有弹性容器片段的组合副尺寸, 它可以被移入该片段并适当对齐。
- 多行行弹性容器
-
- 运行弹性布局算法(不考虑分页), 直到副尺寸确定。
-
布局尽可能多的弹性行
(至少一行),
从第一行开始,
直到页面没有更多空间
或遇到强制中断。
如果一行不适合页面, 且该行不位于页面顶部, 则将该行移至下一页 并重新启动弹性布局算法, 仅使用该行及之后的项目。
如果弹性项目本身引起强制中断, 则重新运行弹性布局算法, 从主尺寸确定到主轴对齐, 仅使用该行及之后的项目, 但自动在断行步骤中 使引起中断的项目开始新行, 然后继续此步骤。 忽略弹性项目内部的强制中断。
- 如果上一步没有布局所有弹性项目, 则重新运行弹性布局算法, 从行长度确定到主轴对齐,适应下一页的大小, 并且仅针对未布局的项目。 返回上一步, 但从尚未布局的第一行开始。
- 对于每个弹性容器片段, 从副轴对齐继续运行弹性布局算法直到完成。
附录A:轴映射
本附录为非规范性内容。
flex-flow | 主轴 | 起点 | 终点 | 交叉轴 | 起点 | 终点 |
---|---|---|---|---|---|---|
行 + nowrap/wrap | 水平 | 左 | 右 | 垂直 | 上 | 下 |
行反转 + nowrap/wrap | 右 | 左 | ||||
行 + wrap-reverse | 左 | 右 | 下 | 上 | ||
行反转 + wrap-reverse | 右 | 左 | ||||
列 + nowrap/wrap | 垂直 | 上 | 下 | 水平 | 左 | 右 |
列反转 + nowrap/wrap | 下 | 上 | ||||
列 + wrap-reverse | 上 | 下 | 右 | 左 | ||
列反转 + wrap-reverse | 下 | 上 |
致谢
感谢以下人员的反馈和贡献:
Erik Anderson, Christian Biesinger, Tony Chang, Phil Cupp, Arron Eicholz, James Elmore, Andrew Fedoniouk, Brian Heuston, Shinichiro Hamaji, Daniel Holbert, Ben Horst, John Jansen, Brad Kemper, Kang-hao Lu, Markus Mielke, Peter Moulder, Robert O’Callahan, Christoph Päper, Ning Rogers, Peter Salas, Elliott Sprehn, Morten Stenshorne, Christian Stockwell, Ojan Vafai, Eugene Veselov, Greg Whitworth, Boris Zbarsky.
更改
本节记录了自上次发布以来的更改。
自2017年10月16日CR版本以来的更改
还可以查看评论处理意见。
- 移除了flex项block轴边距和填充选项,它们必须像块一样根据内联尺寸解决。(Issue 2085)
-
将flex项的最小内容贡献限定在其首选尺寸,并清理相关措辞,使其更精确。
flex项的主尺寸最小内容贡献是其外部最小内容尺寸和外部首选尺寸(其宽度/高度如适用)更大的那个,并受到其flex基尺寸的最大限制(如果不可增长),并/或最小限制(如果不可缩小),然后进一步受到其最小/最大主尺寸的限制。
flex项的主尺寸最大内容贡献是其外部最大内容尺寸和外部
指定首选尺寸更大的那个,并受到其flex基尺寸的最大限制(如果不可增长)和/或最小限制(如果不可缩小),然后进一步受到其最小/最大主尺寸的限制。 -
添加了一些(实际上是说明性的)内容并增加了交叉引用,以更清楚地定义flex-basis: content。
指示基于flex项的内容的自动尺寸。(通常等同于最大内容尺寸,但会进行调整以处理纵横比、固有尺寸约束和正交流;请参见详细信息)。
- 将auto关键字在min-width和min-height的定义移动到了[CSS-SIZING-3]。flex项的自动最小尺寸的定义仍保留在这里。(Issue 1920, Issue 2103)
- 更改了在auto关键字在min-width和min-height中的计算方式,使其始终计算为其自身。(Issue 2230, Issue 2248)
- 澄清了最小/最大尺寸的限定是根据最小/最大尺寸属性的已用值进行的。(Issue 2442)
-
澄清了断点传播不会影响计算值,并使用顺序修改后的文档顺序进行解释。(Issue 2614)
在此Flexible Box Layout级别中未定义分段flex容器的确切布局。然而,flex容器内的断点受以下规则影响:(使用顺序修改后的文档顺序解释):
- 在行方向的flex容器中,flex项上的break-before和break-after值传播到flex行上。
注意:断点传播(如text-decoration传播)不会影响计算值。
- 在行方向的flex容器中,flex项上的break-before和break-after值传播到flex行上。
-
澄清了如果自动最小尺寸直接解析为零而不是内容基的最小尺寸,它不会导致不确定性。
为了计算元素的固有尺寸(例如元素的最小内容尺寸),内容基的最小尺寸会导致该轴上的元素尺寸变为不确定。
- 对自动最小尺寸进行了编辑性改进。(Issue 2385)
- 一些小的编辑修正和澄清,包括更新词汇以与其他CSS模块的更新保持一致。
自2016年5月26日CR版本以来的更改
还可以查看评论处理意见。
实质性更改和错误修复
-
为了使flex因子能够真正代表flex项尺寸的绝对比例,移除了用于查找项的flex基尺寸时对内容框尺寸为零的下限。(Issue 316)
在确定flex基尺寸时,忽略项的最小和最大主尺寸属性(不进行限制)。此外,当应用box-sizing时,忽略对内容框尺寸为零的尺寸计算。
修复最小/最大值违规问题。通过其最小和最大主尺寸属性限制每个非冻结项的目标主尺寸并将其内容框尺寸限制为零。
-
为防止在自适应容器中的空flex项即使指定了尺寸也会收缩为零,现在在计算其最大内容贡献时考虑指定尺寸。(Issue 1435)
- 由于至少有两个实现允许在具有不确定flex基础的flex项中解析百分比,因此删除了需要明确flex基础的条件。(Issue 1679)
-
为了便于实现,auto值的align-self现在始终计算为自身。(Issue 440)
计算值: 与指定值相同 绝对定位元素上的auto值始终计算为自身。
- 修改正交流中的flex项和没有基线的flex项,使它们都从项的边框框合成对齐基线。(Issue 373)
-
修复了在定义交叉轴基线集时的主轴/交叉轴错误。(Issue 792)
否则,flex容器没有第一个/最后一个交叉轴基线集。
- 恢复了有关作为flex项的表格的意外删除文本。(Issue 547)
- 澄清了自动边距在计算绝对定位的flex容器子项静态位置时被视为零。(Issue 665)
- 当在最大主尺寸属性中进行限制时,请确保通过最小主尺寸属性进行下限处理。(Issue 361)
- 添加了缺少的编辑,使order不适用于flex容器的绝对定位子项。(Issue 1439)
- 在确定flex容器的第一个/最后一个基线时考虑了flex方向。(Issue 995)
- 将单个flex行的align-content: space-between处理定义为与start相同。(Issue 718)
- 修复了轴映射表中的错误。(Issue 205)
- 恢复了定义没有指定尺寸或纵横比的框的自动最小尺寸的文本。(Issue 671)
澄清
- 确保主尺寸和交叉尺寸不仅为flex容器定义,也为flex项定义。(Issue 981)
-
调整了关于空间导航的注释中的最终澄清句子。(Issue 1677)
用户代理,包括浏览器、辅助技术和扩展,可能提供空间导航功能。此部分并不排除在此类空间导航模式下确定元素顺序时考虑顺序属性;事实上,考虑此功能是必要的。 但顺序并不是这种空间导航功能需要考虑的唯一(甚至不是主要的)CSS属性。一个好的空间导航功能还需要考虑所有修改空间关系的CSS布局特性。
- 各种琐碎的编辑改进。
自2016年3月1日CR版本以来的更改
还可以查看评论处理意见。
实质性更改和错误修复
-
定义了在计算固有自动最小尺寸时如何处理百分比。(Issue 3)
为了计算元素的固有尺寸(例如元素的最小内容尺寸),此值会导致元素在该轴上的尺寸变得不确定。
- 切换确定的和不确定的引用,以引用[CSS-SIZING-3]中的定义,而不是在此模块中定义它们。(Issue 10)
- Flexbox的绝对定位子项不再响应顺序属性。(Issue 12)
- 更新了§8.5 Flex容器基线以考虑基线集和最后基线对齐。(Issue 13)
澄清
-
在 §9.8 定义和未定义的尺寸
中交叉引用了另一个确定性的情况。(Issue
2)
一旦弹性行的交叉尺寸确定,自动尺寸弹性容器中的项在布局目的上也被视为确定尺寸;参见 步骤 11。
-
改进了解决不了的百分比 flex-basis 值如何转换为 content 的措辞。(Issue 6)
除了 auto 和 content 外的所有值,flex-basis 的解析与横向书写模式中的 width 解析方式相同 [CSS21],除非值会解析为 auto,在这种情况下,它将解析为 content 用于 flex-basis。 例如,flex-basis 的百分比值是基于其弹性容器的包含块进行解析的;如果该包含块的大小是未定义的,flex-basis 的使用值为 content。
-
澄清了具有确定性 definite flex-basis 的非弹性项目具有确定性大小。(Issue 8, Issue 11)
如果 flex 项目 的 flex-grow 和 flex-shrink 的值均为零,则该项目被视为 完全不具弹性。
具有确定性 definite flex-basis 的完全不具弹性项目,其主尺寸是确定的。
-
重新表述了 auto
值的定义,以便更易于理解。(Issue 9)
在 flex 项目 的主轴 main axis 上,当其 overflow 为 visible 时,指定的是 自动最小尺寸。
通常,自动最小尺寸 定义如下:
- 略微重新措辞以使关于确定绝对定位子项静态位置的部分更加清晰。
- 调整了“可动画”行的格式,以便更清晰地说明关键字的动画处理。
- 其他琐碎的编辑改进。
自2015年5月14日 LCWD以来的更改
还提供了评论处理。
实质性更改和错误修复
-
撤销 flex 速记中省略的 flex-basis 回到 0,因为这是解决固有尺寸问题的临时方案,不再需要(且在实现 §9.9
固有尺寸时会产生不良结果)。(Issue 13)
在 flex 速记中省略时,其指定值为 0%。
-
更改了 flex 项目确定,使其直接作用于每个元素,而不是其匿名包装框(如果有的话)。(Issue 6)
某些 display 的值会触发在原始盒子周围生成匿名盒子。最外层盒子——即 flex 容器 的直接子级——成为 flex 项目。
注意:某些 display 的值通常会触发在原始盒子周围生成匿名盒子。如果此类盒子是 flex 项目,则会先将其块化,因此不会发生匿名盒子创建。例如,两个连续的 flex 项目 的 display: table-cell 将成为两个独立的 display: block 的 flex 项目,而不是被包装到单个匿名表中。
-
定义了当以百分比调整任何内容尺寸时,必须参考其
min-width: auto 值。(Issue 3)
为了防止尺寸循环,auto 的 min-height 和 max-height 不会影响其内容的百分比大小。例如,父元素为 height: 120em; min-height: auto 的百分比高度块,将始终以 height: 120em 为基础进行尺寸调整。尽管在某些情况下可能需要额外的布局传递来重新解决百分比,但 auto 值的 min-width 和 min-height(如 min-content、max-content 和 fit-content)不会阻止在项目中解决百分比大小。
-
修正内在尺寸规则以处理不可扩展的项目。
(问题 1)
主尺寸 最小内容/最大内容贡献 的 flex 项目 是其外部
假设的主尺寸 当在 最小内容/最大内容限制下进行尺寸调整时(分别)主尺寸 最小内容/最大内容贡献 的 flex 项目 是其 外部 最小内容/最大内容尺寸, 受其 flex 基本尺寸作为最大值的限制(如果它不能扩展) 或最小值的限制(如果它不能收缩), 然后再进一步受其 最小/最大主尺寸属性的限制。 。 -
更正 弹性容器 主轴内在尺寸的错误。
(问题 1)
-
更正 弹性容器 交叉轴内在尺寸的错误,并为多行列弹性容器指定常用的最小内容尺寸启发式。
(问题 12)
弹性容器的 最小内容 交叉尺寸 和 最大内容 交叉尺寸 是弹性容器在给定的主轴空间和无限可用的交叉轴空间下,执行布局后的交叉尺寸。
一个 单行 弹性容器 的 最小内容/最大内容 交叉尺寸 是其 弹性项目 的最大 最小内容贡献/最大内容贡献(分别)。
对于一个 多行 弹性容器,其 最小内容/最大内容 交叉尺寸 是在根据 交叉轴 最小内容约束/最大内容约束(分别)调整弹性容器的尺寸后,各弹性行交叉尺寸的总和。 然而,如果 弹性容器 是 flex-flow: column wrap;,则首先找到 最小内容/最大内容 交叉尺寸 在 弹性项目 中的最大贡献,然后将该尺寸作为每个 弹性项目 在布局过程中交叉轴中的 可用空间。
这种对 列换行 弹性容器 的启发式方法给出了一个合理的弹性容器尺寸近似值, 每个弹性项目的尺寸为 min(项目自身的最大内容,所有项目中的最大最小内容), 每个 弹性行 不大于其最大的 弹性项目。 在某些情况下,它并不是 完美 的, 但完全正确地处理是非常昂贵的,而这个方法的效果相当好。
-
为作者工具添加明确的符合性标准,以保持表现和 DOM 顺序同步,
除非作者明确表示希望将它们不同步。
(问题 8)
为了在所有展示模式下保持作者意图的顺序, 作者工具——包括所见即所得编辑器以及基于 Web 的作者辅助工具——
必须重新排序底层文档源, 而不是使用 order 进行重新排序, 除非作者明确表示底层文档顺序(决定语音和导航顺序)应与视觉顺序 不同步。 -
定义了在绝对定位元素上,align-self 或 justify-self 的值为 auto 时计算为其自身,以与 [CSS-ALIGN-3] 中这些属性的未来扩展保持一致。
(问题 5)
在绝对定位的元素上,auto 的值计算为其自身。在所有其他元素上,
Aauto 的 align-self 值计算为元素父级的 align-items 值,如果元素没有父级,则为 stretch。 -
撤销将百分比边距和内边距相对于它们自己的轴的更改;而是允许两种行为。
(问题 11,问题 16)
弹性项目上的百分比边距和内边距始终相对于其各自的尺寸解析;与块级元素不同,它们并不总是相对于其包含块的内联尺寸解析。
弹性项目上的百分比边距和内边距可以相对于以下之一解析:
- 它们自己的轴(左/右百分比相对于宽度解析,上/下相对于高度解析),或者,
- 内联轴(左/右/上/下百分比都相对于宽度解析)
用户代理必须在这两种行为中选择一种。
注意:这种差异很糟糕,但它准确地反映了当前的情况(实现之间没有共识,CSSWG 内部也没有共识)。CSSWG 的意图是浏览器将会在其中一种行为上达成一致,届时规范将被修改以要求此行为。
作者应完全避免在 弹性项目 的内边距或边距中使用百分比,因为在不同的浏览器中会有不同的行为。
-
处理调整弹性项目尺寸中的最小/最大约束。
-
修正弹性容器分割规则中的否定:先前的定义在所有情况下都暗示了 break-inside: avoid 的行为。
(问题 5)
-
如果弹性容器的第一个片段不在页面的顶部,并且其弹性项目中
一些没有一个不适合页面剩余的空间,则整个片段将移动到下一页。
-
如果弹性容器的第一个片段不在页面的顶部,并且其弹性项目中
澄清
- 各种小的编辑改进和对示例中的错误修复。
自2014年9月25日 LCWD 以来的更改
也提供了评论处理结果。
实质性更改和错误修复
- 将 flex-basis: auto 恢复到其原始含义。 添加了 flex-basis: content 关键字,以明确指定基于内容的自动尺寸。 (问题 10)
-
将 align-content 的适用性取决于可换行性,而不是结果的弹性行数。
(问题 4)
当弹性容器有多行时,在一个 多行 弹性容器 中(即使只有一行), 每一行的 交叉尺寸是所需的最小尺寸[...]当一个弹性容器(即使是多行的)只有一行时,在一个 单行 弹性容器 中, 该行的 交叉尺寸就是弹性容器的 交叉尺寸, 而 align-content 没有作用。只有
具有多行的弹性容器多行 弹性容器 在交叉轴上才有可供对齐的空闲空间, 因为在只有一行的弹性容器中单行弹性容器中 唯一的行会自动拉伸以填充空间。如果弹性容器
只有一个弹性行(即使它是一个多行 弹性容器)是一个 单行容器 并且具有确定的交叉尺寸, 则弹性行的交叉尺寸为弹性容器的内部交叉尺寸。如果弹性容器
只有一个弹性行(即使它是一个多行弹性容器),是 单行的, 则将该行的交叉尺寸限制在容器的计算最小和最大交叉尺寸属性之间。 -
删除了断言强制换行行为的文本,替换为对分割部分的引用。
这解决了规范中的冲突。
(问题 18)
一个接一个地收集连续的项目, 直到下一个收集的项目第一次无法适应弹性容器的内部主尺寸, ( 或遇到强制断点 ,见 §10 弹性布局的分割) 。 [...]
在 CSS2.1 的 page-break-before/page-break-after [CSS21] 或 CSS3 的 break-before/break-after [CSS3-BREAK] 属性指定分割断点的任何地方都会强制中断。 -
将 弹性收缩因子 更改为乘以内部(非外部)弹性基准尺寸。
(问题 9)
对于行上每个未冻结的项目, 将其弹性收缩因子乘以其
外部内部 弹性基准尺寸, 并将其记为其 缩放弹性收缩因子。 -
在“neither”中添加缺失的“n”...
(问题 6)
如果 弹性项目的 交叉尺寸属性 计算为 auto, 并且 neither 的 交叉轴 边距为 auto, 则 弹性项目被 拉伸。
-
指定弹性容器的主尺寸也必须是确定的,以便弹性项目的弹性主尺寸为确定的。(问题 20)
[如果]... 弹性项目 具有确定的 弹性基础, 并且 弹性容器 具有确定的 主尺寸, 则 弹性项目的 主尺寸必须被视为确定的...
-
删除了为定义指定尺寸而要求弹性基础为 content 的要求。
如果指定尺寸小于固有尺寸,则应始终优先使用指定尺寸。
这对于维护作者的预期尤其重要,
例如
<img src="…" width=40 height=40 title="100x100 image">
。 (问题 25)如果项目的
计算的 flex-basis 为 content 并且其计算的 主尺寸属性 是确定的, 则 指定尺寸为该尺寸 - 删除了在 弹性项目 块化之前(针对类似于 display: table-cell 的内容)需要创建匿名块的要求。 (相反,所有子元素现在立即块化,与绝对定位/浮动行为一致。)
澄清
-
澄清 flex 基本大小 未受限制。
(问题 21)
在确定 flex 基本大小 时, 忽略项目的最小和最大主尺寸属性 (没有发生限制)。
- 恢复了表包装盒的规范状态说明; 它在先前的草案中被意外更改。 (问题 2)
- 删除了对 display 属性长写形式的引用, 因为它们将在 CSS Display Level 3 中被删除。
-
修改措辞以避免暗示不必要的布局过程。
(问题 22)
否则,
布局调整大小 项目到 可用空间,使用其使用的 flex 基础 替代其 主尺寸, 并将 content 值视为 max-content。 - 将“限制大小”重命名为“指定大小”在 height: auto 定义中。
- 各种细微修复。
自 2014年3月25日以来的更改
也提供了 评论处理结果。
实质性更改和错误修复
以下是自 2014年3月25日最后一次工作草案 以来的重大更改
-
修正了 min-width:
auto 定义中的错误(缺少否定,未指定轴)。
(问题 11, 18, 30)
-
扩展并重写了 min-width:
auto 的定义,以添加对具有内在比例项目的特殊处理。
(问题 16 和 28)
对于 flex 项目 其 overflow 不是 visible, 下表给出了最小尺寸:[查看表格]
此关键词指定为较小的最小尺寸:- min-content 尺寸,或
- 计算的 宽度/高度,如果该值是 确定的。
-
调整了 min-width: auto,使其仅在 flex 基础从主尺寸属性中获取时,应用计算的主尺寸作为最小值。
(问题 19)
…定义为如果 项目的计算的 flex 基础为 auto,且 其计算的主尺寸属性是确定的…
-
定义了框的 min-width: auto 所施加的任何尺寸调整在对其内容进行百分比大小调整时不予考虑。
(问题 27)
此更改稍后被 相反的定义 撤销。
为了防止循环调整尺寸, auto 值的 min-height 和 max-height 不会影响对框内容进行百分比大小调整时的尺寸计算。 例如,一个其 flex 项目父元素的 高度为 120em;min-height: auto 的百分比高度块将基于 高度:120em 来调整自身大小,而不会考虑 min-height 对 flex 项目已用尺寸的影响。
- 引入了额外的 main-size 关键字到 flex-basis 中,以便明确指定“从主尺寸属性中查找”和“自动调整大小”行为。 (问题 20) 这一更改随后被替代方案撤销,该替代方案通过引入 content 关键字来解决相同的问题。
-
定义了具有 flex 项目 的 确定的 flex 基础 在 主轴 中也是确定的,
即使项目本身是灵活的,也允许解决百分比大小的子元素。
(问题 26)
如果百分比将根据 flex 项目的主尺寸进行解析, 并且 flex 项目具有确定的 flex 基础, 则主尺寸必须在解析百分比时被视为确定的, 并且百分比必须根据 flex 项目的已调整主尺寸进行解析 (即,在完成下面的 flex 容器布局算法之后, 并且 flex 项目已获得其最终尺寸)。
-
将单行 flexbox 的行 交叉尺寸 限制为容器的最小/最大尺寸,
即使容器的尺寸是不确定的。
(问题 9)
-
使用的 flex 行 的交叉尺寸
是在前两步中找到的最大数值
和零之间的较大值。
如果 flex 容器只有一个 flex 行 (即使它是多行 flex 容器), 那么将行的交叉尺寸限制在容器计算的最小和最大交叉尺寸之间。 请注意,如果 CSS 2.1 的最小/最大宽度/高度定义更广泛适用, 这种行为将自动得出。
-
使用的 flex 行 的交叉尺寸
是在前两步中找到的最大数值
和零之间的较大值。
- 修复了 解决灵活长度 部分中的各种错误 (见 2014年3月的重写,创建了 flex: 0 和 flex: 1 之间的连续性) 并恢复了旧的候选推荐标准的编辑结构。 (问题 3, 4, 8, 10, 15)
- 修正了 flex 容器的 max-content 尺寸计算 以考虑 flex 行为, 通过每个 flex 片段的归一化而不是仅仅相加 flex 项目的 max-content 尺寸。 (问题 39)
- 更新了 flex 属性,使其始终接受动画, 现在 0 和非 0 值之间的不连续性已被 修复。 (问题 5)
澄清
以下是自 2014年3月25日最后一次工作草案 以来的重大更改
-
澄清了如何计算 flex 容器中绝对定位子元素的静态位置,
通过引入更紧密结合 CSS2.1 概念和术语的解释。
(问题 12)
其flex 容器中绝对定位子元素的 静态位置通过首先在没有绝对定位子元素的情况下进行完整的 flex 布局来计算, 然后定位每个绝对定位的子元素确定为该子元素被定位 好像它是 flex 容器中的唯一 flex 项目, 假设子元素和 flex 容器都是使用它们的已用尺寸的固定大小框。换句话说,flex 容器中绝对定位子元素的静态位置在 flex 布局之后确定, 通过将子元素的 静态位置矩形 设置为 flex 容器的内容框, 然后根据 flex 容器的 justify-content 值和子元素本身的 align-self 值来对齐绝对定位的子元素。
-
澄清了 order 属性对 flex 容器 中绝对定位子元素的应用。
(请注意,此行为在稍后 被撤销。)
flex 容器中的绝对定位子元素不参与 flex 布局
超出重新排序步骤。 但是,它参与重新排序步骤(参见 order), 这会影响其绘制顺序。order 属性控制
flex 项目flex 容器的子元素 在其 flex 容器中出现的顺序…除非未来的规范另有规定, 此属性对非
flex 项目flex 容器的子元素 的框没有影响。注意:flex 容器中的绝对定位子元素不参与 flex 布局,但与任何 flex 项目子元素一起重新排序。
-
澄清了 stretched flex 项目的定义,
以便用于特殊行为(如确定性)。
(问题 25)
如果 flex 项目的 交叉尺寸 属性计算为 auto, 并且任何一个交叉轴的边距为 auto,则该 flex 项目被拉伸。
其已使用的值…
自 2012年9月18日候选推荐标准以来的更改
也提供了 评论处理结果。
实质性更改和错误修复
以下是自 2012年9月18日候选推荐标准 以来的重大更改:
-
更改了新的 auto 初始值在 min-width/min-height 中的行为
- 考虑到 overflow 是否为 visible,因为当显式处理 overflow 时,强制足够的大小以显示所有内容是令人困惑且不必要的。
- 考虑到指定的 宽度/高度, 这样隐含的最小值永远不会大于指定的大小。
- 在 flex 项目上计算为自身(而不是 min-content),因为由于上述更改,它们不再等效。
- auto
-
当用作 flex 项目的最小主尺寸属性的值时, 此关键字表示最小的 min-content 尺寸, 以确保项目足够大以容纳其内容。
预计当规范足够成熟时,此计算将转换为 min-content 关键字。
对于 flex 项目 其 overflow 不是 visible, 此关键字指定最小尺寸为以下两者中较小的一个:
- min-content 尺寸,或
- 计算的 宽度/高度,如果该值是 确定的。
-
规定了 flex 项目的百分比边距/填充是相对于其各自的尺寸计算的,
而不是像块级元素那样相对于包含块的内联尺寸计算。
(问题 16)
flex 项目的百分比边距和填充总是相对于其各自的尺寸计算; 与块级元素不同,它们不总是相对于其包含块的内联尺寸计算。
-
将单行 flex 容器的确定性尺寸传递给所有被拉伸的项目。
(问题 3)
作为处理被拉伸的 flex 项目 的特殊情况, 如果一个 单行 flex 容器 具有确定的 交叉尺寸, 则任何带有 align-self: stretch 的 flex 项目 的外部 交叉尺寸 是 flex 容器的内部 交叉尺寸 (被限制在 flex 项目 的最小和最大 交叉尺寸 之间) 并且被认为是 确定的。
-
允许通过重新布局来解析被拉伸的自动高度 flex 项目内的百分比值。
(问题 3)
如果 flex 项目具有 align-self: stretch,则为其内容重新布局, 将此已使用的尺寸视为其确定的 交叉尺寸,以便可以解析百分比大小的子元素。
注意:此步骤不会影响 flex 项目的主尺寸, 即使它具有固有的宽高比。
-
允许固有的宽高比用于 主尺寸计算。 (问题 8)
如果 flex 项目具有 ...
-
定义了 假设的主尺寸,当 主尺寸 依赖于 交叉尺寸。
(问题 23)
如果需要 交叉尺寸 来确定 主尺寸 (例如,当 flex 项目 的 主尺寸 处于其块级轴上时) 并且 flex 项目 的 交叉尺寸 是 auto 且不是 确定的, 则在此计算中将 fit-content 作为 flex 项目 的 交叉尺寸。
-
定义了 flex
容器的固有尺寸。
使用其主尺寸属性确定 flex 容器的主尺寸。
在此计算中,flex 容器的最小内容主尺寸是其项目的最小内容尺寸贡献的最大值, 而 flex 容器的最大内容主尺寸是其项目的最大内容尺寸贡献的总和。 项目的最小内容/最大内容主尺寸贡献是 它在最小内容/最大内容约束下进行尺寸调整时的外部假设主尺寸(分别)。对于此计算,flex 项目的 ‘auto’ 边距被视为 ‘0’。一个 最大内容 主尺寸 的 flex 容器 是 flex 容器的项目在 主轴 上的 最大内容贡献 之和。 一个 最小内容 主尺寸 的 单行 flex 容器 是 flex 容器的项目在 主轴 上的 最小内容贡献 之和; 对于一个 多行 容器, 它是这些贡献中最大的一个。
一个 最小内容 交叉尺寸 和 最大内容 交叉尺寸 的 flex 容器 是在将布局应用到给定的可用 主轴 空间和无限可用的 交叉轴 空间后 flex 容器的 交叉尺寸。
flex 项目的主尺寸 最小内容贡献 / 最大内容贡献 是其外部 假设的主尺寸,当在 最小内容约束 / 最大内容约束 下进行尺寸调整时(分别)。
参见 [CSS-SIZING-3] 以了解本节中的术语定义。
-
修正了 flex 行大小确定中的遗漏,
使得 单行 flexbox 如果没有确定的大小,将根据其内容进行调整。
如果 flex 容器只有一个 flex 行(即使它是一个 多行 flex 容器) 并且有一个 确定的 交叉尺寸 , 该 flex 行 的 交叉尺寸 将是 flex 容器 的内部 交叉尺寸。
-
Flex 行的尺寸底限为 0。
(问题 2)
flex 行的已使用交叉尺寸是之前两个步骤中找到的
较大最大 的数值 和 0 。 -
Flex 项目的绘制方式与内联块类似,而非块级元素。
(问题 18)
-
省略了 flex-basis 的 flex 简写部分
现在解析为 0% 而不是 0px。
因为与不确定大小相关的百分比值表现为 auto,
这使得在收缩包装的 flex 容器中有了更好的表现。
(问题 20)
在 flex 简写中省略时,其指定值为 0%
长度为零。 -
定义了无法解析的百分比
flex base size 将被视为 auto。
flex-basis 的百分比值将根据 flex 项目的包含块,即其 flex 容器进行解析, 如果包含块的大小是 不确定的, 结果是
未定义与 主尺寸 的 auto 值相同。 -
简化了 abspos 子元素的静态位置,使其与 弹性容器 一致。
(问题 6)
弹性容器的绝对定位子元素不参与弹性布局,除了重新排序步骤之外。
但是,如果 left 和 right 或 top 和 bottom 都是 auto,则这些属性的使用值根据其静态位置计算如下:
如果 left 和 right 都是 auto,则 弹性项目 必须定位,使其 main-start 或 cross-start 边缘(无论是哪个水平轴)与 静态位置 对齐。如果 top 和 bottom 都是 auto,则 弹性项目 必须定位,使其 main-start 或 cross-start 边缘(无论是哪个垂直轴)与 静态位置 对齐。
在 主轴中,
- 如果在同一 弹性行 上有后续流内 弹性项目,则 静态位置 是该 弹性项目 的外部 main-start 边缘。
- 否则,如果在同一 弹性行 上有前置流内 弹性项目,则 静态位置 是该 弹性项目 的外部 main-end 边缘。
- 否则,静态位置 由 justify-content 的值在 弹性容器 上确定,静态位置 相当于一个零大小的弹性项目。
在 交叉轴中,
- 如果有前置流内 弹性项目,则 静态位置 是该 弹性行 的 cross-start 边缘。
- 否则,静态位置 是第一 弹性行 的 cross-start 边缘。
静态位置旨在大致匹配参与弹性布局的匿名 0×0 流内 flex-start-对齐弹性项目的位置,主要区别在于由于 justify-content: space-around 或 justify-content: space-between 引起的填充空间在假想项目周围被抑制:如果在它之后有真实项目,则在它与下一个项目之间,否则在它与前一个项目(如果有)之间。
其静态位置通过首先进行完整的弹性布局而没有绝对定位的子元素来计算,然后将每个绝对定位的子元素定位为其所在 弹性容器 中的唯一 弹性项目,假设子元素和 弹性容器 都是固定大小的框,按照其使用大小定位。
例如,默认情况下,绝对定位的子元素的静态位置将其对齐到主轴起始点/交叉轴起始点角,与在 justify-content 和 align-content 上的默认值相对应。 然而,在 弹性容器 上设置 justify-content:center 会在主轴上将其居中。 - 更改了解决弹性长度的算法,使其在弹性因子的总和接近零时行为连续。(对于总和≥1没有变化。) (问题 30) 用这个部分替换了这个部分。
澄清
还进行了以下重要的澄清:
-
弹性容器的绝对定位子元素不再被称为“弹性项目”(为了避免术语混淆)。(??)
名称: order 适用于: 弹性项目 和 弹性容器 的绝对定位子元素 根据其 order 重新排序弹性项目 以及弹性容器的绝对定位子元素。
-
澄清了float 仍然会影响计算的 display(这可能会影响弹性项目确定之前运行的框修正规则)。(问题 7)
float 和 clear 对 弹性项目 没有影响 ,并且不会将其脱离文档流。但是,float 属性仍然可以通过影响 display 属性的计算值来影响框的生成。
-
澄清了“空白”的含义。(问题 26)
但是,包含仅有空白的匿名弹性项目 (即可以被white-space属性影响的字符)不会被渲染,就好像它是 display:none 一样。
- 澄清了表格匿名框的生成发生在内部表格元素的计算值转换之前。
-
澄清了弹性项目确定与 display-inside / display-outside(在display中定义的新长手)之间的交互。
如果生成 弹性容器 的元素的流内子元素的指定 display-outside 为 inline-level,它会计算为 block-level。(这实际上将任何内联 display 值转换为其块级等效值。)
- 澄清了overflow 适用于弹性容器。
- 澄清了::first-line 和::first-letter伪元素不适用于弹性容器(因为它们不是块容器)。
-
澄清了stretch 检查交叉大小属性的计算值是否为auto,这意味着那些由于未针对确定大小解决的百分比交叉大小不会被拉伸。(问题 5)
确定每个弹性项目的使用交叉大小。 如果弹性项目具有 align-self: stretch, 且其 计算的交叉大小属性为 auto,并且...
-
澄清了用于确定弹性容器主尺寸的格式化上下文规则。
使用格式化上下文中的规则 确定弹性容器的主尺寸
其主尺寸属性。 - 澄清了在绘制时使用修改后的文档顺序,而不是原始文档顺序。 (这在order部分中已经说明,但未在专门关于绘制顺序的部分中说明。)
-
澄清了如何精确处理负大小的弹性项目和行末的零大小项目的换行。(问题 1)
否则,从第一个未收集的项目开始,逐个收集 连续的项目,直到第一次收集的下一个项目不再适合弹性容器的内部主尺寸,或遇到强制换行。如果第一个未收集的项目不适合,则只将其收集到行中
尽可能多地收集连续的弹性项目,直到它们适合弹性容器的内部主尺寸,或遇到强制换行(但至少收集一个)。请注意,
零主尺寸的项目不会启动行,除非它们是弹性容器中的第一个项目,或者之前有强制换行。“尽可能多地收集”这一行将它们零大小的弹性项目收集到上一行的末尾,即使最后一个非零项目刚好“填满”了这一行。 -
澄清了弹性容器的交叉尺寸仍然受到其最小/最大属性的约束。(问题 24)
11. 隐私和安全考虑
Flexbox 没有引入新的隐私泄露或安全问题,除了“正确实现它”。