深入浅出之 Flex 弹性布局

563 阅读7分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

flex布局(flexible布局, 弹性布局)是web开发中使用最多的布局方案之一

一旦我们开启了flex布局,flex内部元素的布局方式和flex-item是块级元素还是行内元素都没有关系,全部都有flex布局自己根据设置的属性自己决定

基本使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      width: 500px;
      height: 400px;
      background-color: #FF9933;
    }

    .item {
      width: 100px;
      height: 100px;
      color: #fff;
      line-height: 100px;
      text-align: center;
    }

    .item1 {
      background-color: #33CC33;
    }

    .item2 {
      background-color: #CCDDDD;
    }

    .item3 {
      background-color: #0099CC;
    }

    .container {
      display: flex;
    }
  </style>
</head>
<body>

  <!--
    我们可以使用display: flex 或 inline-flex来开启flex布局
		flex --- .container为块级元素
		inline-flex --- .container为行内元素

    开启flex布局后
      最外层的.container容器就是flex-container
      内部的每一个item就是flex-item
  -->
  <div class="container">
    <div class="item item1">item1</div>
    <div class="item item2">item2</div>
    <div class="item item3">item3</div>
  </div>
</body>
</html>

布局模型

Ii40Ue.png

flex-container的属性

flex-direction

flex items默认都是沿着main axismain startmain end方向排序

flex-driection有四个值:

row: 默认值 从左往右排列

row-reverse: 从右往左排列

column: 从上往下排列

column-reverse:从下往上排列

Ii495R.png

justify-content

justify-content决定了flex items在main axis上的对齐方式

justify-content可选值:

flex-start: 默认值 左对齐

flex-end:右对齐

center:居中

space-between: 两端对齐

  • flex-items之间的距离相等
  • main startmain end两端对齐

space-evenly:等分排列

  • flex-items之间的距离相等

  • flex-itemsmain start, main end之间的距离等于flex-items之间的距离

space-around

  • flex-items之间的距离相等

  • flex-itemsmain start, main end之间的距离是flex-items之间的距离的一半

    IiBSyC.png

IiBmuG.png

align-items

align-items决定了flex-itemscross axis上的对齐方式

可选值

normal --- 默认值

  • 如果flex-items设置了高度,布局和flex-start类似
  • 如果flex-items没有设置高度,布局和stretch类似

stretch --- 高度和flex container的高度一致

  • 设置flex itemscross axis方向的sizeauto
  • 即高度自动拉伸至填充至flex container

flex-start

  • cross start对齐
  • 顶部对齐

flex-end

  • croess end对齐
  • 底部对齐

center

  • 垂直居中
  • flex-items的容器的中心线,垂直居中对齐

baseline

  • 内容的基准线对齐(也就是字母x的底部对齐)
  • 注意: 这里对比的基线是对比第一行的基线,并不包括其它行

IiflfG.png

IifXTp.png

flex-wrap

flex-wrap决定了flex-container中的元素是单行显示还是多行显示

  • 如果一行放不下,会尽可能的压缩flex-items的宽度

mowrap --- 不换行 默认值

wrap --- 多行

wrap-reverse --- 多行 排列在cross axis上翻转

Iifgpy.png

IifxaD.png

flex-flow

flex-flowflex-direction + flex-wrap的简写

/* flex-flow: flex-direction可选的值 flex-wrap可选的值 */
/* flex-flow的两个选项中 任意一个不写 就表示使用对应的默认值 */
/* flex-flow的两个选项的配置并不存在先后顺序 --- 谁先谁后都是可以的 */
{
  flex-flow: row-reverse wrap;
}

align-content

align-content决定了多行 flex itemscross axis上的对齐方式

使用方式和可选值与justify-content一致

IigIWE.png

IigLJQ.png

flex-items的属性

order

order决定了flex-items的排列顺序

  • 默认值是0

  • 可以设置任何的整数(正整数,负整数,0)

  • 值越小就越排在前面

  • 如果order值相同,那么就按照在代码中的默认顺序进行排列

.item1 {
  background-color: hsl(120, 60%, 50%);
}

.item2 {
  background-color: #CCDDDD;
  order: 6;
}

.item3 {
  background-color: #0099CC;
  order: -1;
}

.container {
  display: flex;
}
 <div class="container">
    <div class="item item1">item1</div>
    <div class="item item2">item2</div>
    <div class="item item3">item3</div>
  </div>

IigJhC.png

align-self

设置某一个flex-itemalign-self值可以覆盖其在flex-container上设置的align-items

所以align-self的可选值和align-items一致

.item1 {
  background-color: hsl(120, 60%, 50%);
  align-self: flex-start;
}

.item2 {
  background-color: #CCDDDD;
}

.item3 {
  background-color: #0099CC;
  align-self: flex-end;
}

.container {
  display: flex;
  align-items: center;
}
 <div class="container">
    <div class="item item1">item1</div>
    <div class="item item2">item2</div>
    <div class="item item3">item3</div>
  </div>

IigNnt.png

flex-grow

flex-grow决定了flex items如何扩展

fle-grow的值可以是任何的非负数字(正小数,正整数,0),默认值是0

flex containermain axis上有剩余size的时候,(也就是有剩余宽度的时候),flex-grow属性才会生效

  1. 当所有flex itemsflex-grow的总和超过1,每一个flex item扩展的size为剩余size / 所有flex-grow的总和

  2. 当所有flex itemsflex-grow的总和小于1,每一个flex item扩展的size为剩余size * flex-grow

flex items扩展后的最终size不能超过max-width/max-height

/* 总宽600px,每一个元素100px 剩余300px */
.item1 {
  background-color: hsl(120, 60%, 50%);
  flex-grow: 1; /* 扩100px后总长200px */
}

.item2 {
  background-color: #CCDDDD;
  flex-grow: 1; /* 扩100px后总长200px */
}

.item3 {
  background-color: #0099CC;
  flex-grow: 1; /* 扩100px后总长200px */
}
/* 总宽600px,每一个元素100px 剩余300px */
.item1 {
background-color: hsl(120, 60%, 50%);
flex-grow: 2; /* 300 / 5 = 60 扩展后快递 100 + 60 * 2 = 220 */
}

.item2 {
background-color: #CCDDDD;
flex-grow: 2; /* 300 / 5 = 60 扩展后快递 100 + 60 * 2 = 220 */
}

.item3 {
background-color: #0099CC;
flex-grow: 1; /* 300 / 5 = 60 扩展后快递 100 + 60 * 1 = 160 */
}
/* 总宽600px,每一个元素100px 剩余300px */
.item1 {
  background-color: hsl(120, 60%, 50%);
  flex-grow: .2; /* 100 + 300 * 0.2 = 160 */
}

.item2 {
  background-color: #CCDDDD;
  flex-grow: .2; /* 100 + 300 * 0.2 = 160 */
}

.item3 {
  background-color: #0099CC;
  flex-grow: .1; /* 100 + 300 * 0.1 = 130 */
}
/* 总宽600px,每一个元素100px 剩余300px */
.item1 {
  background-color: hsl(120, 60%, 50%);
  flex-grow: 2; /* 100 + 300 / 4.1 * 2 = 246.34 */
}

.item2 {
  background-color: #CCDDDD;
  flex-grow: 2; /* 100 + 300 / 4.1 * 2 = 246.34 */
}

.item3 {
  background-color: #0099CC;
  flex-grow: .1;  /* 100 + 300 / 4.1 * 0.1 = 107.32 */
}

flex-shrink

flex-shrink用来控制flex item如何进行收缩

fle-shrink的值可以是任何的非负数字(正小数,正整数,0),默认值是1

flex itemsmain axis上超过了flex containersize,(也就是溢出的时候),flex-shrink属性才会生效

  1. 当所有flex itemsflex-shrink的总和超过1,每一个flex item扩展的size为溢出size * flex-grow的总和

  2. 当所有flex itemsflex-shrink的总和小于1,每一个flex item扩展的size为溢出size * flex-grow

    所有flex items的flex-shrink的总和小于1时候,即使flex-items都已经进行了缩放,但是依旧会存在溢出情况

flex-items收缩后最终的size不能小于min-width/min-height

flex-item的最小宽度为flex-item中内容的宽度

/* 总宽500px,每一个元素200px 溢出100px */
.item1 {
  background-color: hsl(120, 60%, 50%);
  flex-shrink: 2; /* 200 - 100 / 5 * 2 = 160 */
}

.item2 {
  background-color: #CCDDDD;
  flex-shrink: 2; /* 200 - 100 / 5 * 2 = 160 */
}

.item3 {
  background-color: #0099CC;
  flex-shrink: 1;  /* 200 - 100 / 5 * 1 = 180 */
}
/* 总宽500px,每一个元素200px 溢出100px */
.item1 {
  background-color: hsl(120, 60%, 50%);
  flex-shrink: .2; /* 200 - 100 * 0.2 = 180 */
}

.item2 {
  background-color: #CCDDDD;
  flex-shrink: .2; /* 200 - 100 * 0.2 = 180 */
}

.item3 {
  background-color: #0099CC;
  flex-shrink: .1;  /* 200 - 100 * 0.1 = 190 */
}
/* 总宽500px,每一个元素200px 溢出100px */
.item1 {
  background-color: hsl(120, 60%, 50%);
  flex-shrink: 2; /* 200 - 100 / 4.1 * 2 = 151.22 */
}

.item2 {
  background-color: #CCDDDD;
  flex-shrink: 2; /* 200 - 100 / 4.1 * 2 = 151.22 */
}

.item3 {
  background-color: #0099CC;
  flex-shrink: .1;  /* 200 - 100 / 4.1 * 0.1 = 197.5s6 */
}

flex-basis

flex-basis用来设置flex item的宽度(当flex-directionrowrow-reverse时)或高度(当flex-directioncolumncolumn-reverse时)

默认值是auto,也就是原本设置了flex item的宽度或高度是多少,就是多少

也可以设置一个具体的值,此时flex-basis设置的宽度或高度会覆盖flex item原本的宽度或高度

.item {
  flex-basis: 100px;
}

在flex布局中,决定flex-item宽高的属性优先级;

  1. max-width/min-width/max-height/min-height
  2. flex-basis
  3. width/height
  4. 内容的宽度或高度

flex

flexflex-grow+ flex-shrink+ flex-basis的简写

flex属性可以指定1个,2个或3个值

单值

  • 无单位number --- flex-grow
  • 有效宽度值 --- flex-basis
  • 诸如: noneautoinital之类的关键字

双值

  • 第一个值必须是无单位值 --- flex-grow
  • 第二个值可以为以下之一
    • 无单位值 --- flex-shrink
    • 有效宽度值 --- flex-basis

三值

  • 无单位值 --- flex-grow
  • 无单位值 --- flex-basis
  • 有效宽度值 --- flex-basis