CSS 播客 - 010:Flexbox
在自适应设计中,可能比较棘手的设计模式是:内嵌一些边栏的边栏 内容。当有视口空间时 这种模式的效果非常好 但如果空间是密集的, 刚性布局可能会出现问题
灵活框布局模型 (flexbox) 是专为一维内容设计的布局模型。 它擅长处理大量不同尺寸的物品 并返回这些项的最佳布局。
这是此边栏模式的理想布局模型。 Flexbox 不仅能以内嵌方式放置边栏和内容, 但若没有足够的剩余空间,边栏便会另起一行。 与其为浏览器设置固定的尺寸,不如 使用 Flexbox 则可以改为提供灵活的边界来提示内容可以如何展示。
您可以使用 Flex 布局执行哪些操作?
Flex 布局具有以下特点, 我们将在本指南中介绍相关内容
- 它们可以显示为行,也可以显示为列。
- 它们遵循文档的书写模式。
- 默认情况下,它们是单行 但可以要求换行成多行。
- 布局中的项在视觉上可以重新排序 改变它们在 DOM 中的顺序。
- 空间可以分布在各项内容内, 这样它们就会根据父单位可用的空间变大或变小
- 空间可以分布在封装布局中的项和 Flex 行周围, 使用文本框对齐方式属性
- 这些项本身可以在交叉轴上对齐。
主轴和交叉轴
了解 Flexbox 的关键在于了解主轴和交叉轴的概念。
主轴是您的 flex-direction
属性设置的主轴。
如果值为 row
,则主轴沿该行,
如果值为 column
,则主轴沿该列。
Flex 项作为一个组在主轴上移动。 请记住:我们已经获得了大量内容,并正在努力为小组成员提供最佳布局。
横轴与主轴相反
因此,如果 flex-direction
为 row
,则交叉轴将沿着列延伸。
您可以在交叉轴上做两件事。
您可以单独移动或成组移动项目,使其彼此对齐
容器。此外,如果使用了封装在一起的弹性行
您可以将这些行视为一组,以控制为这些行分配空间的方式。
在本指南中,您将了解所有这些操作的实际运作方式。
现在只需注意,主轴跟随 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-reverse
和 column-reverse
值就是一个很好的示例。
重新排序只会针对视觉顺序(而非逻辑顺序)。
这一点很重要,因为逻辑顺序就是屏幕阅读器读出的顺序
内容、
所有使用键盘导航的人都会跟随
通过以下视频,您可以了解到 当键盘导航遵循 DOM(而非可视化)时,链接之间的 Tab 键会断开连接 。
任何能够更改 Flexbox 或网格中项顺序的内容都可能会导致此问题。 因此,任何重新排序都应包括全面的测试,确保网站不会 对某些人来说很难使用。
如需了解详情,请参阅以下内容:
书写模式和方向
默认情况下,Flex 项以行的形式显示。 一行的运行方向为句子在书写模式和脚本方向上的流动方向。 也就是说,如果您使用的是阿拉伯语 (即从右到左 (rtl) 脚本方向)对应的列表项会在右侧排列。 制表符顺序也会从右侧开始,因为这是阿拉伯语朗读句子的方式。
如果您使用的是竖向书写模式,
就会有一行从上到下垂直排列
请尝试在此演示(使用垂直书写模式)中更改 flex-direction
。
因此,Flex 项的默认行为方式与文档的写入模式相关联。 大多数教程都是使用英语或其他水平的 从左向右书写模式。 这样就很容易假设弹性项靠左侧排成,并且是水平运行。
根据主轴和横轴以及书写模式, 事实上,在上述示例中我们谈论的是 start 和 end,而不是顶部、底部、左侧和右侧。 那么 Flexbox 可能更易于理解。 每个轴都有起点和终点。 主轴的起点称为 main-start。 因此,我们的 Flex 项目最初是从主线程开始排列的。 该轴的终点是 main-end。 交叉轴的起点为 cross-start 且结束的 cross-end。
封装 Flex 项
flex-wrap
属性的初始值为 nowrap
。
这意味着,如果容器中没有足够的空间,这些项就会溢出。
![一个 Flex 容器,里面有九个项目,这些项目已经缩小,一个单词占一行
但没有足够的空间并排显示它们,所以 Flex 项目延伸到了
容器。](https://web.developers.google.cn/static/learn/css/flexbox/image/a-flex-container-nine-it-e0d8b646b8c9c.jpg?authuser=7&hl=ro)
使用初始值显示的项目会尽可能缩小,
缩减至 min-content
大小后才会发生溢出。
如需使项封装,请向 flex 容器添加 flex-wrap: wrap
。
.container {
display: flex;
flex-wrap: wrap;
}
当 Flex 容器封装时,它会创建多个 Flex 行。 就空间分布而言 每一行都像一个新的 Flex 容器。 因此,如果要对行进行封装 第 2 行中的内容不可能与第 1 行中其上的内容对齐。 这就是 Flexbox 一维的意义。 您可以控制单轴、行或列的对齐方式, 不能像在网格中那样同时设置这两者
Flex-flow 简写形式
您可以使用简写形式 flex-flow
设置 flex-direction
和 flex-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-grow
、flex-shrink
和 flex-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
,因此它们的增长率相同,且空间均等。
允许不同项以不同的速率成长
您不必为所有项都设置 1
的 flex-grow
因子。
您可以为 Flex 项目指定不同的 flex-grow
因子。
在下面的演示中,第一项具有 flex: 1
、第二个 flex: 2
和第三个 flex: 3
。
随着这些项从 0
增大,弹性容器中的可用空间会共享为六个。
其中一个部分分配给第一项,
分为两部分
分为三部分
您可以通过 auto
的 flex-basis
执行相同的操作,但您需要指定上述三个参数,
值。
第一个值为 flex-grow
,
第二个flex-shrink
,
以及第三个 flex-basis
。
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
这是一个不太常见的用例,因为要使用 auto
的 flex-basis
那就是让浏览器了解空间分布
如果您想使某个项的增长幅度超出算法确定的幅度,那么它可能是
实用。
对 Flex 项重新排序
可以使用 order
属性对 Flex 容器中的项进行重新排序。
此属性允许对序数组中的项进行排序。
项的布局方向由 flex-direction
指定,
最小值。
如果多个项目具有相同的值,则该应用将与具有该值的其他项目一起显示。
以下示例演示了这种排序。
检查您的理解情况
测试您对 Flexbox 相关知识的掌握情况
flex-direction
的默认值为
row
column
默认情况下,Flex 容器封装了子节点。
flex-wrap: wrap
和 display: 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
将可以继续正常使用
。
当以列的形式工作时,要在容器中拥有空闲空间,您需要为容器提供一个
height
或 block-size
。
否则,您没有多余的空间可供分发。
这次使用 Flexbox 列布局,尝试不同的值。
在柔性线条之间分配空间
对于封装的 Flex 容器,您可能在交叉轴上留出了分布空间。
在这种情况下,您可以使用与 justify-content
相同的 align-content
属性。
与默认将项对齐到 flex-start
的 justify-content
不同,
align-content
的初始值为 stretch
。
将属性 align-content
添加到 flex 容器以更改该默认行为。
.container {
align-content: center;
}
请在演示中试用此功能。
该示例包含 Flex 项的换行行,
并且容器具有 block-size
,以便为我们留出一些空闲空间。
place-content
简写形式
如需同时设置 justify-content
和 align-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-self
和 justify-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