Flexbox

CSS 播客 - 010:Flexbox

在自适应设计中,可能比较棘手的设计模式是:内嵌一些边栏的边栏 内容。当有视口空间时 这种模式的效果非常好 但如果空间是密集的, 刚性布局可能会出现问题

灵活框布局模型 (flexbox) 是专为一维内容设计的布局模型。 它擅长处理大量不同尺寸的物品 并返回这些项的最佳布局。

这是此边栏模式的理想布局模型。 Flexbox 不仅能以内嵌方式放置边栏和内容, 但若没有足够的剩余空间,边栏便会另起一行。 与其为浏览器设置固定的尺寸,不如 使用 Flexbox 则可以改为提供灵活的边界来提示内容可以如何展示。

您可以使用 Flex 布局执行哪些操作?

Flex 布局具有以下特点, 我们将在本指南中介绍相关内容

  • 它们可以显示为行,也可以显示为列。
  • 它们遵循文档的书写模式。
  • 默认情况下,它们是单行 但可以要求换行成多行。
  • 布局中的项在视觉上可以重新排序 改变它们在 DOM 中的顺序。
  • 空间可以分布在各项内容内, 这样它们就会根据父单位可用的空间变大或变小
  • 空间可以分布在封装布局中的项和 Flex 行周围, 使用文本框对齐方式属性
  • 这些项本身可以在交叉轴上对齐。

主轴和交叉轴

了解 Flexbox 的关键在于了解主轴和交叉轴的概念。 主轴是您的 flex-direction 属性设置的主轴。 如果值为 row,则主轴沿该行, 如果值为 column,则主轴沿该列。

三个相邻的盒子,每个盒子都带有一个从左到右的箭头。箭头标示为“主轴”

Flex 项作为一个组在主轴上移动。 请记住:我们已经获得了大量内容,并正在努力为小组成员提供最佳布局。

横轴与主轴相反 因此,如果 flex-directionrow,则交叉轴将沿着列延伸。

三个高度不同的箱子,彼此相邻,中间有一个箭头从左到右。箭头标记为主轴。还有一个指向顶部指向底部的箭头。这个图表标记为“交叉轴”

您可以在交叉轴上做两件事。 您可以单独移动或成组移动项目,使其彼此对齐 容器。此外,如果使用了封装在一起的弹性行 您可以将这些行视为一组,以控制为这些行分配空间的方式。 在本指南中,您将了解所有这些操作的实际运作方式。 现在只需注意,主轴跟随 flex-direction

创建 flex 容器

我们来看一下 Flexbox 的行为方式,即接收一组不同大小的项,然后使用 Flexbox 进行 删除它们。

<div class="container" id="container">
  <div>One</div>
  <div>Item two</div>
  <div>The item we will refer to as three</div>
</div>

要使用 Flexbox,您需要声明要使用 Flex 格式上下文而不是常规 代码块和内嵌布局。 为此,请将 display 属性的值更改为 flex

.container {
  display: flex;
}

正如您在布局指南中所了解到的,这将为您提供一个块级框, 以及 Flex item 子项。 Flex 项会根据其初始值立即开始表现出某些 Flexbox 行为。

初始值表示:

  • 内容显示为一行。
  • 不换行。
  • 它们不会变大来填满容器。
  • 它们在容器的开头处对齐。

控制项的方向

即使您尚未添加 flex-direction 资源, 由于 flex-direction 的初始值为 row,因此各项内容显示为一行。 如果您只需要添加一行,则无需添加相应属性。 要更改方向,请添加 属性和以下四个值之一:

  • row:项排列成行。
  • row-reverse:,这些项从 flex 容器末尾排列为一行。
  • column:项以列的形式排列。
  • column-reverse:这些项从 Flex 容器末尾排列为一列。

您可以通过以下演示中的项目组尝试所有值。

逆转内容流程和无障碍功能

在使用任何对视觉显示重新排序的属性时,您应保持谨慎 而不再局限于 HTML 文档中内容的排序方式 因为这可能会给无障碍功能带来负面影响。 row-reversecolumn-reverse 值就是一个很好的示例。 重新排序只会针对视觉顺序(而非逻辑顺序)。 这一点很重要,因为逻辑顺序就是屏幕阅读器读出的顺序 内容、 所有使用键盘导航的人都会跟随

通过以下视频,您可以了解到 当键盘导航遵循 DOM(而非可视化)时,链接之间的 Tab 键会断开连接 。

任何能够更改 Flexbox 或网格中项顺序的内容都可能会导致此问题。 因此,任何重新排序都应包括全面的测试,确保网站不会 对某些人来说很难使用。

如需了解详情,请参阅以下内容:

书写模式和方向

默认情况下,Flex 项以行的形式显示。 一行的运行方向为句子在书写模式和脚本方向上的流动方向。 也就是说,如果您使用的是阿拉伯语 (即从右到左 (rtl) 脚本方向)对应的列表项会在右侧排列。 制表符顺序也会从右侧开始,因为这是阿拉伯语朗读句子的方式。

如果您使用的是竖向书写模式, 就会有一行从上到下垂直排列 请尝试在此演示(使用垂直书写模式)中更改 flex-direction

因此,Flex 项的默认行为方式与文档的写入模式相关联。 大多数教程都是使用英语或其他水平的 从左向右书写模式。 这样就很容易假设弹性项靠左侧排成,并且是水平运行。

根据主轴和横轴以及书写模式, 事实上,在上述示例中我们谈论的是 startend,而不是顶部、底部、左侧和右侧。 那么 Flexbox 可能更易于理解。 每个轴都有起点和终点。 主轴的起点称为 main-start。 因此,我们的 Flex 项目最初是从主线程开始排列的。 该轴的终点是 main-end。 交叉轴的起点为 cross-start 且结束的 cross-end

上述术语的带标签图

封装 Flex 项

flex-wrap 属性的初始值为 nowrap。 这意味着,如果容器中没有足够的空间,这些项就会溢出。

<ph type="x-smartling-placeholder">
</ph> 一个 Flex 容器,里面有九个项目,这些项目已经缩小,一个单词占一行
但没有足够的空间并排显示它们,所以 Flex 项目延伸到了
容器。 <ph type="x-smartling-placeholder">
</ph> 一旦达到内容大小下限,Flex 项目就会开始溢出其容器

使用初始值显示的项目会尽可能缩小, 缩减至 min-content 大小后才会发生溢出。

如需使项封装,请向 flex 容器添加 flex-wrap: wrap

.container {
  display: flex;
  flex-wrap: wrap;
}

当 Flex 容器封装时,它会创建多个 Flex 行。 就空间分布而言 每一行都像一个新的 Flex 容器。 因此,如果要对行进行封装 第 2 行中的内容不可能与第 1 行中其上的内容对齐。 这就是 Flexbox 一维的意义。 您可以控制单轴、行或列的对齐方式, 不能像在网格中那样同时设置这两者

Flex-flow 简写形式

您可以使用简写形式 flex-flow 设置 flex-directionflex-wrap 属性。 例如,如需将 flex-direction 设置为 column 并允许内容换行,请使用以下代码:

.container {
  display: flex;
  flex-flow: column wrap;
}

控制 Flex 项内的空间

假设容器的空间超出了显示列表项所需的空间, 这些项在开始时排成一行,并且不会变大以填满空间。 它们不会再达到内容大小上限。 这是因为 flex- 属性的初始值为:

  • flex-grow: 0:内容不会增长。
  • flex-shrink: 1:项可以缩小到其 flex-basis 以下。
  • flex-basis: auto:项目的基本大小为 auto

可以用 flex: initial 的关键字值表示。 flex 简写属性, 或者 flex-growflex-shrinkflex-basis 的长手应用于 Flex 容器。

要使这些项变大 同时允许大型内容比小型内容拥有更多空间,请使用 flex:auto。 您可以使用上面的演示来尝试此操作。 这会将属性设为:

  • flex-grow: 1:内容可以大于其 flex-basis
  • flex-shrink: 1:项可以缩小到其 flex-basis 以下。
  • flex-basis: auto:项目的基本大小为 auto

使用 flex: auto 意味着商品最终将获得不同的尺寸, 因为各项内容之间共享的空间会在每项内容按顺序排列之后 最大内容大小。 因此大型内容将会占据更多空间。 强制所有项使用一致的大小,并忽略内容更改的大小 在演示中将 flex:auto 更改为 flex: 1

这会解压缩到:

  • flex-grow: 1:内容可以大于其 flex-basis
  • flex-shrink: 1:项可以缩小到其 flex-basis 以下。
  • flex-basis: 0:项目的基本大小为 0

使用 flex: 1 表示所有项的大小都为零, 因此 Flex 容器中的所有空间都可以进行分配。 由于所有项的 flex-grow 系数为 1,因此它们的增长率相同,且空间均等。

允许不同项以不同的速率成长

您不必为所有项都设置 1flex-grow 因子。 您可以为 Flex 项目指定不同的 flex-grow 因子。 在下面的演示中,第一项具有 flex: 1、第二个 flex: 2 和第三个 flex: 3。 随着这些项从 0 增大,弹性容器中的可用空间会共享为六个。 其中一个部分分配给第一项, 分为两部分 分为三部分

您可以通过 autoflex-basis 执行相同的操作,但您需要指定上述三个参数, 值。 第一个值为 flex-grow, 第二个flex-shrink, 以及第三个 flex-basis

.item1 {
  flex: 1 1 auto;
}

.item2 {
  flex: 2 1 auto;
}

这是一个不太常见的用例,因为要使用 autoflex-basis 那就是让浏览器了解空间分布 如果您想使某个项的增长幅度超出算法确定的幅度,那么它可能是 实用。

对 Flex 项重新排序

可以使用 order 属性对 Flex 容器中的项进行重新排序。 此属性允许对序数组中的项进行排序。 项的布局方向由 flex-direction 指定, 最小值。 如果多个项目具有相同的值,则该应用将与具有该值的其他项目一起显示。

以下示例演示了这种排序。

检查您的理解情况

测试您对 Flexbox 相关知识的掌握情况

flex-direction 的默认值为

row
默认情况下,Flexbox 会将内容放入一行,并在开头将它们排成一行。开启封装功能后,系统会继续创建可供子项在其中流动的行。
column
将 flex-direction 设置为 column 是堆叠元素的好方法,但它不是默认值。

默认情况下,Flex 容器封装了子节点。

true
必须启用封装功能。
false
结合使用 flex-wrap: wrapdisplay: flex 来封装子项

Flex 子项显示为挤压,下面哪个 Flex 属性有助于缓解这种情况?

flex-grow
此属性描述元素是否可以超出基础大小,而不是其在基础大小下的行为方式。
flex-shrink
可以,此属性说明了当宽度低于基准时如何处理尺寸。
flex-basis
这提供了尺寸调整的起点,但不是如何处理宽度低于基准的尺寸调整场景(例如在挤压场景中)。

Flexbox 对齐概览

Flexbox 自带一组属性,可用于对齐项目和分配项目之间的空间。 这些属性非常实用,后来将它们转移到了他们自己的规范中, 您也会在“网格布局”中遇到它们。 您可在此处了解在使用 Flexbox 时它们是如何运作的。

这组属性可以分成两组。 空间分布属性以及对齐属性。 分布空间的属性包括:

  • justify-content:主轴上的空间分布。
  • align-content:交叉轴上的空间分布。
  • place-content:用于设置上述两个属性的简写形式。

Flexbox 中用于对齐的属性:

  • align-self:在交叉轴上对齐单个项。
  • align-items:在交叉轴上将所有项作为一个组对齐。

如果您处理主轴,则属性以 justify- 开头。 在交叉轴上,它们以 align- 开头。

在主轴上分配空间

在前面使用的 HTML 中,Flex 项排列成一行,因此主轴上有足够的空间。 这些项不够大,无法完全填满 Flex 容器。 这些项会在 flex 容器的开头排列,因为 justify-content 的初始值 为 flex-start。 这些条目在开头排列,任何多余的空格都位于末尾。

justify-content 属性添加到 Flex 容器中, 将其值设为flex-end 物品在容器末端排列,腾出空间放在起始位置。

.container {
  display: flex;
  justify-content: flex-end;
}

您还可以使用 justify-content: space-between 在项之间分配空间。

尝试演示中的一些值, 并参阅 MDN,获取完整的 可能的值。

活动门票提供商:flex-direction: column

如果您已将 flex-direction 更改为 column,那么 justify-content 将可以继续正常使用 。 当以列的形式工作时,要在容器中拥有空闲空间,您需要为容器提供一个 heightblock-size。 否则,您没有多余的空间可供分发。

这次使用 Flexbox 列布局,尝试不同的值。

在柔性线条之间分配空间

对于封装的 Flex 容器,您可能在交叉轴上留出了分布空间。 在这种情况下,您可以使用与 justify-content 相同的 align-content 属性。 与默认将项对齐到 flex-startjustify-content 不同, align-content 的初始值为 stretch。 将属性 align-content 添加到 flex 容器以更改该默认行为。

.container {
  align-content: center;
}

请在演示中试用此功能。 该示例包含 Flex 项的换行行, 并且容器具有 block-size,以便为我们留出一些空闲空间。

place-content 简写形式

如需同时设置 justify-contentalign-content,您可以将 place-content 与其中一项搭配使用 或两个值。 两个轴将使用同一值 如果您同时指定了第一个用于 align-content,第二个则用于 justify-content

.container {
  place-content: space-between;
  /* sets both to space-between */
}

.container {
  place-content: center flex-end;
  /* wrapped lines on the cross axis are centered,
  on the main axis items are aligned to the end of the flex container */
}

在交叉轴上对齐项目

在交叉轴上,您还可以使用 align-items 对齐弹性线条中的项 和 align-self。 可用于这种对齐的空间将取决于 Flex 容器的高度, 或 Flex 行。

align-self 的初始值为 stretch, 这就是为什么默认情况下,一行中的 Flex 项会拉伸到最高项的高度。 如需更改此设置,请向任意 Flex 项添加 align-self 属性。

.container {
  display: flex;
}

.item1 {
  align-self: flex-start;
}

使用以下任一值来对齐项:

  • flex-start
  • flex-end
  • center
  • stretch
  • baseline

请参阅 MDN 上的完整值列表

下一个演示包含一行包含 flex-direction: row 的 Flex 项。 最后一项定义 Flex 容器的高度。 第一项的 align-self 属性的值为 flex-start。 尝试更改该属性的值,看看它在交叉轴上如何在其空间内移动。

align-self 属性适用于单个项。 align-items 属性可以应用于 Flex 容器 将所有单独的 align-self 属性设为一个组。

.container {
  display: flex;
  align-items: flex-start;
}

在下一个演示中,请尝试更改 align-items 的值,以对齐交叉路口上的所有项目 将它们视为一个组

为什么 Flexbox 中没有“ Justify-self”?

Flex 项在主轴上以组的形式发挥作用。 因此,您无法从该组中拆分单个项。

在网格布局中,justify-selfjustify-items 属性适用于内嵌轴 将各项内容在该轴上的网格区域内对齐。 由于 Flex 布局将列表项视为一个组, 这些属性在 flex 环境中无法实现。

需要注意的是,Flexbox 非常适合使用自动外边距。 如果您需要将某一项从一组中分离出来, 或者将分组分为两组 在下面的示例中,最后一项的左外边距为 auto。 自动外边距会吸收应用方向上的所有空间。 这意味着它将该项推送到右侧,从而拆分组。

如何使内容垂直居中和水平居中

对齐方式属性可用于将某个项居中放置在另一个框内。 justify-content 属性在主轴上对齐项, 也就是第 1 行。交叉轴上的 align-items 属性。

.container {
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

检查您的理解情况

测试您对 Flexbox 相关知识的掌握情况

.container {
  display: flex;
  direction: ltr;
}

要与 Flexbox 垂直对齐,请使用

对齐关键字
不错
两全其美
抱歉
.container {
  display: flex;
  direction: ltr;
}

要与 Flexbox 水平对齐,请使用

对齐关键字
抱歉
两全其美
不错
.container {
  display: flex;
  direction: ltr;
}

默认情况下,Flex 项会与 stretch 对齐。想要内容 尺寸,您会使用以下哪种样式?

justify-content: flex-start
两端对齐属性用于水平对齐,而不是垂直对齐。
align-content: start
content 会对齐 Flex 行,而不是对齐子项。
height: auto
此操作不会产生任何影响。
align-items: flex-start
是,我们希望垂直地将它们与“顶部”对齐或 start,后者将移除默认的拉伸值,改为使用内容高度。

资源