flex
基本属性
- flex-direction
row | row-reverse | column | column-reverse
项目的排列方向 - flex-wrap
nowrap | wrap | wrap-reverse
项目内是否可以换行 - justify-content
flex-start | flex-end | center | space-between | space-around
水平对齐方式(会受排列方向影响) - align-items
flex-start | flex-end | center | baseline
垂直对齐方式(会受排列方向的影响) - align-content
flex-start | flex-end | center | space-between | space-around
定义多根轴线的对齐方式(也就是当可以换行时有多根轴线,操作的就是这些轴线的对齐方式)
flex: 1
flex: 1等于
- flex-grow: 1
- flex-shrink: 1
- flex-basis: 0%
TIP
解释: 也就是舍去元素本身的宽度( flex-basis优先级比width高 ),然后将收缩和扩大都设置1,等比缩放
注意: flex: 2 时, flex-grow = 2 且 flex-shrink = 2
flex-grow
决定了父元素在空间分配方向上还有剩余空间时,如何分配这些剩余空间,默认为 0
比如父元素剩余空间x,其三个子元素flex-grow分别为a, b, c
设 sum = a+b+c
,则这三个元素各自将要得到的剩余空间(也就是权重)分别为: x*a/sum
x*b/sum
x*c/sum
TIP
子级的 max-width 以及 min-width 有些场景会覆盖 flex-grow 生成的宽度
场景1: 子元素无初始宽度
<div class="content">
<div class="left"></div>
<div class="cen"></div>
<div class="right"></div>
</div>
<style type="text/css">
.content {
display: flex;
width: 100px;
height: 200px;
border: 1px solid red;
}
.left {
flex-grow: 1;
background-color: green;
}
.cen {
flex-grow: 2;
background-color: yellow;
}
.right {
flex-grow: 3;
background-color: red;
}
<script>
这里可以知道父级元素有三个子元素,都没有设置基础宽度且各自 flex-grow
设置为 1,2,3
那么可以得到它们各自分别按照比例分摊父级元素剩余内容: 1/6, 2/6, 3/6
也就是最终各个子元素的宽度为:
- left.width = (100 * 1/6)px
- cen.width = (100 * 2/6)px
- right.width = (100 * 3/6)px
场景2: 子元素有初始宽度
<style type="text/css">
.content {
display: flex;
width: 100px;
height: 200px;
border: 1px solid red;
}
.left {
flex-grow: 1;
width: 10px;
background-color: green;
}
.cen {
flex-grow: 2;
width: 20px;
background-color: yellow;
}
.right {
flex-grow: 3;
width: 30px;
background-color: red;
}
<script>
接着场景1的布局,只是给每个子元素设定初始宽度
按照上面的公式,可以得到它们各自分别按照比例分摊父级元素剩余内容: 1/6, 2/6, 3/6
不同的是,此时父级剩余内容为 100 - 10 - 20 - 30 = 40px
所以最终各个子元素能分到的宽度分别为: 1/6 * 40
2/6 * 40
3/6 * 40
也就是最终各个子元素宽度为:
- left.width = (10 + 6.66)px
- cen.width = (20 + 13.34)px
- right.width = (30 + 20)px
场景3: flex-grow之和小于1
当所有元素的 flex-grow 之和小于 1 的时候,sum会按照1来算,而不是sum等于各个子元素的 flex-grow
总和,也就是剩余空间不会全部分配给各个元素
<style type="text/css">
.content {
display: flex;
width: 100px;
height: 200px;
border: 1px solid red;
}
.left {
flex-grow: 0.1;
background-color: green;
}
.cen {
flex-grow: 0.2;
background-color: yellow;
}
.right {
flex-grow: 0.3;
background-color: red;
}
<script>
所以这里各个子元素宽度分配为:
- left.width = (100 * 0.1/1)px
- cen.width = (100 * 0.2/1)px
- right.width = (100 * 0.3/1)px
场景4: 和小于1且有初始宽度
注意:这里的子元素初始宽度和上面几个例子不一样的
<style type="text/css">
.content {
display: flex;
width: 100px;
height: 200px;
border: 1px solid red;
}
.left {
flex-grow: 0.1;
width: 30px;
background-color: green;
}
.cen {
flex-grow: 0.2;
width: 20px;
background-color: yellow;
}
.right {
flex-grow: 0.3;
width: 10px;
background-color: red;
}
<script>
父级的剩余宽度为: (100 - 30 - 20 - 10) = 40px
所以这里各个子元素宽度分配为:
- left.width = (30 + 40 * 0.1/1)px
- cen.width = (20 + 40 * 0.2/1)px
- right.width = (10 + 40 * 0.3/1)px
flex-shrink
在空间不够时让各个子元素收缩以适应有限的空间,默认为 1
TIP
子级的 max-width 以及 min-width 有些场景会覆盖 flex-grow 生成的宽度
场景1: flex-shrink总和大于1
<style type="text/css">
.content {
display: flex;
width: 100px;
height: 200px;
border: 1px solid red;
}
.left {
flex-shrink: 1;
width: 30px;
background-color: green;
}
.cen {
flex-shrink: 2;
width: 40px;
background-color: yellow;
}
.right {
flex-shrink: 3;
width: 50px;
background-color: red;
}
<style>
溢出宽度: 100 - 30 - 40 - 50 = -20px
总权重: 1*30 + 2*40 + 3*50 = 260
三个子元素分别收缩:
- left: 20 * 1 * 30/260 = 2.3
- cen: 20 * 2 * 40/260 = 6.16
- right: 20 * 3 * 50/260 = 11.54
最终宽度:
- left: 30 - 2.3 = 27.7
- cen: 40 - 6.16 = 33.84
- right: 50 - 11.54 = 38.46
场景2: flex-shrink总和小于1
<style type="text/css">
.content {
display: flex;
width: 100px;
height: 200px;
border: 1px solid red;
}
.left {
flex-shrink: 0.1;
width: 30px;
background-color: green;
}
.cen {
flex-shrink: 0.2;
width: 40px;
background-color: yellow;
}
.right {
flex-shrink: 0.3;
width: 50px;
background-color: red;
}
<style>
溢出宽度: 100 - 30 - 40 - 50 = -20px
总权重: 0.1*30 + 0.2*40 + 0.3*50 = 26
注意: 这里不再按照溢宽度20全部收回去,只会收缩 20 * (0.1+0.2+0.3)/1 = 12
的空间
三个子元素分别收缩:
- left: 12 * 0.1 * 30/26 = 1.38
- cen: 12 * 0.2 * 40/26 = 3.7
- right: 12 * 0.3 * 50/26 = 6.92
最终宽度:
- left: 30 - 1.38 = 28.62
- cen: 40 - 3.7 = 36.3
- right: 50 - 6.92 = 43.08
flex子元素属性
- order 定义项目在容器中排列顺序,数值越小越靠前(-1, -10这些)
- align-self
auto | flex-start | flex-end | center | baseline
允许单个项目有与其他项目不一样的对齐方式 - flex-basis
auto | 数值
表示flex items 在被放进一个flex容器之前的大小,width是其一个回退选项
布局实现
九宫格
( 不保证有九个格子且最后一行左对齐 )
- flex,父级
display: flex; flex-warp: warp;
,然后子元素width: 30%
- 浮动,父级
overflow: hidden
, 子级float: left; width: 30%
- 强行补齐源数据,并且给出属性标识,然后在渲染的时候设内容为空(额,还是用上面的套路)
圣杯布局
两边固定宽度,中间设置 flex: 1
置顶 & 置底
- 中心内容设置
margin-bottom: -50px
,底部高度也是50px - 中心内容设置
padding-bottom: 50px
,底部设置margin-top: -50px
- 中心内容设置
height: calc(100vh - 50px)
,底部高度50px - 父级设置
flex-direction: column
,中心内容设置flex: 1
,底部高度随意变化