CSS弹性盒布局模块 第1级

W3C候选推荐草案,

关于本文档的更多详情
此版本:
https://www.w3.org/TR/2025/CRD-css-flexbox-1-20251014/
最新发布版本:
https://www.w3.org/TR/css-flexbox-1/
编辑草稿:
https://drafts.csswg.org/css-flexbox/
历史记录:
https://www.w3.org/standards/history/css-flexbox-1/
实现报告:
https://wpt.fyi/results/css/css-flexbox
反馈:
CSSWG问题库
规范内问题
编辑者:
Tab Atkins Jr. (Google)
Elika J. Etemad / fantasai (Apple)
(Microsoft)
前编辑者:
(Microsoft Corporation)
L. David Baron (Mozilla)
(Mozilla Corporation)
(前Opera Software)
(前Netscape Corporation)
建议对本规范进行编辑:
GitHub 编辑器
问题列表:
https://drafts.csswg.org/css-flexbox-1/issues
测试套件:
https://wpt.fyi/results/css/css-flexbox/

摘要

本规范描述了一种针对用户界面设计优化的 CSS 盒模型。在弹性布局模型中,弹性容器的子元素可以按照任何方向进行布局,并且可以“弹性”地调整它们的尺寸,不论是通过扩展填充未使用空间,还是通过收缩避免溢出父容器。子元素的水平和垂直对齐都可以轻松操作。这些盒子的嵌套(水平嵌套垂直,或垂直嵌套水平)可以用于构建二维布局。

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

本文档状态

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

本文档由 CSS 工作组 作为 候选推荐草案,采用了 推荐流程。 发布为候选推荐并不代表 W3C 及其成员的认可。 候选推荐草案整合了工作组计划在后续候选推荐快照中包含的前一版本的变更。

本文档为草稿,可能随时被更新、替换或废止。 不应将本文件作为正式引用,仅作为正在进行的工作。

请通过 在 GitHub 提交问题(推荐),标题中包含规范代码 “css-flexbox”,格式如下: “[css-flexbox] …评论摘要…”。 所有问题和评论都会被 存档。 或者,也可以发送反馈到(存档)公共邮件列表 www-style@w3.org

本文档受 2025年8月18日 W3C 流程文件 管理。

本文档由依据 W3C 专利政策 运营的工作组制作。 W3C 维护着与工作组交付物相关的 专利披露公开列表; 该页面也包含披露专利的说明。 如果个人明确知晓某专利且认为其包含 必要权利要求, 必须根据 W3C 专利政策第6节 进行披露。

1. 介绍

本节非规范性内容。

CSS 2.1 定义了四种布局模式——根据盒子与其兄弟和祖先盒子的关系确定盒子的尺寸和位置的算法:

本模块引入了一种新的布局模式,弹性布局,用于更加复杂的应用和网页布局。

1.1. 概述

本节非规范性内容。

弹性布局在表面上与块布局类似。 它缺少许多块布局中用于文本或文档的复杂属性,比如 浮动多栏。 但弹性布局获得了简单且强大的工具, 可用于分配空间和对齐内容,这也正是 Web 应用和复杂网页常常需要的。 一个弹性容器的内容:

下面是一个目录示例,每个商品有标题、图片、描述和购买按钮。 设计师希望每一项整体尺寸一致,图片在文本上方, 并且无论描述长度如何,购买按钮都要底部对齐。 弹性布局让这些设计需求变得简单:
#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>如果你的预算有限,这是你能买到的最好的电脑。
    <ul>
      <li>电脑
      <li>显示器
      <li>键盘
      <li>鼠标
    </ul>
    <img src="images/computer.jpg"
         alt="你将获得:一台白色电脑和配套外设。">
    <button>立即购买</button>
  </section>
  <section class="sale-item"></section></section>
你将获得:一台白色电脑和配套键盘显示器。

电脑入门套装

如果你的预算有限,这是你能买到的最好的电脑。

  • 电脑
  • 显示器
  • 键盘
  • 鼠标
你将获得:漂亮的ASCII艺术。

打印机

只能打印 ASCII 艺术。

  • 不含纸张和墨水。
上述代码的示例渲染效果。

1.2. 模块交互

本模块扩展了 display 属性 [CSS2], 增加了新的块级和内联级 display 类型, 并定义了一种新的格式化上下文,以及用于控制其布局的属性。 本模块定义的属性均不适用于 ::first-line::first-letter 伪元素。

CSS 盒对齐模块扩展并替代了此处引入的对齐属性定义 (justify-content, align-items, align-self, align-content) 。

测试

1.3. 值定义

本规范采用 CSS 属性定义约定 [CSS2], 并使用 值定义语法 [CSS-VALUES-3]。 本规范未定义的值类型在 CSS Values & Units [CSS-VALUES-3] 中定义。 与其他 CSS 模块结合时,这些值类型定义可能会扩展。

除了各自定义中列出的属性专用值外, 本规范定义的所有属性也接受 CSS 全局关键字 作为属性值。 为便于阅读未一一列出。

2. 弹性布局盒模型及术语

弹性容器是由 display 属性计算为 flexinline-flex 的元素生成的盒。 弹性容器的普通流内子元素称为 弹性项目,并使用弹性布局模型进行布局。

与偏向于 块和内联流向 的块和内联布局不同, 弹性布局偏向于 弹性方向。 为便于讨论弹性布局, 本节定义了一组弹性流向相关术语。 flex-flow 的值和 书写模式决定了这些术语如何映射到物理方向(上/右/下/左)、轴线(垂直/水平)和尺寸(宽度/高度)。

图示在 row 弹性容器上各种方向和尺寸术语的应用。
主轴
主维度
主轴是弹性容器内弹性项目布局的主要轴线。 它沿着主维度延伸。
主起点
主终点
弹性项目在容器内从 主起点边开始,依次放置到 主终点边。
主尺寸
主尺寸属性
主尺寸指的是 弹性容器弹性项目宽度高度, 取决于哪个位于 主轴方向。 它的 主尺寸属性 是其 widthheight 属性, 取决于哪个位于 主轴方向。 同理,其 最小最大主尺寸属性 分别是 min-width/max-widthmin-height/max-height 属性, 取决于哪个位于 主轴方向, 并决定其 最小/最大主尺寸

弹性布局中, 主尺寸flex 属性控制, 而不是直接由 主尺寸属性控制。

注意:这意味着任何对弹性项目在 主轴方向上的已用尺寸(widthheightinline sizeblock size) 的引用都指其弹性伸缩后的 主尺寸

交叉轴
交叉维度
主轴 垂直的轴称为 交叉轴, 沿着 交叉维度 延伸。
交叉起点
交叉终点
弹性行交叉起点边开始填充并放入容器, 依次到 交叉终点边。
交叉尺寸
交叉尺寸属性
交叉尺寸弹性容器弹性项目宽度高度, 取决于其所在的 交叉维度。 其 交叉尺寸属性widthheight 属性, 取决于 交叉维度。 同理,最小最大交叉尺寸属性min-width/max-widthmin-height/max-height 属性, 取决于 交叉维度, 决定其 最小/最大交叉尺寸

本规范用到的其他尺寸术语,详见 CSS 内在与外在尺寸[CSS-SIZING-3]

测试

3. 弹性容器:flexinline-flex display 属性值

名称: display
新值: flex | inline-flex
测试
flex
该值会使元素生成一个 弹性容器 盒, 当其处于 流式布局 时,该盒为 块级
测试
inline-flex
该值会使元素生成一个 弹性容器 盒, 当其处于 流式布局 时,该盒为 内联级
测试

弹性容器为其内容建立了一个新的 弹性格式化上下文。 这与建立块格式化上下文类似,只是使用弹性布局而不是块布局。 例如,浮动不会侵入弹性容器, 并且弹性容器的外边距不会与其内容的外边距折叠。 弹性容器为其内容形成包含块, 和块容器完全一样[CSS2] overflow 属性适用于弹性容器

测试

弹性容器不是块容器,因此一些基于块布局假设设计的属性在弹性布局环境下并不适用。尤其:

测试

如果元素指定的display 属性为 inline-flex, 那么在某些情况下其display属性会被计算为 flexCSS 2.1 第9.7节中的表格会添加一行, 其中 "Specified Value" 列为 inline-flex, "Computed Value" 列为 flex

4. 弹性项目

简单来说,弹性项目弹性容器流内内容所生成的盒子。

每个弹性容器的流内子元素都会成为 弹性项目, 每个子文本序列会被包裹在一个匿名 块容器 弹性项目中。 但是,如果整个文本序列仅包含 文档空白字符(即能被white-space属性影响的字符), 则不会渲染(就像其文本节点被设置为display:none一样)。

测试

弹性项目的示例:

<div style="display:flex">

    <!-- 弹性项目:块级子元素 -->
    <div id="item1">block</div>

    <!-- 弹性项目:浮动元素,浮动会被忽略 -->
    <div id="item2" style="float: left;">float</div>

    <!-- 弹性项目:匿名块盒包裹内联内容 -->
    anonymous item 3

    <!-- 弹性项目:内联子元素 -->
    <span>
        item 4
        <!-- 弹性项目不会在块元素周围分割 -->
        <q style="display: block" id=not-an-item>item 4</q>
        item 4
    </span>
</div>
根据上述代码块确定的弹性项目
  1. 包含 block 的弹性项目。
  2. 包含 float 的弹性项目。
  3. (匿名且不可设置样式的)弹性项目,内容为 anonymous item 3
  4. 弹性项目,顺序包含三个块元素:
    • 包含 item 4 的匿名块。
    • 包含 item 4<q> 元素块。
    • 包含 item 4 的匿名块。

注意,元素间的空白会消失:它不会成为独立的弹性项目,即使元素间的文本确实会被包裹在匿名弹性项目中。

还要注意,匿名项目的盒子不可设置样式,因为没有元素可以分配样式规则。但其内容会继承弹性容器的样式(如字体设置)。

弹性项目 为其内容建立独立的格式化上下文。 但弹性项目自身是弹性级盒子,而不是块级盒子: 它们参与其容器的弹性格式化上下文,而不是块格式化上下文。


注意: 阅读本规范的作者可能想要跳过下面的盒子生成与静态定位细节

如果元素最近的祖先元素(跳过 display:contents 祖先)的 计算 display值为 flexinline-flex, 那么该元素自身的display值将会被 块化。 (块化值转换的详细信息见 CSS2.1§9.7 [CSS2]CSS Display 3 § 2.7 自动盒类型转换。)

注意: 即使 flexinline-flex 元素最终没有生成 弹性容器盒子, 块化仍然会发生。例如当其是 替换元素 或处于 display: none 子树中时。

注意: 某些 display 的值通常会在原始盒子外创建匿名盒。 如果这样的盒子是 弹性项目, 会先块化,因此不会再创建匿名盒。例如,两个连续的弹性项目 display: table-cell, 会变成两个独立的display: block 弹性项目,而不是被包裹为一个匿名表格。

对于 display: table 的弹性项目, 表格包装盒会成为弹性项目, 因此 align-self 属性适用于它。 任何 caption 盒的内容会参与表格包装盒的 min-content 和 max-content 尺寸计算。 但与 widthheight 一样, flex 长属性应用于表格盒时如下: 弹性项目的最终尺寸通过布局计算, 假定表格包装盒的边缘与表格盒内容边缘之间的距离都属于表格盒的 border+padding 区域, 并且表格盒就是弹性项目

测试

4.1. 绝对定位的弹性子项

由于绝对定位元素脱离了文档流,弹性容器的绝对定位子元素不会参与弹性布局。

弹性容器的绝对定位子元素的 交叉轴方向的 静态定位矩形边缘, 是该弹性容器的内容边缘静态定位矩形主轴方向的边缘, 是子元素作为唯一弹性项目时, 其外边距边缘 应该被放置的位置, 前提是子元素和弹性容器都是其已用尺寸的固定尺寸盒子。 (在此情况下,子元素的auto外边距视为零。)

测试
这意味着,如果你在 align-self: center; 设置于 弹性容器的绝对定位子元素上, 子元素的 auto 偏移会使其在弹性容器交叉轴上居中。

4.2. 弹性项目的外边距和内边距

相邻弹性项目的外边距不会折叠

弹性项目上的百分比外边距和内边距, 与块盒上的一样, 都是相对于包含块的内联尺寸计算的, 例如左右/上下百分比都相对于其包含块宽度在水平书写模式下计算。

auto 外边距会扩展以吸收相应维度的多余空间。 它们可以用于对齐,或用于将相邻弹性项目分开。 详见使用 auto 外边距进行对齐

测试

4.3. 弹性项目的Z轴排序

弹性项目的绘制方式与内联块几乎完全一致 [CSS2], 唯一不同点是使用order调整后的文档顺序, 替代原始文档顺序, 并且z-index属性值只要不是 auto, 都会创建一个堆叠上下文, 即使positionstatic(行为与positionrelative时完全一致)。

注意: 定位在弹性项目之外的后代元素,依然参与弹性项目建立的堆叠上下文。

测试

4.4. 折叠项

在弹性项目上指定 visibility:collapse 会使其成为一个折叠弹性项目, 其效果类似于表格行或表格列上的 visibility:collapse折叠弹性项目会完全从渲染中移除, 但会留下一个“支撑”,以保持弹性行的交叉轴尺寸稳定。 因此,如果弹性容器只有一行, 动态折叠或展开项目 可能会改变弹性容器主尺寸, 但保证不会影响其交叉尺寸,也不会导致页面其它布局“晃动”。 然而,折叠后会重新进行弹性行换行, 所以有多行的弹性容器的交叉尺寸可能会改变,也可能不会改变。

虽然折叠弹性项目不会被渲染, 但它们仍然会出现在格式化结构中。 因此,与display:none元素不同 [CSS2], 依赖盒子出现在格式化结构中的效果 (如计数器递增或动画与过渡的运行) 仍然会作用于折叠项。

测试
在下面的例子中,侧边栏的尺寸根据其内容自动调整。使用 visibility: collapse 动态隐藏导航侧边栏的部分内容, 不会影响侧边栏的宽度,即使最宽的项目(“Architecture”)位于折叠的分区内。
下方代码的示例实时渲染效果
鼠标悬停在左侧菜单: 每个分区会展开其子项目。 为了保持侧边栏宽度(以及主区域宽度)稳定,使用 visibility: collapse 替代 display: none。 这样侧边栏始终足够宽以容纳“Architecture”一词,即使其并不总是可见。
@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">关于</a><li id="nav-projects"><a href="#nav-projects">项目</a>
        <ul>
          <li><a href="…">艺术</a>
          <li><a href="…">建筑</a>
          <li><a href="…">音乐</a>
        </ul>
      <li id="nav-interact"><a href="#nav-interact">互动</a></ul>
  </nav>
</div>
<footer>

为了计算支撑的尺寸,弹性布局首先会在所有项目未折叠的情况下进行,然后对每个折叠弹性项目用一个支撑替换,保持该项目原本所在行的交叉尺寸。 关于 visibility:collapse 如何与弹性布局交互的规范定义,参见弹性布局算法

注意: 在任何弹性项目上使用 visibility:collapse 都会导致弹性布局算法在中途重复执行,重新运行最耗资源的步骤。 建议作者在项目不会动态折叠/展开时继续使用 display:none 隐藏项目, 因为这样对布局引擎更高效。 (由于仅在更改 visibility 时需要重复部分步骤, 所以“visibility: collapse”仍推荐用于动态场景。)

4.5. 弹性项目的自动最小尺寸

注意: auto 关键字, 表示 自动最小尺寸, 是 min-widthmin-height 属性的新初始值。 该关键字此前在本规范中定义,现在已由 CSS Sizing 模块定义。

为了给弹性项目提供更合理的默认最小尺寸, 当 弹性项目主轴方向 自动最小尺寸的已用值, 且其计算overflow值为不可滚动时, 其自动最小尺寸为基于内容的最小尺寸; 对于滚动容器,自动最小尺寸一如既往为零。

基于内容的最小尺寸 对于弹性项目,取决于该 弹性项目是否为替换元素

对于替换元素

内容尺寸建议传递尺寸建议(如有)中较小值, 再以指定尺寸建议(如有)作为上限。

对于非替换元素

内容尺寸建议传递尺寸建议(如有)中较大值, 再以指定尺寸建议(如有)作为上限。

无论哪种情况,尺寸都会被最大 主尺寸限制(如果是确定的)。

测试

内容尺寸建议指定尺寸建议传递尺寸建议在此计算中会考虑相关的 min/max/首选尺寸属性, 以确保基于内容的最小尺寸不会影响作者提供的约束, 定义如下:

指定尺寸建议
如果该项目的首选 主尺寸确定的且不是 自动的, 那么指定尺寸建议即为该尺寸。 否则无定义。
传递尺寸建议
如果该项目有首选纵横比, 且其首选 交叉尺寸确定的, 那么传递尺寸建议即为该尺寸 (如有最小最大 交叉尺寸且为确定的则加以限制), 并通过纵横比转换。 否则无定义。
内容尺寸建议
内容尺寸建议最小内容尺寸主轴方向上, 若有首选纵横比, 则通过纵横比转换,并受任何确定的 最小最大 交叉尺寸限制。
测试

注意: 基于内容的最小尺寸 是一种内在尺寸贡献, 因此CSS Sizing 3 § 5.2 内在贡献中的循环百分比条款适用。

在计算盒子的内在尺寸(如盒子的最小内容尺寸)时, 基于内容的最小尺寸 会导致该轴上的盒子尺寸变为不确定(即使其width属性指定了确定的尺寸)。 注意,这意味着针对该尺寸计算的百分比会表现为 auto

在除计算内在尺寸之外的任何用途, 基于内容的最小尺寸 (不同于显式的min-content最小尺寸)不会强制盒子的尺寸变为不确定。 但是,如果某个百分比是在应用此最小值前根据盒子尺寸解析的,则必须在应用后重新基于新尺寸解析该百分比。

注意,虽然基于内容的最小尺寸通常是合适的,并有助于防止内容重叠或溢出容器,但在某些情况下并不适用:

特别是,当弹性尺寸用于文档的主要内容区时,最好设置一个显式的相对字体的最小宽度,如min-width: 12em。 基于内容的最小宽度可能导致一个大表格或大图片将整个内容区拉伸到溢出区域,从而使文本行过长、难以阅读。

还要注意,当对内容量大的项目使用基于内容的尺寸时,布局引擎必须遍历所有内容才能找到其最小尺寸,而如果作者设置了显式最小值则无需遍历。 (不过对于内容较少的项目,这种遍历影响很小,因此不会影响性能。)

测试

5. 排序与方向

弹性容器中的内容可以以任意方向和顺序进行布局。 这让作者能够轻松实现以前需要复杂或易碎方法才能达到的效果, 比如使用 floatclear 属性的技巧。 这些功能通过 flex-directionflex-wraporder 属性来实现。

注意: 弹性布局的重新排序能力有意只影响视觉渲染, 保持语音顺序和基于源码的导航不变。 这让作者能够调整视觉呈现效果, 同时让源码顺序在非 CSS 用户代理和诸如语音或顺序导航等线性模型中保持不变。 参见 CSS Display 3 § 3.1 重新排序与可访问性 以及 弹性布局概述,其中有利用这种区分提升可访问性的示例。

作者不得使用 order*-reverse 作为 flex-flow/flex-direction 的值来替代正确的源码顺序, 因为这样会破坏文档的可访问性。

5.1. 弹性流方向:flex-direction 属性

名称: flex-direction
值: row | row-reverse | column | column-reverse
初始值: row
适用于: 弹性容器
是否继承:
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散

flex-direction 属性指定 弹性项目 在弹性容器中的放置方式, 通过设置弹性容器的 主轴 方向。 这决定了弹性项目的布局方向。

row
弹性容器的 主轴 与当前 内联轴 的方向一致。 main-startmain-end 的方向分别等同于当前 inline-startinline-end, 即 writing mode 的对应方向。
测试
row-reverse
row 相同, 只是 main-startmain-end 的方向被交换。
测试
column
弹性容器的 主轴 与当前 块轴 的方向一致。 main-startmain-end 的方向分别等同于当前 block-startblock-end, 即 writing mode 的对应方向。
测试
column-reverse
column 相同, 只是 main-startmain-end 的方向被交换。
测试

注意: 反向值不会改变盒子的顺序: 与 writing-modedirection [CSS3-WRITING-MODES] 类似, 它们只会改变流动方向。 绘制顺序、语音顺序和顺序导航的顺序都不会受到影响。

注意: 根据 justify-content 的值, flex-direction 的反向值可能会影响 既是 弹性容器 又是 滚动容器 的初始滚动位置。 参见 CSS Box Alignment 3 § 5.3 溢出对齐与滚动容器

测试

5.2. 弹性行换行:flex-wrap 属性

名称: flex-wrap
值: nowrap | wrap | wrap-reverse
初始值: nowrap
适用于: 弹性容器
是否继承:
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散

flex-wrap 属性用于控制弹性容器是 单行 还是 多行, 以及 交叉轴 的方向, 该方向决定了新行的堆叠方向。

nowrap
弹性容器为 单行
wrap
弹性容器为 多行
wrap-reverse
wrap 相同。

对于不是 wrap-reverse 的值, cross-start 方向等同于当前 inline-startblock-start 方向(取决于哪个是 交叉轴), 而 cross-end 方向则与 cross-start 方向相反。 当 flex-wrapwrap-reverse 时, cross-startcross-end 的方向会被交换。

注意: 根据 align-content 的值, wrap-reverse 作为 flex-wrap 的值时, 可能会影响既是 弹性容器 又是 滚动容器 的初始滚动位置。 参见 CSS Box Alignment 3 § 5.3 溢出对齐与滚动容器

测试

5.3. 弹性方向与换行:flex-flow 简写属性

名称: flex-flow
值: <'flex-direction'> || <'flex-wrap'>
初始值: 见各单独属性
适用于: 见各单独属性
是否继承: 见各单独属性
百分比: 见各单独属性
计算值: 见各单独属性
动画类型: 见各单独属性
规范顺序: 按语法
测试

flex-flow 属性是 flex-directionflex-wrap 属性的简写, 两者共同定义了弹性容器的主轴和交叉轴。

以下是在英文(从左到右、水平书写模式)文档中的一些有效流示例:
div { flex-flow: row; }
/* 初始值。主轴为内联方向,不换行。
   (项目会缩小以适应或溢出。)*/
div { flex-flow: column wrap; }
/* 主轴为块方向(自上而下)
   并且行在内联方向(向右)换行。*/
div { flex-flow: row-reverse wrap-reverse; }
/* 主轴为内联方向的反方向
   (从右到左)。新行向上换行。*/
注意 flex-flow 的方向会受到 书写模式影响。 例如在日文竖排中, row 弹性容器会从上到下排列内容, 如下例所示:
英文 日文
flex-flow: row wrap;        
writing-mode: horizontal-tb;
flex-flow: row wrap;        
writing-mode: vertical-rl;

5.4. 重新排序与可访问性:order 属性

弹性项目默认按照它们在源文档中的顺序显示和布局, 这代表了它们的逻辑顺序。 非视觉媒体(如语音)的渲染、 顺序导航模式的默认遍历顺序(比如通过链接循环, 参考 tabindex [HTML]), 以及内容在非 CSS UA 中的表现, 也都使用这个顺序。

order 属性可以用来改变弹性项目的排序, 改为以 order-modified document order 进行布局, 以使它们在二维视觉画布上的空间排列 与在语音、顺序导航等线性表现中的逻辑顺序不同。 参见 CSS Display 3 § 3 显示顺序:order 属性[CSS-DISPLAY-3]

注意: 由于视觉感知是二维且非线性的, 所需的盒子顺序并不总与非视觉媒体和非CSS UA使用的逻辑顺序一致。

作者必须仅使用 order 来进行视觉上的内容重排, 而不是逻辑上的重排。 如果样式表使用 order 来实现逻辑重排,则是不符合规范的。

许多网页的标记结构类似, 顶部是页眉, 底部是页脚, 中间是内容区和一个或两个额外的列。 通常, 希望内容在页面源代码中排在首位, 在额外列之前。 然而,这使很多常见设计, 比如让额外列在左侧、内容区在右侧, 变得难以实现。 多年来针对这个问题有很多方案, 当有两个额外列时,常被称为“圣杯布局”。order 让这一实现变得非常简单。 例如,以下是页面代码草图以及期望的布局:
<!DOCTYPE html>
<header>...</header>
<main>
   <article>...</article>
   <nav>...</nav>
   <aside>...</aside>
</main>
<footer>...</footer>
此页面中,header 在顶部,footer 在底部,但 article 在中间,nav 在右侧,aside 在左侧。

使用弹性布局可轻松实现如下:

main { display: flex; }
main > article { order: 2; min-width: 12em; flex:1; }
main > nav     { order: 1; width: 200px; }
main > aside   { order: 3; width: 200px; }

额外福利是, 所有列默认都会等高, 主内容会根据需要自动撑满屏幕宽度。 此外, 可以结合媒体查询,在窄屏下切换为全竖直布局:

@media all and (max-width: 600px) {
  /* 太窄,无法支持三列布局 */
  main { flex-flow: column; }
  main > article, main > nav, main > aside {
    /* 返回文档顺序 */
    order: 0; width: auto;
  }
}

(更智能换行的多行弹性容器用法留给读者自行练习。)

6. 弹性行

弹性项目弹性容器内会被布局和对齐在 弹性行 中, 这是布局算法用于分组和对齐的假想容器。 弹性容器可以是 单行多行, 取决于 flex-wrap 属性:

此示例展示了四个按钮无法横向排成一行, 因此会换行为多行。
#flex {
  display: flex;
  flex-flow: row wrap;
  width: 300px;
}
.item {
  width: 80px;
}
<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 无效。 一行的 主尺寸总是与弹性容器内容区的 主尺寸一致。

测试
这是与前面相同的示例, 不同之处在于所有弹性项目都设置了 flex: auto。 第一行有 60px 的剩余空间, 三个项目的弹性相同, 所以这一行的每个项目都会分到 20px 的额外宽度, 最终每个项目宽度为 100px。 剩下的那个项目单独占一行, 会拉伸到该行的全部宽度,即 300px。
与上方相同的渲染, 但所有项目都设置了 flex: auto

7. 弹性

弹性布局的核心特性是让 弹性项目“弹性伸缩”, 通过改变它们的宽度/高度来填满 主维度的可用空间。 这通过 flex 属性完成。 弹性容器会把剩余空间按项目的 flex grow factor 比例分配给项目, 以填满容器, 或根据 flex shrink factor 比例收缩项目以防止溢出。

如果一个 弹性项目flex-growflex-shrink 都为零, 则称其为 完全无弹性, 否则称为 有弹性

测试

7.1. flex 简写属性

名称: flex
值: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
初始值: 0 1 auto
适用于: 弹性项目
是否继承:
百分比: 见各单独属性
计算值: 见各单独属性
动画类型: 按计算值类型
规范顺序: 按语法
测试

flex 属性用于指定弹性尺寸的各组成部分: 弹性因子growshrink) 以及 弹性基础值。 当一个盒子为 弹性项目 时,会优先参考 flex而不是 主尺寸属性, 以决定盒子的 主尺寸。 如果盒子不是 弹性项目,则 flex 没有效果。

注意: flex 各长属性的初始值等同于 flex: 0 1 auto。 这与在 flex 简写属性省略时的默认值不同 (实际上是 1 1 0px), 这样 flex 简写可以更好地适应 最常见的情况

<'flex-grow'>
<number [0,∞]> 组件设置 flex-grow 长属性并指定 弹性增长因子, 用于决定当分配正剩余空间时, 弹性项目相对于同一弹性容器内其他 弹性项目 的增长比例。 若未指定,则默认为 1
测试
Flex 值在 0 到 1 之间时有一些特殊行为: 当该行上的 flex 值总和小于 1 时, 它们只会占据不到 100% 的剩余空间。

项目的 flex-grow 值 实际上是对剩余空间某一比例的请求, 1 表示“请求 100% 剩余空间”; 如果该行上的项目总请求超过 100%, 会按比例重新分配,全部用满剩余空间。 但如果项目请求的总量少于全部剩余空间 (比如三个项目每个都是 flex-grow: .25) 那么每个项目会正好获得它请求的份额 (每个分到 25%,剩下的 25% 空间则不填充)。 详见 § 9.7 解决弹性长度, 了解剩余空间分配的具体细节。

flex-grow 趋近于 0 时, 这种模式是为了保证行为连续 (意味着项目想要不占剩余空间)。 如果没有这种模式,flex-grow: 1 的项目会占据全部剩余空间; 而 flex-grow: 0.1 的项目也会如此, flex-grow: 0.01 也是, 依此类推, 直到值非常小以至于下溢为 0, 项目突然完全不占剩余空间。 有了这种行为, 当 flex-grow 小于 1 时, 项目会逐渐减少对剩余空间的占据, 在为零时平滑过渡为不占空间。

除非确实需要“部分填充”行为, 作者应坚持使用 ≥ 1 的值; 例如,使用 12 通常比用 .33.67 更好, 因为如果项目被添加、移除或换行时更能达到预期效果。

<'flex-shrink'>
<number [0,∞]> 组件设置 flex-shrink 长属性并指定 弹性收缩因子, 用于决定当分配负剩余空间时, 弹性项目相对于同一弹性容器内其他 弹性项目 的收缩比例。 若未指定,则默认为 1
测试

注意: 在分配负空间时,flex shrink factor 会与 flex base size 相乘。 这样会按照项目可收缩的程度来分配负空间, 例如,一个较小的项目不会在较大的项目明显变小之前就缩小到零。

测试
<'flex-basis'>
此组件用于设置 flex-basis 长属性, 用于指定 弹性基础值: 即在根据弹性因子分配剩余空间之前, 弹性项目的初始 主尺寸
测试

<'flex-basis'> 接受与 widthheight 属性相同的值 (但 auto 的处理方式不同) 以及 content 关键字:

auto
当在 弹性项目 上指定时,auto 关键字 会将 主尺寸属性 的值作为实际使用的 flex-basis。 如果该值本身也是 auto,则实际使用的值为 content
content
表示一个基于 自动尺寸 的值,依据 弹性项目的内容。 (通常等同于 max-content size, 但会针对 首选宽高比、 固有尺寸约束、 以及正交流作出调整; 具体可参见 详细说明§ 9 弹性布局算法。)

注意: 此值在 Flexible Box 布局最初发布时并未包含, 因此部分较早的实现可能不支持。 可以通过将 auto 与主尺寸(widthheight)设为 auto 来实现等效效果。

<'width'>
对于其它值,flex-basis 的解析方式与 widthheight 一致。

flex 简写属性中省略时,其指定值为 0

none
关键字 none 展开为 0 0 auto
示意图展示了“绝对”弹性(以基础为零开始) 和“相对”弹性(以项目内容尺寸为基础开始)的区别。 三个项目的弹性因子分别为 112: 可以看到弹性因子为 2 的项目增长速度是其他的两倍。

没有单位的零在未被两个弹性因子前置时,必须被解释为弹性因子。 为避免误解或无效声明, 作者应为 <'flex-basis'> 组件指定带单位的零, 或在其前面加上两个弹性因子。

7.1.1. flex 的基本值

本节仅供参考。

下方列表总结了四个 flex 值的效果, 代表最常用的几种情况:

flex: initial
等价于 flex: 0 1 auto。(这也是初始值。) 项目尺寸由 width/height 属性决定。 (如果项目的 主尺寸属性 计算为 auto, 那么弹性项目的尺寸将由内容决定。) 在有正剩余空间时,使弹性项目不可伸展, 但在空间不足时允许其收缩到最小尺寸。 可以使用 对齐能力auto 外边距主轴 上对齐弹性项目。
flex: auto
等价于 flex: 1 1 auto。 项目尺寸由 width/height 属性决定, 但会变为完全弹性,可以吸收 主轴 上的所有剩余空间。 如果所有项目都是 flex: autoflex: initialflex: none, 那么在项目尺寸确定后,所有正剩余空间将平均分配给 flex: auto 的项目。
flex: none
等价于 flex: 0 0 auto。 此值会根据 width/height 属性设置项目尺寸, 但会让弹性项目变为 完全无弹性。 这与 initial 类似, 但弹性项目即使溢出也不允许收缩。
flex: <number [1,∞]>
等价于 flex: <number [1,∞]> 1 0。 让弹性项目可伸展,并将 flex basis 设为零, 结果就是项目可获得弹性容器中指定比例的剩余空间。 如果弹性容器中的所有项目都使用此模式, 它们的尺寸会按指定的弹性因子成比例分配。
测试

默认情况下,弹性项目不会缩小到低于其最小内容尺寸 (即最长单词或定尺寸元素的长度)。 如需改变这一行为,可设置 min-widthmin-height 属性。 (参见 § 4.5 弹性项目的自动最小尺寸。)

7.2. 弹性的组成部分

弹性的各个组成部分可以通过独立的长属性进行控制。

鼓励作者使用 flex 简写属性控制弹性, 而不是直接使用各长属性, 因为简写属性会正确重置未指定的组件, 以适应常见用法

7.2.1. flex-grow 属性

名称: flex-grow
值: <number [0,∞]>
初始值: 0
适用于: 弹性项目
是否继承:
百分比: 不适用
计算值: 指定数值
规范顺序: 按语法
动画类型: 按计算值类型
测试

鼓励作者优先使用 flex 简写属性来控制弹性, 而不是直接使用 flex-grow, 因为简写属性能正确重置未指定的组件, 更好地满足常见用法

flex-grow 属性将 弹性增长因子 设置为指定的 <number>。 不允许负值。

7.2.2. flex-shrink 属性

名称: flex-shrink
值: <number [0,∞]>
初始值: 1
适用于: 弹性项目
是否继承:
百分比: 不适用
计算值: 指定值
规范顺序: 按语法
动画类型: 数值
测试

鼓励作者优先使用 flex 简写属性来控制弹性, 而不是直接使用 flex-shrink, 因为简写属性能正确重置未指定的组件, 更好地满足常见用法

flex-shrink 属性将 弹性收缩因子 设置为指定的 <number>。 不允许负值。

7.2.3. flex-basis 属性

名称: flex-basis
值: content | <'width'>
初始值: auto
适用于: 弹性项目
是否继承:
百分比: 相对于 弹性容器 的内部 主尺寸
计算值: 指定关键字或计算出的 <length-percentage>
规范顺序: 按语法
动画类型: 按计算值类型
测试

鼓励作者使用 flex 简写属性来控制弹性, 而不是直接使用 flex-basis, 因为简写属性会正确重置未指定的组件, 更好地适应常见用法

flex-basis 属性用于设置 弹性基础值。 它接受与 widthheight 属性相同的值,以及 content 关键字。

对于除了 autocontent(如上定义)以外的所有值, flex-basis 的解析方式与在水平书写模式下 width 的解析方式相同 [CSS2], 但如果某个值在 width 下会解析为 auto, 那么在 flex-basis 下则解析为 content。 例如,flex-basis 的百分比值, 是根据弹性项目的包含块(即其 弹性容器)进行解析; 如果该包含块的尺寸是 不确定的, 那么 flex-basis 的实际值为 content。 另一个推论是,flex-basis 决定了内容盒子的尺寸, 除非有其它属性(如 box-sizing [CSS3UI])做了特殊规定。

8. 对齐

当弹性容器的内容完成弹性伸缩,所有弹性项目的尺寸确定后, 就可以在弹性容器内对齐这些项目。

margin 属性可用于对齐项目,其方式与块布局中的外边距类似,但更强大。弹性项目也支持 CSS Box Alignment 的对齐属性, 能够轻松地通过关键字对项目进行主轴 main axis 和交叉轴 cross axis 的对齐。 这些属性让许多常见的对齐类型变得简单, 包括一些在 CSS 2.1 中很难实现的效果, 如水平居中和垂直居中。

注意: 虽然对齐属性定义在 CSS Box Alignment [CSS-ALIGN-3], 弹性盒布局在此复述了相关属性的定义, 以避免产生规范性依赖,这样有助于规范推进。 这些属性目前仅适用于弹性布局, 直到 CSS Box Alignment Level 3 完成并定义其在其他布局模式下的效果。 此外,Box Alignment 模块中定义的新值也会适用于弹性盒布局; 换言之,一旦 Box Alignment 模块完成, 这里的定义将由其取代。

测试

8.1. 使用 auto 外边距进行对齐

本节为非规范性内容。 关于外边距如何影响弹性项目的规范性定义,请参见 弹性布局算法 一节。

弹性项目上的 auto 外边距的效果与块流中的 auto 外边距非常相似:

测试

注意: 如果剩余空间被分配给 auto 外边距, 对齐属性在该方向上将不起作用, 因为外边距会“偷走”弹性分配后留下的所有剩余空间。

在主轴上使用 auto 外边距的一个用途是将弹性项目分为不同的“组”。 下例展示如何利用这一点实现常见的 UI 模式—— 一行操作按钮,部分左对齐,部分右对齐。
下方代码的示例渲染。
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>
下图展示了在溢出情况下, 使用 auto 外边距与使用 对齐属性 在交叉轴上的区别。
关于
专制主义
博客
关于
专制主义
博客
左侧图中的项目通过外边距居中, 右侧图中的项目通过 align-self 属性居中。 如果这个列式弹性容器贴在页面左边, 外边距的行为会更理想, 因为长项目能完全显示。 而在其他场景下, 真正居中的效果可能更好。

8.2. 轴对齐:justify-content 属性

名称: justify-content
值: flex-start | flex-end | center | space-between | space-around
初始值: flex-start
适用于: 弹性容器
是否继承:
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散
测试

justify-content 属性用于将 弹性项目 沿弹性容器当前行的 主轴对齐。 此操作会在所有弹性长度和 auto 外边距 都已处理后进行。 一般用于分配当某一行上的所有 弹性项目都不可伸展, 或可伸展但已达到最大尺寸时剩余的自由空间。 还可以在项目溢出到行外时,控制其对齐方式。

flex-start
弹性项目会向该行起始方向排列。 行上第一个 弹性项目main-start 外边距紧贴行的 main-start 边缘, 后续每个 弹性项目都紧贴前一个项目。
测试
flex-end
弹性项目会向该行末尾排列。 行上最后一个 弹性项目main-end 外边距紧贴行的 main-end 边缘, 前面的每个 弹性项目都紧贴后一个项目。
测试
center
弹性项目会向该行中心排列。 行上的 弹性项目彼此紧贴,并在行中央对齐, 行 main-start 边缘与第一个项目之间, 以及行 main-end 边缘与最后一个项目之间的间距相等。 (如果剩余空间为负,弹性项目会在两个方向上等量溢出。)
测试
space-between
弹性项目会在行内均匀分布。 若剩余空间为负或该行只有一个 弹性项目, 则此值会退回为 safe flex-start。 否则, 行上第一个 弹性项目main-start 外边距紧贴行的 main-start 边缘, 行上最后一个 弹性项目main-end 外边距紧贴行的 main-end 边缘, 行内其他 弹性项目均匀分布,相邻项目间距相同。
测试
space-around
弹性项目会在行内均匀分布,并且两端的空隙为单个间距的一半。 若剩余空间为负或该行只有一个 弹性项目, 则此值会退回为 safe center。 否则,行上的 弹性项目会分布, 相邻 弹性项目之间间距相同, 第一个、最后一个 弹性项目与弹性容器边缘的间距是项目间距的一半。
测试

五个 justify-content 关键字及其对一个三色弹性容器的影响示意图。

8.3. 交叉轴对齐:align-itemsalign-self 属性

名称: align-items
值: flex-start | flex-end | center | baseline | stretch
初始值: stretch
适用于: 弹性容器
是否继承:
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散
测试
名称: align-self
值: auto | flex-start | flex-end | center | baseline | stretch
初始值: auto
适用于: 弹性项目
是否继承:
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散
测试

弹性项目可以在弹性容器当前行的 交叉轴上对齐, 类似于 justify-content,但方向垂直。align-items 设置弹性容器所有 项目(包括匿名 弹性项目)的默认对齐方式。align-self 可以为单个 弹性项目覆盖这种默认对齐方式。 (对于匿名弹性项目,align-self 总是与其所属弹性容器上的 align-items 值一致。)

如果 弹性项目的任一交叉轴外边距为 auto,则 align-self 失效。

各值含义如下:

auto
交叉轴对齐由父盒子的 align-items 控制。 (这是 align-self 的初始值。)
测试
flex-start
弹性项目cross-start 外边距紧贴行的 cross-start 边缘。
测试
flex-end
弹性项目cross-end 外边距紧贴行的 cross-end 边缘。
测试
center
弹性项目的外边距盒在该行的 交叉轴居中。 (如果弹性行的 交叉尺寸小于 弹性项目的尺寸, 项目会在两个方向上等量溢出。)
测试
baseline
弹性项目 参与基线对齐: 行上所有参与基线对齐的 弹性项目其基线会对齐, 与基线距离 cross-start 外边距最远的项目紧贴行的 cross-start 边缘。 如果项目在该轴上没有基线, 则会从 弹性项目的边框盒合成一个基线。
测试
stretch
如果 弹性项目交叉尺寸属性 计算为 auto, 且交叉轴外边距都不是 auto, 则 弹性项目会被拉伸。 其最终值是让项目外边距盒的 交叉尺寸尽量与该行等高所需的长度, 同时还会考虑 min-height/min-width/max-height/max-width 的限制。

注意: 如果弹性容器的高度受限, 此值可能会导致 弹性项目内容溢出项目盒。

弹性项目cross-start 外边距紧贴行的 cross-start 边缘。

测试

五个 align-items 关键字及其对一个四色弹性容器的影响示意图。

8.4. 弹性行的收纳:align-content 属性

名称: align-content
值: flex-start | flex-end | center | space-between | space-around | stretch
初始值: stretch
适用于: 多行 弹性容器
是否继承:
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散

align-content 属性用于在弹性容器内对齐弹性行, 当交叉轴有剩余空间时, 类似于 justify-content 对齐主轴上的项目。 注意:此属性对 单行 弹性容器无效。 各值含义如下:

flex-start
行向弹性容器起始方向排列。 弹性容器内第一行的 cross-start 边缘紧贴弹性容器的 cross-start 边缘, 后续每行紧贴前一行。
flex-end
行向弹性容器末尾排列。 最后一行的 cross-end 边缘紧贴弹性容器的 cross-end 边缘, 前面的每行紧贴后一行。
center
行在弹性容器中央排列。 所有行彼此紧贴,并在弹性容器中心对齐, 弹性容器 cross-start 内容边缘与第一行之间, 以及容器 cross-end 内容边缘与最后一行之间的空隙相等。 (若剩余空间为负,所有行会在两个方向等量溢出。)
space-between
行在弹性容器内均匀分布。 若剩余空间为负或弹性容器内只有一条 弹性行, 则此值退回为 safe flex-start。 否则, 弹性容器内第一行的 cross-start 边缘紧贴容器的 cross-start 内容边缘, 最后一行的 cross-end 边缘紧贴容器的 cross-end 内容边缘, 其他行均匀分布,相邻行间距一致。
space-around
行在弹性容器内均匀分布,且两端空隙为单个间距的一半。 若剩余空间为负, 则此值退回为 safe center。 否则,所有行分布时,相邻行间距一致, 第一行和最后一行与容器边缘的空隙是行间距的一半。
stretch
行会拉伸以占据剩余空间。 若剩余空间为负, 此值退回为 flex-start。 否则, 所有行平均分配剩余空间,增加其交叉尺寸。

注意: 只有 多行 弹性容器的交叉轴才有剩余空间可用于对齐弹性行, 因为 单行弹性容器唯一的行会自动拉伸填满空间。

align-content 关键字及其对一个 多行弹性容器的影响示意图。

测试

8.5. 弹性容器基线

为了让 弹性容器自身能够参与基线对齐(例如当弹性容器本身作为外部弹性容器中的弹性项目时), 它需要提交最能代表其内容的基线位置。 为此, 弹性容器的基线按照如下方式确定 (在用order重排,并考虑flex-direction后):

first/last 主轴基线集
内联轴弹性容器主轴方向一致时, 基线按照如下方式确定:
  1. 如果弹性容器的弹性项目中,有任何项目在最起始最末尾弹性行参与基线对齐, 则弹性容器的第一/最后主轴基线集由这些弹性项目的共享对齐基线生成

  2. 否则,如果弹性容器至少有一个弹性项目, 则弹性容器的第一/最后主轴基线集最起始/最末尾弹性项目对齐基线生成。 (如果该项目在弹性容器主轴方向没有对齐基线, 则首先会从其边框边缘合成一个基线。)

  3. 否则,弹性容器没有主轴方向的第一/最后基线集, 如有需要则根据其对齐上下文规则合成

first/last 交叉轴基线集
内联轴弹性容器交叉轴方向一致时, 基线按照如下方式确定:
  1. 如果弹性容器至少有一个弹性项目, 则弹性容器的第一/最后交叉轴基线集最起始/最末尾弹性项目对齐基线生成。 (如果该项目在弹性容器交叉轴方向没有对齐基线, 则首先会从其边框边缘合成一个基线。)

  2. 否则,弹性容器没有交叉轴方向的第一/最后基线集, 如有需要则根据其对齐上下文规则合成

根据上述规则计算基线时, 如果贡献基线的盒子的overflow值允许滚动, 在确定基线时必须把盒子视为处于初始滚动位置。

确定表格单元格的基线时, 弹性容器会像行盒或 table-row 一样提供基线。[CSS2]

更多关于基线的信息请参见 CSS Writing Modes 3 § 4.1 基线介绍CSS Box Alignment 3 § 9 基线对齐细节

测试

9. 弹性布局算法

本节包含规范性算法, 详细说明弹性容器及其内容的具体布局行为。 这里的算法以优化可读性和理论简洁性为目标, 实际实现不一定采用这些最优算法, 但必须保证实际效果与本节描述一致。

注意: 本节主要面向实现者。 编写网页的作者通常只需参考各属性的描述, 除非你非常渴望深入理解 CSS 布局的细节,否则无需阅读本节。

下列各节定义了弹性容器及其内容的布局算法。

注意: 弹性布局根据弹性项目order-修改后的文档顺序进行, 而不是它们在原始文档中的顺序。

测试

9.1. 初始设置

  1. 生成匿名弹性项目,详见 § 4 弹性项目

9.2. 行长度确定

  1. 确定弹性项目的主轴和交叉轴可用空间。 对每个维度, 如果该维度的 弹性容器内容框是确定尺寸,则直接使用该尺寸; 如果该维度的 弹性容器正受最小内容约束最大内容约束,则该维度的可用空间就是对应约束; 否则,从弹性容器所在维度的可用空间中减去 弹性容器的外边距、边框和内边距, 使用得到的值。 这可能导致值为无穷大。

    例如,可用空间对于一个 浮动auto 宽度的 弹性容器来说为:

    • 弹性容器的包含块宽度,减去 弹性容器的外边距、边框和内边距(在水平方向上)
    • 在垂直方向上为无穷大
  2. 确定每个项目的弹性基础尺寸假定主尺寸
    测试
    1. 如果该项目有一个确定的已用flex basis, 那么这个弹性基础尺寸就是该值。
    2. 如果弹性项目有…… 那么弹性基础尺寸由其已用已用交叉尺寸弹性项目的宽高比计算得出。
    3. 如果已用flex basiscontent或依赖于其可用空间, 且弹性容器正在最小内容或最大内容约束下进行尺寸计算 (例如进行自动表格布局 [CSS2]), 则按该约束对项目进行尺寸计算。 弹性基础尺寸即为该项目结果的主尺寸
    4. 否则, 如果已用flex basiscontent或依赖于其可用空间, 主尺寸可用空间为无穷大, 并且弹性项目的内联轴与主轴平行, 使用正交流盒子的规则 [CSS3-WRITING-MODES]进行布局。 弹性基础尺寸即为该项目的 max-content 主尺寸

      注意: 例如,在一个英文文档(水平书写模式)中, 包含一个列式弹性容器, 容器中有一个日文竖排(竖直书写模式弹性项目时会出现该情况。

    5. 否则, 使用已用flex basis代替主尺寸,在可用空间内对项目进行尺寸计算, 并将content视为max-content。 如果确定主尺寸需要交叉尺寸 (例如弹性项目主尺寸在其块轴上, 或有首选宽高比时), 且弹性项目的交叉尺寸为auto且不是确定值, 在此计算中用fit-content作为弹性项目交叉尺寸弹性基础尺寸为项目最终的主尺寸
      测试

    在确定弹性基础尺寸时, 会忽略项目的最小和最大主尺寸 (不会进行约束)。 此外,应用box-sizing时将内容盒尺寸下限为零的计算也会被忽略。 (例如,一个指定尺寸为零、正内边距,并设置为box-sizing: border-box的项目, 其外部弹性基础尺寸为零——因此其内部弹性基础尺寸为负值。)

    假定主尺寸是项目的弹性基础尺寸 按照其已用最小和最大主尺寸进行约束(并将内容盒尺寸下限到零)后的结果。

    测试
  3. 确定弹性容器的 主尺寸,使用其所处格式化上下文的规则。
    块级自动尺寸对于块级 弹性容器来说,就是其max-content size

    Block Layout 规范应该定义这个等价关系,但目前还没有。

9.3. 主尺寸确定

  1. 将弹性项目收集到弹性行中:
    • 如果弹性容器是单行, 则把所有弹性项目收集到一个弹性行中。
    • 否则, 从第一个未收集的项目开始, 依次收集连续的项目, 直到第一次下一个要收集的项目 无法放入弹性容器的内部主尺寸 (或遇到强制换行,参见§ 10 弹性布局分页)。 如果第一个未收集的项目就放不下, 则只将它收集到该行。

      在此步骤中, 弹性项目的尺寸为其外部 假定主尺寸(注意:该值可能为负。)

      重复此过程,直到所有弹性项目都被收集到弹性行中。

      注意,“尽量收集”这一行会把零尺寸弹性项目收集到上一行的末尾, 即使最后一个非零项目刚好“填满”了该行。

  2. 解析所有弹性项目的弹性长度,以确定其已用主尺寸。参见§ 9.7 解析弹性长度
测试

9.4. 交叉尺寸确定

  1. 为每个项目确定假定交叉尺寸,方法是按照其为一个流内 块级盒,使用已用主尺寸和给定的可用空间进行布局, 将auto视为fit-content
    测试
  2. 计算每个弹性行的交叉尺寸。

    如果弹性容器是单行且有确定交叉尺寸, 那么交叉尺寸就是弹性行弹性容器内部交叉尺寸

    否则, 对每个弹性行:

    1. 收集所有内联轴与主轴平行的弹性项目, 其 align-selfbaseline, 且交叉轴外边距均非 auto。 找出每个项目基线与其假定外部交叉起点边之间的最大距离, 以及基线与假定外部交叉终点边之间的最大距离, 将这两个值相加。
    2. 在所有未被上一步收集的项目中, 找出最大的外部 假定交叉尺寸
    3. 弹性行 的已用交叉尺寸为前两步所得数值与零中的最大值。

      如果弹性容器为 单行, 则将该行的交叉尺寸限制在容器计算得到的最小和最大 交叉尺寸范围内。 注意:如果 CSS 2.1 对 min/max-width/height 的定义更广泛适用, 该行为即可自动得出。

    测试
  3. 处理 'align-content: stretch'。 如果弹性容器有确定的交叉尺寸,align-contentstretch, 并且所有弹性行的交叉尺寸之和小于弹性容器的内部交叉尺寸, 就将每个弹性行的交叉尺寸按相同的量增加, 使它们的总和正好等于弹性容器的内部交叉尺寸。
  4. 折叠 visibility:collapse 项目。 如果有弹性项目设置了visibility: collapse, 记住它所在行的交叉尺寸作为该项目的 strut size, 然后从头重新布局。

    在第二轮布局时, 收集项目到行时, 把折叠的项目视为主尺寸为零。 在后续算法中, 完全忽略这些折叠项目 (就像它们 display:none 一样), 但在计算行交叉尺寸之后, 如果某行的交叉尺寸小于该行所有折叠项目的最大 strut size, 就将该行交叉尺寸设置为这个 strut size

    第二轮布局时跳过此步骤。

    测试
  5. 确定每个弹性项目的已用交叉尺寸。 如果某个弹性项目的 align-self: stretch, 其计算的交叉尺寸属性为 auto, 且其交叉轴外边距都不是 auto, 则已用外部交叉尺寸为其弹性行的已用交叉尺寸, 并根据该项目的已用最小和最大 交叉尺寸进行限制。 否则, 已用交叉尺寸为该项目的 假定交叉尺寸

    如果弹性项目设置了align-self: stretch, 则要重新为其内容布局, 并把此已用尺寸视为确定的交叉尺寸, 以便能解析百分比尺寸的子元素。

    测试

    注意:此步骤不会影响弹性项目的主尺寸, 即使它有首选宽高比

测试

9.5. 主轴对齐

  1. 分配任何剩余的自由空间。 对每个弹性行:
    1. 如果剩余自由空间为正, 且该行至少有一个主轴外边距为auto, 则将自由空间在这些外边距之间平均分配。 否则,将所有auto外边距设为零。
    2. justify-content沿主轴对齐项目。

9.6. 交叉轴对齐

  1. 解析交叉轴auto外边距。 如果弹性项目有auto交叉轴外边距:
    • 如果其外部交叉尺寸(将这些auto外边距视为零)小于其弹性行的交叉尺寸, 将尺寸差在这些auto外边距间平均分配。
    • 否则, 如果block-startinline-start外边距(以交叉轴为准)为auto,则设为零。 设置相对的外边距,使项目外部交叉尺寸等于弹性行的交叉尺寸。
  2. align-self沿交叉轴对齐所有弹性项目, 前提是项目的交叉轴外边距都不是auto
  3. 按其参与的格式化上下文规则,确定弹性容器的已用交叉尺寸。 如果需要基于内容的交叉尺寸, 则用所有弹性行交叉尺寸之和。
  4. align-content对齐所有弹性行

9.7. 弹性长度的解析

要解析弹性行中项目的弹性长度:

  1. 确定已用弹性因子。 求该行所有项目的外部假定主尺寸之和。 如果该值小于弹性容器的内部主尺寸, 则后续算法用弹性增长因子; 否则用弹性收缩因子。
  2. 每个弹性行中的项目有一个目标主尺寸,初始设为其弹性基础尺寸。 每个项目最初都是未冻结状态,之后可能变成冻结状态。

    注意: 项目的目标主尺寸冻结后不再变化。

  3. 处理不可伸缩项目。 冻结, 并将其目标主尺寸设为其假定主尺寸……
    • 弹性因子为零的项目
    • 若用弹性增长因子: 所有弹性基础尺寸大于其假定主尺寸的项目
    • 若用弹性收缩因子: 所有弹性基础尺寸小于其假定主尺寸的项目
  4. 计算初始自由空间 求该行所有项目的外部尺寸之和, 并用弹性容器的内部主尺寸减去它。 对于冻结项目,用其外部目标主尺寸; 对于其他项目,用其外部弹性基础尺寸
  5. 循环:
    1. 检查是否有弹性项目。 如果该行所有弹性项目都已冻结,退出该循环。
    2. 计算剩余自由空间,方法同上面的初始自由空间。 如果未冻结弹性项目的弹性因子之和小于 1, 就用初始自由空间乘以这个和。 如果这个值的绝对值小于剩余自由空间的绝对值, 则用此值作为剩余自由空间
    3. 如果剩余自由空间非零,按弹性因子比例分配
      若用弹性增长因子
      对该行所有未冻结项目, 求其弹性增长因子与所有未冻结项目弹性增长因子之和的比例。 将项目的目标主尺寸设为其弹性基础尺寸加剩余自由空间按比例分配的部分。
      若用弹性收缩因子
      对该行所有未冻结项目, 用其弹性收缩因子乘以其内部弹性基础尺寸, 记作缩放弹性收缩因子。 求其缩放弹性收缩因子与所有未冻结项目缩放弹性收缩因子之和的比例。 将项目的目标主尺寸设为其弹性基础尺寸减去剩余自由空间绝对值按比例分配的部分。注意,这可能导致内部主尺寸为负值; 下一步将纠正。
    4. 修正最小/最大约束。 用项目的已用最小和最大主尺寸约束每个未冻结项目的目标主尺寸,并将内容盒尺寸下限为零。 如果项目的目标主尺寸因此变小, 则为最大约束违规; 如果变大,则为最小约束违规。
    5. 冻结超出约束的项目。 总违规量为上一步所有调整的总和 ∑(约束后尺寸 - 约束前尺寸)。 如果总违规量:
      为零
      冻结所有项目。
      为正
      冻结所有最小约束违规的项目。
      为负
      冻结所有最大约束违规的项目。

      注意: 此步骤至少冻结一个项目,保证循环能继续并最终终止。

    6. 返回到该循环的开头。
  6. 将每个项目的已用主尺寸设为其目标主尺寸
测试

9.8. 明确尺寸与不明确尺寸

尽管 CSS Sizing [CSS-SIZING-3] 定义了 明确不明确 的长度, Flexbox 还包含若干额外的情况下,长度也可视为明确

  1. 如果 弹性容器具有 明确主尺寸, 那么其 弹性项目 在弹性伸缩后的 主尺寸 都视为 明确

  2. 如果某个 弹性项目flex basis明确的, 那么它弹性伸缩后的 主尺寸 也视为 明确

  3. 如果 单行 弹性容器具有明确的 交叉尺寸, 那么任何被拉伸的 弹性项目自动 首选 外部交叉尺寸等于弹性容器的内部交叉尺寸(限制在该 弹性项目 的最小和最大 交叉尺寸 范围内), 并且视为 明确 尺寸。

  4. 一旦弹性行的交叉尺寸已确定, 自动尺寸弹性容器中的项目的交叉尺寸在布局时也视为明确尺寸; 参见 步骤 11

测试

注意: 这意味着在弹性布局中, “明确”尺寸有时需要先进行布局计算。 这样设计是为了让弹性项目内部的百分比能够按作者预期被正确解析。

9.9. 内在尺寸

内在尺寸用于为弹性容器生成多种基于内容的自动尺寸, 如自适应逻辑宽度(使用 fit-content 公式) 和基于内容的逻辑高度(使用 max-content size)。 在这些计算中,弹性项目上的 auto 外边距会被视为 0

相关术语定义参见 [CSS-SIZING-3]

测试

9.9.1. 弹性容器的内在主尺寸

max-content 主尺寸弹性容器,理论上是指弹性容器能取的最小尺寸, 当用该容器尺寸进行弹性布局时, 每个弹性项目最终至少达到其 max-content 贡献尺寸, 在项目弹性允许的范围内。

min-content 主尺寸弹性容器,理论上是指弹性容器能取的最小尺寸, 使得没有项目溢出容器, 且没有项目内容溢出项目本身——不考虑那些布局本身定义为溢出的情况 (如负外边距或百分比尺寸总和超过 100%)。

测试
9.9.1.1. 理想算法

注意: 下述算法用于计算弹性容器的理想内在主尺寸。 然而,由于最初实现不正确, 且已有内容依赖于(不幸地一致的)错误实现行为,该算法并不兼容 Web。 实现者和 CSS 工作组正在研究浏览器实现是否可以安全地趋近于该行为, 并欢迎进一步实验。

仅考虑未折叠弹性项目

  1. 对每个 弹性项目, 用其 外部 flex base size 去减其 max-content 贡献尺寸。 如果结果为正, 若 flex grow factor ≥ 1,则除以该项目的 flex grow factor; 若 flex grow factor < 1,则乘以 flex grow factor; 如果结果为负, 则除以该项目的 scaled flex shrink factor(若除以零,结果视为负无穷)。 这就是该项目的 期望 flex 分数
  2. 将所有 弹性项目 放入无限长度的行中。 在每一行内, 找出所有 弹性项目中最大的(最正的)期望 flex 分数。 这就是该行的 选定 flex 分数
  3. 如果 选定 flex 分数 为正, 且该行的 flex grow factor 之和小于 1, 则用该和去除 选定 flex 分数

    如果 选定 flex 分数 为负, 且该行的 flex shrink factor 之和小于 1, 则用该和去乘 选定 flex 分数

  4. 将每个项目的 flex base size 与其 flex grow factor(若收缩则为 scaled flex shrink factor)乘以 选定 flex 分数 的积相加, 然后用 最大主尺寸(下限为 最小主尺寸)进行夹取。
  5. 弹性容器max-content 尺寸 为所有行中, 某一行内所有项目按上述计算所得尺寸的最大总和。

min-content 主尺寸对于单行 弹性容器, 计算方式与max-content 主尺寸相同, 只是使用min-content 贡献而不是max-content 贡献

当 flex 之和小于 1 时该算法的影响

上述算法特别为两种情况设计,以保证 弹性容器的尺寸在这两种情况之间连续变化:

  1. 如果所有项目都不可伸缩, 弹性容器的尺寸就是所有 弹性基础尺寸之和。 (不可伸缩的弹性基础尺寸实际上可替代width/height, 而在块布局中指定时,max-content 贡献也是基于此。)

  2. 如果所有项目的弹性因子≥1, 那么弹性容器的尺寸是其项目的 max-content 贡献之和 (或稍大一些, 使每个弹性项目至少等于其 max-content 贡献, 但同时仍能按弹性分配比例保持各项目尺寸间的正确比例)。

例如,如果一个 弹性容器 只有一个 弹性项目,其 flex-basis: 100px;,但 max-content 尺寸为 200px, 那么当该项目设为 flex-grow: 0 时,弹性容器(以及 弹性项目)宽度为 100px, 但如果该项目设为 flex-grow: 1 或更高, 弹性容器(和弹性项目)宽度为 200px

有几种可能的方法可以让这两种情况之间的整体行为连续, 但它们都有缺陷。 我们选择了一种认为副作用最小的方式; 不幸的是,在 flex factor 小于 1 的情况下,会出现“灵活性被双重应用”。 就上例而言,如果项目设为 flex-grow: .5, 那么 弹性容器最终宽度为 150px, 但项目在该可用空间下正常排布,最终宽度为 125px

关于所选特定行为的更深入说明

原则:

  1. 无论增长还是收缩,输入趋近于零时都不能让尺寸爆炸。

  2. 当所有 flex factor >=1 时,返回每个项目大于等于 max-content 尺寸所需的最小尺寸。

  3. flex 为零的项目不应影响整体尺寸。

  4. 保持对 flex factor 和项目尺寸变化的连续性。

  5. 对任意输入变量(尺寸、flex factor)线性变化时,尽量保持尺寸变化的线性。

  6. 当 flex factor 之和 >=1 时,返回让每个项目大于等于 max-content 尺寸所需的最小总尺寸。

为了让这些原则都能成立, 当单个 flex factor 或一行上的 flex factor 总和小于 1 时, 就需要做修正。

收缩时行为更简单些; 因为 shrink=0 时爆炸成负无穷, 但我们最终总是选取最大值,所以不会选到负无穷, 只需要在行级做修正即可, 只有当总和小于 1 时才会出现双重修正。

增长时更复杂。 grow=0 会爆炸成正无穷, 而我们会选中正无穷, 所以需要对每个项目单独修正:当 factor 小于 1 时用 factor 乘空间。 但这样处理会导致 factor 小于 1 且总和 ≥ 1 时双重修正, 而总和小于 1 时会三重修正。 为避免这种极端情况, 总和为 1 时要反向修正,即再除以总和。 这样一来,factor 小于 1 的项目在所有情况下都会有双重修正。

我们无法完全消除双重修正, 除非放弃其它更重要的原则 (尤其是原则 3——比如让两个 flex-grow: .5 的项目不双重应用, 但又不能让 flex-grow: 0 的项目 干扰到 flex-grow: 1 的兄弟项目; 据我们所知,这是无法做到的。)

9.9.1.2. Web 兼容的内在尺寸算法

注意: 下述算法已被证明兼容 Web。 未来可能会调整,使其更接近理想算法。

Web 兼容算法将在此补充,一旦有成果。[Issue #8884]

9.9.1.3. 多行 min-content 算法

对于多行容器, min-content 主尺寸就是该弹性容器中所有未折叠弹性项目的最大min-content 贡献。 对于此目的, 每个项目的贡献 若项目不可增长则不超过其弹性基础尺寸, 若不可收缩则不小于其弹性基础尺寸, 然后再按项目的最小和最大主尺寸约束。

9.9.2. 弹性容器的内在交叉尺寸

min-content/max-content 交叉尺寸对于 单行 弹性容器, 就是其弹性项目的最大min-content 贡献/max-content 贡献(分别对应)。

对于多行 弹性容器, 行为取决于是行式还是列式弹性盒:

row 多行 弹性容器 交叉尺寸

min-content/max-content 交叉尺寸是各弹性行交叉尺寸之和, 即弹性容器在交叉轴上受min-content 约束max-content 约束(分别对应)时计算得到的各弹性行交叉尺寸之和。

column 多行 弹性容器 交叉尺寸

min-content 交叉尺寸为所有弹性项目的最大min-content 贡献

注意: 这种启发式做法实际上假定只有一条弹性行, 以保证 min-content size 小于 max-content size。 如果弹性容器有高度约束, 则可能会导致溢出, 但如果弹性容器也是滚动容器, 那么至少保证任何一列都能完整显示在其滚动端口内。

max-content 交叉尺寸为各弹性行交叉尺寸之和, 这些弹性行是在弹性容器交叉轴上受交叉轴 max-content 约束下, 以所有max-content 交叉尺寸贡献的最大值作为每个弹性项目的交叉轴可用空间进行布局得到的。

注意: 这种启发式能合理近似弹性容器应有的尺寸, 即每个弹性项目以其max-content 贡献或更大尺寸布局, 每个弹性行不会超过其最大项目尺寸。 某些情况下不算完美, 但完全正确的做法成本极高, 这种方案已经很实用。

测试

9.9.3. 弹性项目的内在尺寸贡献

min-content 贡献的主尺寸对于弹性项目而言,是其 外部min-content 尺寸与外部首选尺寸(如果不是 auto)中的较大值, 并按其最小/最大主尺寸进行约束。

max-content 贡献的主尺寸对于弹性项目而言,是其 外部max-content 尺寸与外部首选尺寸(如果不是 auto)中的较大值, 并按其最小/最大主尺寸进行约束。

10. 弹性布局的分页处理

弹性容器可以在项目之间、 项目所在的行之间(在多行模式下), 以及项目内部进行分页断开。 break-* 属性对于弹性容器的应用方式与块级或内联盒一样。 本节定义这些属性如何应用于弹性项目 以及弹性项目的内容。 更多内容请参见 CSS 分页模块[CSS3-BREAK]

下述分页规则中,将 分页容器称为“页面”。 同样的规则适用于任何其他分页上下文。 (在需要时将“页面”替换为合适的 分页容器类型。) 为便于理解,本节中的“行”和“列”术语是指弹性容器相对于 分页上下文块流方向的排列, 而不是指 弹性容器自身的方向。

分页的弹性容器的具体布局 在本级别的弹性盒布局规范中未定义。 但弹性容器内部的断开需遵循如下规则 (以 order-修改后的文档顺序为准):

测试

10.1. 弹性布局分页算法示例

本说明性章节展示了弹性容器的一种可能的分页算法。 鼓励实现者在此算法基础上改进并向 CSS 工作组反馈意见

此算法假定分页总是仅向前进行; 因此,下面的算法在分页前基本忽略了对齐。 高级布局引擎可能能够在各分页片段间保持对齐。

单行列式弹性容器
  1. 运行弹性布局算法(不考虑分页),直至交叉尺寸确定
  2. 从第一个项目开始,尽量多地连续布局弹性项目或其片段(但至少要布局一个或其片段),直到页面没有剩余空间或遇到强制分页断开。
  3. 如果上一步空间不足且剩余空间为正, UA 可以减少本页分配的自由空间(最多减到零),以便为下一个不可断开的弹性项目或片段腾出空间。 否则,不适合的项目或片段会被推到下一页。 UA 应在超过 50% 片段能放入剩余空间时拉上,否则推下。
  4. 若还有未布局的弹性项目或片段,重新运行弹性布局算法,从行长度确定交叉尺寸确定,用下页的尺寸,且包含所有内容(包括已布局的),然后返回上一步,从第一个未布局的项目或片段开始。
  5. 对弹性容器的每个片段,从主轴对齐继续执行弹性布局算法直到结束。

此算法意在让列方向的单行弹性容器的分页行为与块流非常类似。 测试时,设弹性容器为 justify-content:start 且无弹性项目时, 其分页效果应与内容、尺寸、外边距均相同的块级盒一致。

多行列式弹性容器
  1. 运行弹性布局算法(考虑分页,将弹性容器最大行长度限制为页面剩余空间),直至交叉尺寸确定
  2. 尽量多地布局弹性行(但至少一行),直到弹性容器交叉轴没有空间或遇到强制断开:
    1. 从第一个项目开始,尽量多地连续布局弹性项目(但至少一个),直到页面没有空间或遇到强制断开。弹性项目内的强制断开忽略。
    2. 如果这是第一个弹性容器片段,且该行只有一个比页面剩余空间大的弹性项目,且弹性容器未在页面顶部,则将容器移至下一页并重新布局。
    3. 若有未布局的弹性项目,重新运行弹性布局算法,从主尺寸确定交叉尺寸确定,只用未布局的项目,并返回上一步,从第一个未布局的项目开始。
  3. 若有未布局的弹性项目,重新运行弹性布局算法,从行尺寸确定交叉尺寸确定,用下页尺寸,仅包含未布局的项目,并返回上一步,从第一个未布局的项目开始。
  4. 对弹性容器的每个片段,从主轴对齐继续执行弹性布局算法直到结束。

此示例算法的不足之处在于, 若弹性项目无法完整放入单页,则不会在多行列式弹性容器中进行分页。

单行行式弹性容器
  1. 运行完整弹性布局算法(不考虑分页),但将任何align-selfflex-startbaseline 视为 flex-start
  2. 若不可断开的项目无法放入页面剩余空间,且弹性容器未在页面顶部,则将弹性容器移至下一页并重新布局。
  3. 对每个项目,尽量布局其内容至页面剩余空间,剩余内容在下一页分页,重新运行弹性布局算法,从行长度确定主轴对齐,用新页面尺寸和所有内容(含前页已完成项目)。

    完全放入前片段的弹性项目在后续片段主轴上依然占据空间。

  4. 对弹性容器的每个片段,重新运行弹性布局算法,从交叉轴对齐到结束。 除第一个片段外,所有项目片段和行的align-selfalign-content都视为flex-start
  5. 若有项目按原align-self值对齐后能完整放入某个弹性容器片段,则可移入该片段并适当对齐。
多行行式弹性容器
  1. 运行弹性布局算法(不考虑分页),直到交叉尺寸确定
  2. 从第一个行开始,尽量多地布局弹性行(但至少一行),直到页面没有空间或遇到强制断开。

    如果某行无法放入页面,且该行未在页面顶部,则将该行移至下一页并重新运行弹性布局算法,只用该行及后续项目。

    如果弹性项目本身导致强制断开,则重新运行弹性布局算法,从主尺寸确定主轴对齐,只用该行及后续行的项目,并让导致断开的项目在行分步时自动开启新行,然后继续本步骤。 弹性项目内的强制断开忽略。

  3. 若有未布局的弹性项目,重新运行弹性布局算法,从行长度确定主轴对齐,用下页尺寸和未布局项目。返回上一步,从第一个未布局的行开始。
  4. 对弹性容器的每个片段,从交叉轴对齐继续执行弹性布局算法直到结束。

附录 A:轴映射

本附录为非规范性内容。

轴映射:ltr + horizontal-tb 书写模式(例如英文)
flex-flow 主轴 起点 终点 交叉轴 起点 终点
row + nowrap/wrap 水平 垂直
row-reverse + nowrap/wrap
row + wrap-reverse
row-reverse + wrap-reverse
column + nowrap/wrap 垂直 水平
column-reverse + nowrap/wrap
column + wrap-reverse
column-reverse + wrap-reverse
轴映射:rtl + horizontal-tb 书写模式(例如波斯语)
flex-flow 主轴 主轴起点 主轴终点 交叉轴 交叉轴起点 交叉轴终点
row + nowrap/wrap 水平 垂直
row-reverse + nowrap/wrap
row + wrap-reverse
row-reverse + wrap-reverse
column + nowrap/wrap 垂直 水平
column-reverse + nowrap/wrap
column + wrap-reverse
column-reverse + wrap-reverse
轴映射:ltr + vertical-rl 书写模式(例如日文)
flex-flow 主轴 起点 终点 交叉轴 起点 终点
row + nowrap/wrap 垂直 水平
row-reverse + nowrap/wrap
row + wrap-reverse
row-reverse + wrap-reverse
column + nowrap/wrap 垂直 水平
column-reverse + nowrap/wrap
column + wrap-reverse
column-reverse + wrap-reverse

附录 B:-webkit- 旧版属性

本附录为规范性内容。

这些别名已废弃,作者不应使用,除非内容需兼容仍在使用的旧版 UA。

为兼容主流 Web 内容, 必须(Web 浏览器)或可以(其他 UA) 实现如下 旧名别名

别名 标准
-webkit-align-content align-content
-webkit-align-items align-items
-webkit-align-self align-self
-webkit-flex flex
-webkit-flex-basis flex-basis
-webkit-flex-direction flex-direction
-webkit-flex-flow flex-flow
-webkit-flex-grow flex-grow
-webkit-flex-shrink flex-shrink
-webkit-flex-wrap flex-wrap
-webkit-justify-content justify-content
-webkit-order order
测试

致谢

感谢以下人员的反馈和贡献:

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。

变更记录

本节记录了自之前版本发布以来的变更内容。

2018年11月19日 CR 以来的变更

可查看 评论处理情况。重要变更包括:

自 2017 年 10 月 16 日 CR 以来的变更

也可查看 评论处理情况

自 2016 年 5 月 26 日 CR 以来的变更

也可查看 评论处理情况

重大变更和缺陷修复

澄清

自 2016 年 3 月 1 日 CR 以来的变更

也可查看 评论处理情况

重大变更和缺陷修复

澄清

自 2015 年 5 月 14 日 LCWD 以来的变更

也可查看 评论处理情况

重大变更和缺陷修复

澄清

自 2014 年 9 月 25 日 LCWD 以来的变更

也可查看 评论处理情况

重大变更和缺陷修复

澄清

自 2014 年 3 月 25 日 LCWD 以来的变更

也可查看 评论处理情况

重大变更和缺陷修复

2014 年 3 月 25 日最后征求意见工作草案 以来进行了如下重要变更

澄清

2014 年 3 月 25 日最后征求意见工作草案 以来还进行了如下重要澄清:

自 2012 年 9 月 18 日候选推荐以来的变更

也可查看 评论处理情况

重大变更和缺陷修复

2012 年 9 月 18 日候选推荐 以来进行了如下重要变更:

澄清

还进行了如下重要澄清:

隐私注意事项

本规范未报告新的隐私注意事项。

安全注意事项

本规范未报告新的安全注意事项。

测试

the order property, now in css-display-3


print stuff


non-specific crashers


need quirks mode


css box 3 tests


unsure/nonspecific


符合性

文档约定

符合性要求通过描述性断言与 RFC 2119 术语的组合来表达。规范性部分中的关键词 “MUST” 、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL” 应按 RFC 2119 的描述进行解释。 不过,为了可读性,本规范中这些词并非全部使用大写字母。

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

本规范中的示例以 “for example” 引入,或通过 class="example" 与规范性文本区分, 例如:

这是一个说明性示例。

说明性注记以 “Note” 开头,并通过 class="note" 与规范性文本区分,例如:

Note,這是一条说明性注记。

提示(Advisement)是为引起特别注意而设置的规范性小节, 并通过 <strong class="advisement"> 与其他规范性文本区分,例如: UA 必须提供一种可访问的替代方案。

测试

与本规范内容相关的测试 可以像这样记录在 “Tests” 区块中。 任何此类区块均为非规范性内容。


符合性类别

对本规范的符合性 定义为以下三类符合性类别:

style sheet
一个 CSS 样式表
renderer
一个 UA,其解释样式表的语义并渲染 使用它们的文档。
authoring tool
一个编写样式表的 UA

若样式表中使用本模块定义语法的所有语句 都根据通用 CSS 语法和本模块中各特性的独立语法有效, 则该样式表符合本规范。

若渲染器除了按相关规范定义解释样式表外, 还能通过正确解析并相应渲染文档来支持 本规范定义的所有特性, 则该渲染器符合本规范。 然而,由于设备限制导致 UA 无法正确渲染文档, 并不会使该 UA 不符合规范。(例如,UA 不要求在单色显示器上渲染颜色。)

若创作工具编写的样式表在语法上符合 通用 CSS 语法以及本模块中各特性的独立语法, 并满足本模块中对样式表描述的所有其他符合性要求, 则该创作工具符合本规范。

部分实现

为使作者能够利用前向兼容的解析规则来 指定回退值,CSS 渲染器必须将任何其不具备可用支持级别的 at-rule、属性、属性值、关键字以及其他语法构造视为无效(并在适当情况下忽略)。 尤其是,用户代理不得在一次 多值属性声明中选择性地忽略不支持的组件值而仅接受支持的值: 如果任一值被视为无效(不支持的值必须如此), CSS 要求整个声明被忽略。

不稳定与专有特性的实现

为避免与未来稳定的 CSS 特性发生冲突, CSSWG 建议在实现 不稳定 特性和 CSS 的专有扩展时,遵循最佳实践

非实验性实现

一旦规范进入候选推荐(CR)阶段, 即可进行非实验性实现,且实现者应 发布任何达到 CR 级别且能证明依规范正确实现的特性的 无前缀实现。

为建立并维护 CSS 在不同实现间的互操作性, CSS 工作组请求非实验性的 CSS 渲染器在发布任何 CSS 特性的无前缀实现之前, 向 W3C 提交实现报告(以及在必要时, 该实现报告所用的测试用例)。 提交至 W3C 的测试用例将由 CSS 工作组审查与修订。

关于提交测试用例与实现报告的更多信息, 可在 CSS 工作组网站 https://www.w3.org/Style/CSS/Test/ 获取。 如有问题,请发送至邮件列表 public-css-testsuite@w3.org

CR 退出标准

为将本规范推进为提议推荐(PR), 必须至少有两个彼此独立且可互操作的 对每个特性的实现。每个特性可以由不同产品集实现, 不要求所有特性由同一产品实现。就此标准而言,我们定义如下术语:

independent
每个实现必须由不同的主体开发,且不得共享、复用或派生 自另一个合格实现所使用的代码。对本规范实现无影响的 代码部分不受此要求约束。
interoperable
通过官方 CSS 测试套件中的相应测试用例, 或(若实现不是 Web 浏览器)通过等效测试。若某类用户代理(UA) 用于声明互操作性,则测试套件中的每个相关测试都应有等效测试被创建。 此外,如该 UA 用于声明互操作性,则必须有一个或多个额外的 UA 也能够以相同方式通过这些等效测试,以满足互操作性的目的。 这些等效测试必须公开以供同行评审。
implementation
指如下的用户代理:
  1. 实现了该规范。
  2. 可供公众使用。该实现可以是已发布的产品或其他公开可用的版本 (例如 beta 版、预览版或 “nightly build”)。 未发布的产品版本必须在至少一个月的时间内 实现该特性,以证明其稳定性。
  3. 非实验性(即并非专为通过测试套件而设计、 且不打算用于今后正常使用的版本)。

该规范将至少保持候选推荐状态六个月。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. 11 March 2025. WD. URL: https://www.w3.org/TR/css-align-3/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 4 August 2024. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-BREAK-4]
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 4. 18 December 2018. FPWD. URL: https://www.w3.org/TR/css-break-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 13 January 2022. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 30 March 2023. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. 19 December 2024. FPWD. URL: https://www.w3.org/TR/css-display-4/
[CSS-FLEXBOX-1]
Tab Atkins Jr.; et al. CSS Flexible Box Layout Module Level 1. 19 November 2018. CR. URL: https://www.w3.org/TR/css-flexbox-1/
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 3. 18 December 2023. CRD. URL: https://www.w3.org/TR/css-images-3/
[CSS-INLINE-3]
Elika Etemad. CSS Inline Layout Module Level 3. 18 December 2024. WD. URL: https://www.w3.org/TR/css-inline-3/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 7 October 2025. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. 7 October 2025. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 27 June 2025. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS Box Sizing Module Level 3. 17 December 2021. WD. URL: https://www.w3.org/TR/css-sizing-3/
[CSS-SIZING-4]
Tab Atkins Jr.; Elika Etemad; Jen Simmons. CSS Box Sizing Module Level 4. 20 May 2021. WD. URL: https://www.w3.org/TR/css-sizing-4/
[CSS-TEXT-4]
Elika Etemad; et al. CSS Text Module Level 4. 29 May 2024. WD. URL: https://www.w3.org/TR/css-text-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 22 March 2024. CRD. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 12 March 2024. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 30 July 2019. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: https://www.w3.org/TR/CSS2/
[CSS3-BREAK]
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 3. 4 December 2018. CR. URL: https://www.w3.org/TR/css-break-3/
[CSS3-WRITING-MODES]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 10 December 2019. REC. URL: https://www.w3.org/TR/css-writing-modes-3/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 26 August 2021. WD. URL: https://www.w3.org/TR/cssom-1/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119

说明性引用

[CSS-TEXT-DECOR-4]
Elika Etemad; Koji Ishii. CSS Text Decoration Module Level 4. 4 May 2022. WD. URL: https://www.w3.org/TR/css-text-decor-4/
[CSS3UI]
Tantek Çelik; Florian Rivoal. CSS Basic User Interface Module Level 3 (CSS3 UI). 21 June 2018. REC. URL: https://www.w3.org/TR/css-ui-3/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/

属性索引

名称 取值 初始值 适用于 继承 百分比 动画类型 规范顺序 计算值
align-content flex-start | flex-end | center | space-between | space-around | stretch stretch 多行弹性容器 no n/a discrete per grammar specified keyword
align-items flex-start | flex-end | center | baseline | stretch stretch 弹性容器 no n/a discrete per grammar specified keyword
align-self auto | flex-start | flex-end | center | baseline | stretch auto 弹性项目 no n/a discrete per grammar specified keyword
flex none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] 0 1 auto 弹性项目 no see individual properties by computed value type per grammar see individual properties
flex-basis content | <'width'> auto 弹性项目 no relative to the flex container’s inner main size by computed value type per grammar specified keyword or a computed <length-percentage> value
flex-direction row | row-reverse | column | column-reverse row 弹性容器 no n/a discrete per grammar specified keyword
flex-flow <'flex-direction'> || <'flex-wrap'> see individual properties see individual properties see individual properties see individual properties see individual properties per grammar see individual properties
flex-grow <number [0,∞]> 0 弹性项目 no n/a by computed value type per grammar specified number
flex-shrink <number [0,∞]> 1 弹性项目 no n/a number per grammar specified value
flex-wrap nowrap | wrap | wrap-reverse nowrap 弹性容器 no n/a discrete per grammar specified keyword
justify-content flex-start | flex-end | center | space-between | space-around flex-start 弹性容器 no n/a discrete per grammar specified keyword

问题索引

一旦确定,将在此概述与 Web 兼容的算法。 [Issue #8884]