1. flex 布局是什么
Flex是Flexible Box的缩写,翻译成中文就是“弹性盒子”,用来为盒装模型提供最大的灵活性。任何一个容器都可以指定为Flex布局。是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。
引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。
2. 基本概念
2.1 弹性盒
flex
(弹性盒、伸缩盒)
- 是css中的又一种布局手段,它主要用来代替浮动来完成页面的布局
flex
可以使元素具有弹性,让元素可以跟随页面的大小的改变而改变
2.2 弹性容器
要使用弹性盒,必须先将一个元素设置为弹性容器
通过 display
来设置弹性容器
display:flex
设置为块级弹性容器display:inline-flex
设置为行内的弹性容器
2.3 弹性元素
- 弹性容器的子元素是弹性元素(弹性项)
- 弹性元素可以同时是弹性容器
3. 学习弹性盒子(代码来源自MDN)
一个简单的例子
代码如下:
1 |
|
这个页面有一个含有顶级标题的<header>
元素,和一个包含三个<article>
的<section>
元素,
指定元素的布局为 flexible
我们需要选择将哪些元素将设置为柔性的盒子。我们需要给这些 flexible 元素的父元素 display
设置一个特定值。在本例中,我们想要设置<article>
元素,因此我们给<section>
元素设置display:
1 | section { |
结果如下:
flex 模型说明
当元素表现为 flex 框时,它们沿着两个轴来布局:
- 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。
- 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
- 设置了
display: flex
的父元素(在本例中是 ``)被称之为 flex 容器(flex container)。 - 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项(flex item)(本例中是
<article>
元素。
排列方式
flex-direction
指定容器中弹性元素的排列方式。可选值:
row
默认值,弹性元素在容器中水平排列(自左向右)row-reverse
弹性元素在容器中反向水平排列(自右向左)column
弹性元素纵向排列(自上向下)column-reverse
弹性元素反向纵向排列(自下向上)
换行
当你在布局中使用定宽或者定高的时候,可能会出现问题即处于容器中的 弹性盒子子元素会溢出,破坏了布局。解决此问题的一种方法是设置元素自动换行,将以下声明添加到 <section>
css 规则中:
1 | flex-wrap: wrap |
同时,把以下规则也添加到<article>
的css规则中:
1 | flex: 200px; |
flex-flow 缩写
flex-flow
是flex-direction
和flex-wrap
的简写属性
flex 项的动态尺寸
我们来看看是如何控制 flex 项占用空间的比例的。
首先,我们添加下面的规则到CSS底部:
1 | article { |
这是一个无单位的比例值,表示每个 flex 项沿主轴的可用空间大小。我们设置<article>
flex值都为1,表示每个元素占用一样的空间,占用的空间是在设置 padding 和 margin 之后剩余的空间。
现在在上一个规则下添加:
1 | article:nth-of-type(3) { |
会看到第三个<article>
元素占用了两倍的可用宽度和剩下的一样,因为现在的比例是1:1:2。
水平与垂直对齐
还可以使用弹性盒子的功能让 flex 项沿主轴或交叉轴对齐。
align-items
控制 flex 项在交叉轴上的位置。
- 默认的值是
stretch
,其会使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。我们的第一个例子在默认情况下得到相等的高度的列的原因。 - 在上面规则中我们使用的
center
值会使这些项保持其原有的高度,但是会在交叉轴居中。这就是那些按钮垂直居中的原因。 - 你也可以设置诸如
flex-start
或flex-end
这样使 flex 项在交叉轴的开始或结束处对齐所有的值。
justify-content
控制 flex 项在主轴上的位置。
- 默认值是
flex-start
,这会使所有 flex 项都位于主轴的开始处。 - 你也可以用
flex-end
来让 flex 项到结尾处。 center
在justify-content
里也是可用的,可以让 flex 项在主轴居中。- 而我们上面用到的值
space-around
是很有用的——它会使所有 flex 项沿着主轴均匀地分布,在任意一端都会留有一点空间。 - 还有一个值是
space-between
,它和space-around
非常相似,只是它不会在两端留下任何空间。
flex 项排序
弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。
示例代码:
1 | button:first-child { |
然后第一个button就移到了主轴末尾。
- 所有 flex 项默认的
order
值是 0。 - order 值大的 flex 项比 order 值小的在显示顺序中更靠后。
- 相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是2,1,1和0,那么它们的显示顺序就分别是第四,第二,第三,和第一。
- 第三个元素显示在第二个后面是因为它们的 order 值一样,且第三个元素在源顺序中排在第二个后面。
flex 嵌套
弹性盒子也能创建一些颇为复杂的布局。设置一个元素为flex项目,那么他同样成为一个 flex 容器,它的孩子(直接子节点)也表现为 flexible box 。可以去这里跟着实例学习。
GitHub Issues