# 认识 flex 布局
- flex 布局是目前 web 开发中使用最多的布局方案
- flex 布局 (Flexible 布局,弹性布局)
- 目前特别在移动端用的最多,目前 PC 端也使用越来越多了
- 两个重要概念
- 开启了 flex 布局的元素叫
flex container
- flex container 里面的子元素叫做
flex items
- 开启了 flex 布局的元素叫
- 设置 display 属性为
flex
或者inline-flex
可以成为flex container
- flex:flex container 以 block-level 形式存在
- inline-flex:flex container 以 inline-level 形式存在
# flex 布局模型
# flex 相关属性
- 应用在 flex container 上的 CSS 属性
- flex-flow
- flex-direction
- flex-wrap
- justify-content
- align-items
- align-content
# Flex-direction
- flex items 默认都是沿着 main axis (主轴) 从 main start 开始往 main end 方向排布
- flex-direction 决定 main axis
# row
- 下面开启 flex 布局,并设置主轴方向为
row
(默认就是 row:主轴从左到右)
<style> | |
.box { | |
display: flex; | |
flex-direction: row; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">a</div> | |
<div class="item item2">b</div> | |
<div class="item item3">c</div> | |
</div> |
# row-reversr
- 当我们设置
flex-direction
为row-reverse
时,则是主轴从右到左
# column
- 当设置
flex-direction
为column
时,主轴从上往下排放
# column-reverse
- 当设置
flex-direction
为column-reverse
时,主轴从下往上并且反转,意味着从下到上了
# justify-content
- justify-content 决定了 flex-items 在 main axis 上的对齐方式
- flex-start (默认值):与 main start 对齐
- flex-end:与 main end 对齐
- center:居中对齐
- space-between:
- flex items 之间的距离相等
- 与 main start、main end 两端对齐
- space-evenly:
- flex items 之间的距离相等
- flex items 与 main start、main end 之间的距离等于 flex items 之间的距离
- space-around:
- flex items 之间的距离相等
- flex items 与 main start、main end 之间的距离是 flex items 之间距离的一半
# flex-start
- justify-content:决定 flex items 主轴的对齐方式,默认值是
flex-start
<style> | |
.box { | |
display: flex; | |
justify-content: flex-start; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">a</div> | |
<div class="item item2">b</div> | |
<div class="item item3">c</div> | |
</div> |
# flex-end
- 当设置
justify-content: end
时,主轴在 main end 依次对齐
# center
- 当设置
justify-content: center
时,居中对齐
# space-between
- 当设置
justify-content: space-between
时,两端对齐
# space-evenly
- 当设置
justify-content: space-evenly
时,平均 (等分) 对齐
# space-around
- 当设置
justify-content: space-around
时,两边距离稍小,中间距离稍大(两边的距离是中间距离的二分之一,中间距离是两步距离的两倍)
# align-items
- align-items 决定了 flex item 在 cross axis 上的对齐方式
- normal:在弹性布局中,效果和 stretch 一样
- stretch:当 flex items 在 cross axis 方向的 size 为 auto 时,会自动拉伸至填充 flex container
- flex-start:与 cross start 对齐
- flex-end:与 cross end 对齐
- center:居中对齐
- baseline:与基线对齐
# normal & stretch
- 当设置
align-items: normal
且子元素没有设置高度时,默认进行拉伸,与stretch
一样
<style> | |
.box { | |
display: flex; | |
align-items: normal; | |
/* align-items: stretch; */ | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
/* height: 100px; */ | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">a</div> | |
<div class="item item2">b</div> | |
<div class="item item3">c</div> | |
</div> |
# flex-start
- 没有高度地情况下高度与自身文本相关,且都是默认开始位置对齐
<style> | |
.box { | |
display: flex; | |
align-items: flex-start; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛 | |
苦。</div> | |
<div class="item item2">横眉冷对千夫指,俯首甘为孺子牛。</div> | |
<div class="item item3">倘只看书,便变成书橱。</div> | |
</div> |
# flex-end
- 当设置
align-items: flex-end
时,在交叉轴底部依次对齐
# center
- 当设置
align-items: center
时,在交叉轴中心点对齐
# baseline
- 当设置
align-items: baseline
时,与文本基线对齐
<style> | |
.box { | |
display: flex; | |
align-items: baseline; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
color: #fff; | |
} | |
.item1 { | |
padding-top: 20px; | |
background-color: goldenrod; | |
} | |
.item2 { | |
padding-top: 30px; | |
background-color: pink; | |
} | |
.item3 { | |
padding-top: 50px; | |
background-color: coral; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒 | |
苦。</div> | |
<div class="item item2">横眉冷对千夫指,俯首甘为孺子牛。</div> | |
<div class="item item3">倘只看书,便变成书橱。</div> | |
</div> |
# flex-wrap
-
flex-wrap 决定了 flex container 是单行还是多行
- nowrap(默认)单行
- wrap: 多行
- wrap-reverse:多行 (对比 wrap, cross start 与 cross end 相反)
-
flex-flow 是 flex-direction || flex-wrap 的简写
- 可以省略,顺序任意
# nowrap
- 当设置
flex-wrap: nowrap
时 (默认),默认情况下所有地flex items
都会在同一行显示,不换行显示
<style> | |
.box { | |
display: flex; | |
flex-wrap: nowrap; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
.item4 { | |
background-color: #48df35; | |
} | |
.item5 { | |
background-color: #2055c9; | |
} | |
.item6 { | |
background-color: #f17806; | |
} | |
.item7 { | |
background-color: rgb(205, 16, 223); | |
} | |
.item8 { | |
background-color: #dee20e; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A</div> | |
<div class="item item2">B</div> | |
<div class="item item3">C</div> | |
<div class="item item4">D</div> | |
<div class="item item5">E</div> | |
<div class="item item6">F</div> | |
<div class="item item7">G</div> | |
<div class="item item8">H</div> | |
</div> |
# wrap
- 当设置
flex-wrap: wrap
且排不下时,不会进行压缩,会换行显示
# wrap-reverse
- 当设置
flex-wrap: wrap-reverse
时,在交叉轴上进行反转再进行排布
# flex-flow
- 当
flex-flow: column wrap
同时设置时,代表改变主轴为column
, 是换行 - ![ flex-flow-column wrap]( flex-flow-column wrap.png)
# align-content
- align-content 决定了多行 flex items 在 cross axis 上的对齐方式,用法与 justify-content 类似
- stretch (默认值):与 align-items 的 stretch 类似
- flex-start:与 cross start 对齐
- flex-end:与 cross end 对齐
- center:居中对齐
- space-between:
- flex items 之间的距离相等
- 与 cross start 、cross end 两端对齐
- space-around:
- flex items 之间的距离相等
- flex items 与 cross start、cross end 之间的距离是 flex items 之间距离的一般
- space-evenly:
- flex items 之间的距离相等
- flex items 与 cross start、cross end 之间的距离相等 等于 flex items 之间的距离
# flex-start
- 当设置了
align-content: flex-start;
时,代表在交叉轴上面依次排
<style> | |
.box { | |
display: flex; | |
flex-flow: row wrap; | |
align-content: flex-start; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
.item4 { | |
background-color: #48df35; | |
} | |
.item5 { | |
background-color: #2055c9; | |
} | |
.item6 { | |
background-color: #f17806; | |
} | |
.item7 { | |
background-color: #cd10df; | |
} | |
.item8 { | |
background-color: #dee20e; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A</div> | |
<div class="item item2">B</div> | |
<div class="item item3">C</div> | |
<div class="item item4">D</div> | |
<div class="item item5">E</div> | |
<div class="item item6">F</div> | |
<div class="item item7">G</div> | |
<div class="item item8">H</div> | |
</div> |
# flex-end
- 当设置了
align-content: flex-end;
时,则是从end
开始紧挨着依次排布
# center
- 当设置了
align-content: center;
时,则是进行居中排布
# space-between
- 当设置了
align-content: space-between;
时,则是紧贴两边边缘排布
# space-evenly
- 当设置了
align-content: space-evenly;
时,平均间隔排布
# space-around
- 当设置了
align-content: space-around;
时,两边的距离是中间距离的二分之一,中间距离是两步距离的两倍
# order
- 决定了 flex items 的排布顺序
- 可以设置任意整数 (正整数、负整数、0),值越小越排前面
- 默认值是 0
<style> | |
.box { | |
display: flex; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
order: 2; | |
background-color: goldenrod; | |
} | |
.item2 { | |
order: 1; | |
background-color: pink; | |
} | |
.item3 { | |
order: 0; | |
background-color: coral; | |
} | |
.item4 { | |
order: -1; | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A</div> | |
<div class="item item2">B</div> | |
<div class="item item3">C</div> | |
<div class="item item4">D</div> | |
</div> |
# align-self
- flex items 可以通过 align-self 覆盖 flex container 设置的 align-items
- auto (默认值):遵从 flex container 的 align-items 设置
- stretch、flex-start、flex-end、center、baseline,效果跟 align-items 一致
- 就是可以单独决定 align items 的对齐方式
<style> | |
.box { | |
display: flex; | |
align-items: center; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
background-color: goldenrod; | |
} | |
.item2 { | |
background-color: pink; | |
} | |
.item3 { | |
align-self: baseline; | |
background-color: coral; | |
} | |
.item4 { | |
align-self: flex-end; | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A: 110px</div> | |
<div class="item item2">B: 120px</div> | |
<div class="item item3">C: 130px</div> | |
<div class="item item4">D: 140px</div> | |
</div> |
# flex-grow
-
flex-grow 决定了 flex items 如何扩展
- 可以设置任意非负数字 (正小数、正整数、0),默认值是 0
- 当 flex container 在 main axis 方向上有剩余 size 时,flex-grow 属性才会有效
-
如果所有 flex items 的 flex-grow 总和 sum 超过 1,每个 flex item 扩展的 size 为:
flex container 的剩余 size * (flex-grow / sum)
-
就比如下面,每个盒子宽度是
100px
,父盒子是宽度500px
- 那么则是剩余
size
:500px - 400px = 100px
- 然后
sum
则是通过flex-grow
的所有份数 (值) 加起来 就是1+2+3+4=10
份 - 最后进行公式分别计算份数
1|2|3|4 / (1+2+3+4) = 0.1|0.2|0.3|0.4
- 那么
flex-grow: 1;
就是100px * 0.1 = 10px
- 那么
flex-grow: 2;
就是100px * 0.5 = 20px
- 那么
flex-grow: 3;
就是100px * 0.3 = 30px
- 那么
flex-grow: 4;
就是100px * 0.4 = 40px
- 那么则是剩余
-
那么
item1、item2、item3、item4
的宽度则是本身100px
加上各自份数的宽度结果分别是:110px、120px、130px、140px
<style> | |
.box { | |
display: flex; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
flex-grow: 1; | |
background-color: goldenrod; | |
} | |
.item2 { | |
flex-grow: 2; | |
background-color: pink; | |
} | |
.item3 { | |
flex-grow: 3; | |
background-color: coral; | |
} | |
.item4 { | |
flex-grow: 4; | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A</div> | |
<div class="item item2">B</div> | |
<div class="item item3">C</div> | |
<div class="item item4">D</div> | |
</div> |
- 如果所有 flex itens 的 flex-grow 总和不超过 1,每个 flex item 扩展的 size 为:
flex container 的剩余 size * flex-grow
- 例如下面栗子,并且为负数时代表不进行份数占比,保持不变
<style> | |
.box { | |
display: flex; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
flex-grow: .1; | |
background-color: goldenrod; | |
} | |
.item2 { | |
flex-grow: .2; | |
background-color: pink; | |
} | |
.item3 { | |
flex-grow: .3; | |
background-color: coral; | |
} | |
.item4 { | |
flex-grow: -1; | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A: 110px</div> | |
<div class="item item2">B: 120px</div> | |
<div class="item item3">C: 130px</div> | |
<div class="item item4">D: 100px</div> | |
</div> |
- 注意:flex items 扩展后的最终 size 不能超过 max-width\max-height
# flex-shrink
- flex-shrink 决定了 flex items 如何收缩
- 可以设置任意非负数字 (正小数、正整数、0) 默认值是 1
- 当 flex items 在 main axis 方向上超过了 flex container 的 size, flex-shrink 属性才会有效
- 如果所有 flex items 的 flex-shrink 总和超过 1,每个 flex item 收缩的 size 为:
flex items 超出 flex container 的 size * (收缩比例 / 所有 flex items 的收缩比例之和)
- 就比入下面这个父盒子宽度是
500px
, 每个子盒子宽度是200px
<style> | |
.box { | |
display: flex; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 200px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
flex-shrink: 1; | |
background-color: goldenrod; | |
} | |
.item2 { | |
flex-shrink: 2; | |
background-color: pink; | |
} | |
.item3 { | |
flex-shrink: 3; | |
background-color: coral; | |
} | |
.item4 { | |
flex-shrink: 4; | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A: 170px</div> | |
<div class="item item2">B: 140px</div> | |
<div class="item item3">C: 110px</div> | |
<div class="item item4">D: 80px</div> | |
</div> |
-
那么超出的
size
就是:200px * 4 - 500px = 300px
-
然后进行收缩比例计算,收缩比例则分别是每个
flex-shrink
的 (值) 加起来即:1|2|3|4 / (1+2+3+4) = 0.1|0.2|0.3|0.4
-
最后进行公式计算分别的缩小比例而需要缩小后的值:
- 那么
flex-shrink: 1;
就是300px * 0.1 = 30px
- 那么
flex-shrink: 2;
就是300px * 0.2 = 60px
- 那么
flex-shrink: 3;
就是300px * 0.3 = 90px
- 那么
flex-shrink: 4;
就是300px * 0.4 = 120px
- 那么
-
最终
item1、item2、item3、item4
的宽度则是本身200px
减去各自缩小比列的值,结果分别是:170px、140px、110px、80px
- 如果所有 flex items 的 flex-shrink 总和 sun 不超过 1 ,每个 flex item 收缩的 size 为:
- flex items 超出 flex container 的 size * sum * 收缩比例 / 所有 flex items 的收缩比例之和
- 收缩比例 = fkex-shrink * flex item 的 base size
- base size 就是 flex item 放入 flex container 之前的 size
- 很明显则是
300px * 0.1|0.1|0.2|0.3 = 30px|30px|60px|90px
- 那么减去缩小的大小
item
的宽度分别是:170px 170px 140px 110px
- 那么减去缩小的大小
<style> | |
.box { | |
display: flex; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 200px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
flex-shrink: .1; | |
background-color: goldenrod; | |
} | |
.item2 { | |
flex-shrink: .1; | |
background-color: pink; | |
} | |
.item3 { | |
flex-shrink: .2; | |
background-color: coral; | |
} | |
.item4 { | |
flex-shrink: .3; | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A: 170px</div> | |
<div class="item item2">B: 170px</div> | |
<div class="item item3">C: 140px</div> | |
<div class="item item4">D: 110px</div> | |
</div> |
- flex items 收缩后的最终 size 不能小于 min-width\min-height
# flex-basis
- flex-basis 用来设置 flex items 在 main axis 方向上的 base size
- auto (默认值)、具体的宽度数值 (100px)
- 决定 flex items 最终 base size 的因素,从优先级高到低
- max-width\max-height\min-width\min-height
- flex-basis
- width\height
- 内容本身的 size
<style> | |
.box { | |
display: flex; | |
width: 500px; | |
height: 400px; | |
background-color: orange; | |
} | |
.item { | |
width: 100px; | |
height: 100px; | |
color: #fff; | |
} | |
.item1 { | |
flex-basis: 140px; | |
background-color: goldenrod; | |
} | |
.item2 { | |
flex-basis: 160px; | |
background-color: pink; | |
} | |
.item3 { | |
background-color: coral; | |
} | |
.item4 { | |
background-color: #48df35; | |
} | |
</style> | |
<div class="box"> | |
<div class="item item1">A: 140px</div> | |
<div class="item item2">B: 160px</div> | |
<div class="item item3">C: 100px</div> | |
<div class="item item4">D: 100px</div> | |
</div> |
# flex
-
flex 式 flex-grow || flex-shrink || flex-basis 的简写,flex 属性可以指定 1 个,2 个或 3 个值,且注意这都是给 item 设置的
-
单值语法:值必须为以下其中之一:
- 一个无单位数 (<number>):它会被当作 <flex-grow > 的值
- 一个有效的宽度 (width) 值:它会被当作 <flex-basis > 的值
- 关键字 none,auto 或 initial
-
双值语法:第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值
- 第二个值必须为以下之一:
- 一个无单位数:它会被当作 <flex-shrink> 的值
- 一个有效的宽度值:它会被当作 <flex-basis> 的值
- 第二个值必须为以下之一:
-
三值语法:
- 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值
- 第二个值必须为一个无单位数,并且它会被当作 <flex-shrink> 的值
- 第三个值必须为一个有效的宽度值,并且它会被当作 <flex-basis> 的值
-
就不举栗子了,了解即可,我也记不住~