Flex 布局目前已经非常流行了,现在几乎已经兼容所有浏览器了。在文章开始之前我们需要思考一个问题:我们为什么要使用 Flex 布局?
其实答案很简单,那就是 Flex 布局好用。一个新事物的出现往往是因为旧事物不那么好用了,比如,如果想让你用传统的 css 布局来实现一个块元素垂直水平居中你会怎么做?实现水平居中很简单,margin: 0 auto
就行,而实现垂直水平居中则可以使用定位实现:
<div class="container"> <div class="item"></div> </div>
.container { position: relative; width: 300px; height: 300px; background: red; } .item { position: absolute; background: black; width: 50px; height: 50px; margin: auto; left: 0; top: 0; bottom: 0; right: 0; }
或者
.item { position: absolute; background: black; width: 50px; height: 50px; margin: auto; left: calc(50% - 25px); top: calc(50% - 25px); }
但是这样都显得特别繁琐,明明可以一个属性就能解决的事情没必要写这么麻烦。而使用 Flex 则可以使用 place-content 属性简单的实现(place-content 为 justify-content 和 align-content 简写属性)
.container { width: 300px; height: 300px; background: red; display: flex; flex-wrap:wrap; place-content: center; } .item { background: black; width: 50px; height: 50px; }
接下来的本篇文章将会带领大家一起来探讨Flex
布局
基本概念
我们先写一段代码作为示例(部分属性省略)
html
<div class="container"> <div class="item">flex项目</div> <div class="item">flex项目</div> <div class="item">flex项目</div> <div class="item">flex项目</div> </div>
.container { display: flex; width: 800px; gap: 10px; } .item { color: #fff; }
flex 容器
我们可以将一个元素的 display 属性设置为 flex,此时这个元素则成为flex 容器比如container
元素
flex 项目
flex 容器的子元素称为flex 项目,比如item
元素
轴
flex 布局有两个轴,主轴和交叉轴,至于哪个是主轴哪个是交叉轴则有flex 容器的flex-direction
属性决定,默认为:flex-direction:row
,既横向为主轴,纵向为交叉轴,
flex-direction
还可以设置其它三个属性,分别为row-reverse
,column
,column-reverse
。
- row-reverse
- column
- column-reverse
从这里我们可以看出 Flex 轴的方向不是固定不变的,它受到flex-direction
的影响
不足空间和剩余空间
当 Flex 项目总宽度小于 Flex 容器宽度时就会出现剩余空间
当 Flex 项目总宽度大于 Flex 容器宽度时就会出现不足空间
Flex 项目之间的间距
Flex 项目之间的间距可以直接在 Flex 容器上设置 gap 属性即可,如
<div class="container"> <div class="item">A</div> <div class="item">B</div> <div class="item">C</div> <div class="item">D</div> </div>
.container { display: flex; width: 500px; height: 400px; gap: 10px; } .item { width: 150px; height: 40px; }
Flex 属性
flex
属性是flex-grow
,flex-shrink
,flex-basis
三个属性的简写。下面我们来看下它们分别是什么。
flex-basis
可以设定 Flex 项目的大小,一般主轴为水平方向的话和 width 解析方式相同,但是它不一定是 Flex 项目最终大小,Flex 项目最终大小受到flex-grow
,flex-shrink
以及剩余空间等影响,后面文章会告诉大家最终大小的计算方式flex-grow
为 Flex 项目的扩展系数,当 Flex 项目总和小于 Flex 容器时就会出现剩余空间,而flex-grow
的值则可以决定这个 Flex 项目可以分到多少剩余空间flex-shrink
为 Flex 项目的收缩系数,同样的,当 Flex 项目总和大于 Flex 容器时就会出现不足空间,flex-shrink
的值则可以决定这个 Flex 项目需要减去多少不足空间
既然flex
属性是这三个属性的简写,那么flex
属性简写方式分别代表什么呢?
flex
属性可以为 1 个值,2 个值,3 个值,接下来我们就分别来看看它们代表什么意思
- 一个值
如果flex
属性只有一个值的话,我们可以看这个值是否带单位,带单位那就是flex-basis
,不带就是flex-grow
.item { flex: 1; /* 相当于 */ flex-grow: 1; flex-shrink: 1; flex-basis: 0; } .item { flex: 30px; /* 相当于 */ flex-grow: 1; flex-shrink: 1; flex-basis: 30px; }
- 两个值
当flex
属性有两个值的话,第一个无单位的值就是flex-grow
,第二个无单位的值则是flex-shrink
,有单位的就是flex-basis
.item { flex: 1 2; /* 相当于 */ flex-grow: 1; flex-shrink: 2; flex-basis: 0; } .item { flex: 30px 2; /* 相当于 */ flex-grow: 2; flex-shrink: 1; flex-basis: 30px; }
- 三个值
当flex
属性有三个值的话,第一个无单位的值就是flex-grow
,第二个无单位的值则是flex-shrink
,有单位的就是flex-basis
.item { flex: 1 2 10px; /* 相当于 */ flex-grow: 1; flex-shrink: 2; flex-basis: 10px; } .item { flex: 30px 2 1; /* 相当于 */ flex-grow: 2; flex-shrink: 1; flex-basis: 30px; } .item { flex: 2 30px 1; /* 相当于 */ flex-grow: 2; flex-shrink: 1; flex-basis: 30px; }
另外,flex 的值还可以为initial
,auto
,none
。
- initial
initial 为默认值,和不设置 flex 属性的时候表现一样,既 Flex 项目不会扩展,但会收缩,Flex 项目大小有本身内容决定
.item { flex: initial; /* 相当于 */ flex-grow: 0; flex-shrink: 1; flex-basis: auto; }
- auto
当 flex 设置为 auto 时,Flex 项目会根据自身内容确定flex-basis
,既会拓展也会收缩
.item { flex: auto; /* 相当于 */ flex-grow: 1; flex-shrink: 1; flex-basis: auto; }
- none
none 表示 Flex 项目既不收缩,也不会扩展
.item { flex: none; /* 相当于 */ flex-grow: 0; flex-shrink: 0; flex-basis: auto; }