# 认识 flex 布局

  • flex 布局是目前 web 开发中使用最多的布局方案
    • flex 布局 (Flexible 布局,弹性布局)
    • 目前特别在移动端用的最多,目前 PC 端也使用越来越多了
  • 两个重要概念
    • 开启了 flex 布局的元素叫 flex container
    • flex container 里面的子元素叫做 flex items
  • 设置 display 属性为 flex 或者 inline-flex 可以成为 flex container
    • flex:flex container 以 block-level 形式存在
    • inline-flex:flex container 以 inline-level 形式存在

# flex 布局模型

flex-model

# 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>

flex-direction-row

# row-reversr

  • 当我们设置 flex-directionrow-reverse 时,则是主轴从右到左

flex-direction-row-reverse

# column

  • 当设置 flex-directioncolumn 时,主轴从上往下排放

flex-direction-colum

# column-reverse

  • 当设置 flex-directioncolumn-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>

justify-content-flex-start

# flex-end

  • 当设置 justify-content: end 时,主轴在 main end 依次对齐

justify-content-flex-end

# center

  • 当设置 justify-content: center 时,居中对齐

justify-content-center

# space-between

  • 当设置 justify-content: space-between 时,两端对齐

justify-content-space-between

# space-evenly

  • 当设置 justify-content: space-evenly 时,平均 (等分) 对齐

justify-content-space-evenly

# space-around

  • 当设置 justify-content: 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>

align-items-normal

# 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>

align-items-flex-start

# flex-end

  • 当设置 align-items: flex-end 时,在交叉轴底部依次对齐

align-items-flex-end

# center

  • 当设置 align-items: 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>

align-items-baseline

# 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>

flex-wrap-nowrap

# wrap

  • 当设置 flex-wrap: wrap 且排不下时,不会进行压缩,会换行显示

flex-wrap-wrap

# wrap-reverse

  • 当设置 flex-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>

align-content-flex-start

# flex-end

  • 当设置了 align-content: flex-end; 时,则是从 end 开始紧挨着依次排布

align-content-flex-end

# center

  • 当设置了 align-content: center; 时,则是进行居中排布

align-content-center

# space-between

  • 当设置了 align-content: space-between; 时,则是紧贴两边边缘排布

align-content-space-between

# space-evenly

  • 当设置了 align-content: space-evenly; 时,平均间隔排布

align-content-space-evenly

# space-around

  • 当设置了 align-content: 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>

order

# 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>

align-self

# 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-grow

  • 如果所有 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-grow-1

  • 注意: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-shrink

  • 如果所有 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-shrink-.x

  • 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-basis

# 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> 的值
  • 就不举栗子了,了解即可,我也记不住~

Update on Views times

Give me a cup of [coffee]~( ̄▽ ̄)~*

Nico Niconi WeChat Pay

WeChat Pay

Nico Niconi Alipay

Alipay