flex布局是目前常用的一种布局方式,这篇文章主要对flex的常用基础知识做一个整理。
1、flex简介
flex布局是一种一维布局(网格布局则是一种二维布局)。这种布局主要作用于父级容器,通过控制父级容器的排列规则来达到需要的效果。任何一个元素都可以使用flex布局,只要给元素添加display: flex;即可。我们把添加了display: flex;的元素称为容器,元素内部的子元素称为项目。

从上图我们可以看出,flex布局的容器默认存在两条轴(主轴和侧轴),我们的布局就基于这两条轴。我们可以简单的理解为x轴和y轴。这时有人可能会有疑问,既然有两个方向,为什么要叫一维布局而不是二维布局呢?我的理解是这样:虽然我们可以在两个方向对元素进行排列,达到类似二维的效果,但事实上仅仅使用flex布局并不能够精确的定位到二维平面的所有位置(网格布局可以,它是目前最强大的css布局方法),它是主要控制主轴上的排列,然后在侧轴上进行调整。接下来就这两条轴分别介绍flex布局的用法。
2、主轴上的设置
flex布局在主轴上会让子元素默认排成一行,此时的子元素具有行内块元素的性质。如果设置了每个子元素的宽度,当父级元素宽度足够时正常显示,如果父级元素宽度不够,则每个子元素的宽度会按比例压缩,充满整个父级元素。
如下:
<div class="container">
<div class="items">1</div>
<div class="items">2</div>
<div class="items">3</div>
<div class="items">4</div>
<div class="items">5</div>
</div>
.container {
display: flex;
width: 400px;
border: 1px solid #000;
}
.items {
width: 100px;
height: 100px;
background-color: pink;
}
.items:last-child {
width: 300px;
}

(前4子元素宽度为57.14px,最后一个子元素宽度为171.42px,可以看出它们按比例缩放了)
由于flex布局默认显示在一行,因此如果我们想要它换行显示,则需要使用flex-wrap属性进行控制。它有3个值:
| 属性 | 作用 |
|---|---|
| nowrap | 不换行(默认值) |
| wrap | 超出父级元素宽度时换行显示,第一行在上方 |
| wrap-reverse | 超出父级元素宽度时换行显示,第一行在下方 |
flex-wrap: wrap;

(父级元素宽度不够,换行显示,第一行在上面)
flex-wrap: wrap-reverse;

(父级元素宽度不够,换行显示,第一行在下面)
在主轴上,我们通常通过justify-content来控制子元素的排列方式,它有以下几个值:
| 属性 | 作用 |
|---|---|
| flex-start | 子元素左对齐(默认值) |
| flex-end | 子元素右对齐 |
| center | 子元素居中排列 |
| space-around | 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 |
| space-between | 两端对齐,项目之间的间隔都相等 |
justify-content: flex-start;

justify-content: flex-end;

justify-content: center;

justify-content: space-around;

justify-content: space-between;

2、侧轴上的设置
侧轴上主要由alitn-items和align-content进行设置。其中align-items只针对单行,即在侧轴方向上只有一行,如果有多行则需要使用align-content。
align-items有如下值:
| 属性 | 作用 |
|---|---|
| flex-start | 侧轴方向上从上向下排列 |
| flex-end | 侧轴方向上从下向上排列 |
| center | 侧轴方向上居中排列 |
| stretch | 侧轴方向上拉伸撑满整个父盒子高度(只在子盒子未设置高度时或高度设为auto时生效)(默认值) |
| baseline | 项目的第一行文字的基线对齐。 |
align-items: flex-start;

align-items: flex-end;

align-items: center;

align-items: strench;

align-items: baseline;

align-content有如下值:
| 属性 | 作用 |
|---|---|
| flex-start | 侧轴方向上靠上方排列 |
| flex-end | 侧轴方向上靠下方排列 |
| flex-center | 侧轴方向上居中排列 |
| stretch | 侧轴方向上拉伸撑满整个父盒子高度(只在子盒子未设置高度时或高度设为auto时生效)(默认值) |
| space-around | 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 |
| space-between | 两端对齐,项目之间的间隔都相等 |
align-content: flex-start;

align-content: flex-end;

align-content: center;

align-content: stretch;

align-content: space-around;

align-content: space-between;

4、其余部分
上面我们介绍了怎样在主轴和侧轴上控制元素的排列方式(注意:这些样式都是添加在父级元素上的,即添加了display: flex;的元素),但是仅仅这样是不够的,一些情况需要对子元素做特殊处理,还有一些情况需要调换主轴和侧轴(默认情况下主轴从左指向右,侧轴从上指到下)。还有时候我们也需要控制子元素的排列方式。这时我们就需要知道下面的这些属性。
- flex-direction设置主轴方向
- align-self 对某个子元素单独设置排列方式
- order 控制子元素的排列顺序
- flex-grow 定义子元素的放大比例
- flex-shrink 定义了子元素的缩小比例
- flex-basis 定义了在分配多余空间之前,子元素占据的主轴空间
flex-direction有以下值:
| 属性 | 作用 |
|---|---|
| row | 主轴方向设为x轴方向,起点在左边(默认) |
| row-reverse | 主轴方向设为x轴方向,起点在右边 |
| column | 主轴方向设为y轴方向,起点在左边 |
| column-reverse | 主轴方向设为y轴方向,起点在右边 |
flex-direction: row;

flex-direction: row-reverse;

flex-direction: column;

flex-direction: column-reverse;

有时候我们需要同时设置主轴方向和换行显示,这时可以使用flex-flow,它是一种简写形式。如下:
flex-flow: column wrap;
上面代码设置了主轴方向为y轴,并且换行显示。
上面的所有设置都在父级元素上,下面的则是设置在子元素上。
align-self有如下值,它设置在某一个子元素上,覆盖父元素的样式,单独控制这个子元素的样式:
| 属性 | 作用 |
|---|---|
| auto | 继承父元素的align-items(默认) |
| flex-start | 与align-items效果相同 |
| flex-end | 与align-items效果相同 |
| center | 与align-items效果相同 |
| stretch | 与align-items效果相同 |
| baseline | 与align-items效果相同 |
例如,在第2个子元素上设置如下样式:
align-self: flex-end;

order可以控制主轴上子元素的排列顺序,每个子元素的order默认为0。例如给最后一个子元素的order设置为-1。
order: -1;

从上面可以看出,order越小排列越靠前。这里很多人会将order和z-index混淆,z-index越大越靠近用户,小的则被大的遮挡。事实上order和z-index是同一回事,看看下面这张图就明白了。

flex布局默认主轴为x轴,order事实上就相当于x轴上的坐标,order越小自然在x轴上越靠前。主轴为y轴时同理。而定位实际相当于ps里面的图层,对应的是z轴,如下:

如上图,num1小于num2,则对应的元素排在后面。这就解释了为什么z-index越大越靠前。
flex-grow用于控制主轴上子元素的放大比例。默认为0,即元素的本来宽度。如果flex-grow设为1,则子元素会撑满剩余宽度。如下:

上图前5个元素设置了固定宽度,第6个元素没有设置宽度,但是flex-grow为1,因此撑满了剩余的宽度。如果有多个元素设置了flex-grow,则按比例平分剩余宽度(父级宽度减去所有设置了固定宽度的元素),此时宽度计算公式如下:
元素宽度 = 元素本身宽度 + 按比例平分父级元素剩余宽度后得到的宽度
上面的公式只适用于父级元素宽度足够的情况。
flex-shrink用于控制主轴上子元素的缩小比例。默认为1,即如果父元素宽度不够则子元素等比例缩小。如果其中一个设为0,则这个子元素不缩放。

上图元素等比例缩放。如果将第二个元素flex-shrink设为0,则如下:

等比例缩小时最多变回原来大小,即不缩放时候的大小(也就是下面要讲的flex-basis的大小)。如下:

flex-basis表示在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即子元素的本来大小。如下:

上图两个元素宽度都为100px,父盒子宽度为200px,但是第一个元素的flex-basis为150px,因此第二个元素被缩小了。此时第一个元素的flex-basis为150px,第二个元素为100px,浏览器根据这两个值进行等比例缩小,则计算后第一个盒子宽度为120px,第二个盒子宽度为80px。
上面的三个样式如果每次都要一个个写过于麻烦,此时可以使用简写形式:
flex: flex-grow flex-shrink flex-basis;
其中flex-grow必须写,后两个可以省略,省略后取默认值。因此flex: 1;相当于flex: 1 1 auto;通常我们都只用这种简写形式。flex属性有两个快捷值: flex: auto;相当于flex: 1;,flex: none;相当于flex: 0 0 auto;
以上。
参考链接
[1] 阮一峰-Flex布局教程
Flex布局详解:主轴侧轴设置与实战应用
本文深入浅出地介绍了Flex布局的基础知识,包括主轴和侧轴的设置,如flex-wrap、justify-content、align-items等属性的用法,以及如何通过flex-grow、flex-shrink和flex-basis控制子元素的尺寸变化。通过实例展示了在不同场景下如何灵活运用Flex布局实现各种布局效果,是前端开发者掌握Flex布局的必备教程。
1万+

被折叠的 条评论
为什么被折叠?



