Skip to content

Flex 学习

1: 基本概念

有个水平的主轴(main axis)和垂直的交叉轴(cross axis)。

容器上一共有 6 个属性:

flex-direction flex-wrap flex-flow justify-content align-items align-content

项目上也有 6 个属性

order flex-grow flex-shrink flex-basis flex align-self

2. 例子

2.1. 常规例子

html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
  }

  .div {
    width: 100px;
    height: 100px;
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>

<div class="container">
  <div class="div">1</div>
  <div class="div">2</div>
</div>

image

2.2 只添加 diplay: flex; 注意 display: inline-flex 会让 box 变成 inline 的属性

html
<style type="text/css">
  .container {
    display: flex;
  }
</style>

image

若元素比较多, 则他们的宽度会自动压缩:

html
<div class="container">
  <div class="div">1</div>
  <div class="div">2</div>
  <div class="div">3</div>
  <div class="div">4</div>
  <div class="div">5</div>
  <div class="div">6</div>
  <div class="div">7</div>
  <div class="div">8</div>
  <div class="div">9</div>
  <div class="div">10</div>
  <div class="div">11</div>
  <div class="div">12</div>
  <div class="div">13</div>
</div>

image

3. flex-direction

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。

3.1 row-reverse

image

3.2 column

image

3.3 column-reverse

image

4. flex-wrap

  • nowrap(默认)
  • wrap 必须大于 box 的宽度才起作用, 否则和默认的一样
  • wrap-reverse

4.1 wrap

html
<style type="text/css">
  .container {
    display: flex;
    flex-direction: wrap;
  }
  .div {
    width: 100px;
    height: 120px;
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>
<div class="container">
  <div class="div">1</div>
  <div class="div">2</div>
  <div class="div">3</div>
  <div class="div">4</div>
  <div class="div">5</div>
  <div class="div">6</div>
  <div class="div">7</div>
  <div class="div">8</div>
</div>

image

若注释了 height: 120px, 效果如下图, 由于 align-content 默认为 stretch

image

若设置 align-content: flex-startimage

4.2 wrap-reverse

image

5. flex-flow

flex-flow 属性是 flex-direction 属性和 flex-wrap 属性的简写形式 默认值为, flex-flow: row nowrap;

6. justify-content

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:项目之间的间隔比项目与边框的间隔大一倍。
  • space-evenly: 项目之间的间隔都相等。

6.1 flex-end

image

6.2 center

image

6.3 space-between

image

6.4 space-around

20 比 10 大一倍 image

6.5 space-evenly

image

7. align-items

  • stretch(默认值):如果项目未设置高度或设为 auto,将占满整个容器的高度。
  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的都以靠近最下面的项目的文字的基线对齐。

7.1 stretch

若 div 没有指定 height 或 设置 min-height: 100px;

html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
    display: flex;
  }

  .div {
    width: 100px;
    /* height: 100px; */
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>

<div class="container">
  <div class="div">1</div>
  <div class="div">2</div>
  <div class="div">3</div>
</div>

image

7.2 flex-start

html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
    display: flex;
    align-items: flex-start;
  }

  .div {
    width: 100px;
    /* height: 100px; */
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>

image

7.3 flex-end

image

7.4 center

html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
    display: flex;
    align-items: center;
  }

  .div {
    width: 100px;
    height: 100px;
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>

<div class="container">
  <div class="div" style="padding-top: 20px;">1</div>
  <div class="div" style="padding-top: 80px;height: 160px;">2</div>
  <div class="div" style="padding-top: 60px;">3</div>
</div>

image

7.5 baseline

以靠近最下面的项目 2 的文字对齐。 image

8. align-content

定义了多根轴线的对齐方式, 所以通常要设置上 flex-wrap: wrap; 这样就会有多根轴线了

  • stretch:轴线占满整个交叉轴。(默认)
  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:项目之间的间隔比项目与边框的间隔大一倍。
  • space-evenly: 项目之间的间隔都相等。

8.1 stretch -- 像交叉轴的 align-items: stretch 属性

html
<style type="text/css">
  .container {
    display: flex;
    flex-wrap: wrap;
    align-content: stretch;
  }

  .div {
    height: 120px;
  }
</style>

image

8.2 flex-start -- 像交叉轴的 align-items: flex-start 属性

image

8.3 flex-end -- 像交叉轴的 align-items: flex-end 属性

image

8.4 center -- 像交叉轴的 align-items: center 属性

image

8.5 space-between -- 像主轴的 justify-content: space-between

image

8.6 space-around -- 像主轴的 justify-content: space-around

image

8.7 space-evenly -- 像主轴的 justify-content: space-evenly

image

9. order

order 属性定义项目的排列顺序。数值越小,排列越靠前,默认每个 item 为 0。 所以要让它靠前,它至少要为-1, 或者设置其它的 order 比较大

css
.div:nth-of-type(3) {
  order: -1;
}

image

10. flex-grow

  • 定义项目的放大比例, 默认值为 0
  • 何时起作用:和 flex-shrink 相反,当空间足够的时候起作用,则空间已经占满(例子2)不起作用

例子 1 - 如何计算:

  1. 计算剩余空间 300 = 600 - 100 - 100 - 100

  2. flex-grow 每份多少 300 / (5 + 1) =50

  3. 最终宽度

  • 100 + 5 _ 50 = 350
  • 100 + 1 _ 50 = 150
html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
    display: flex;
  }

  .div {
    width: 100px;
    height: 100px;
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>
<div class="container">
  <div class="div" style="flex-grow: 5;">1</div>
  <div class="div" style="flex-grow: 1;">2</div>
  <div class="div">3</div>
</div>

特殊的情况 根据上面的计算公示,若只有一个 item 设置 flex-grow: 1, 那它和设置 flex-grow: 100 是没有区别的,因为剩下的空间都给它占用了。

html
<div class="container">
  <!-- 设置 1 和 100都没有区别 -->
  <div class="div" style="flex-grow: 1;">1</div>
  <div class="div">2</div>
  <div class="div">3</div>
  <div class="div">4</div>
  <div class="div">5</div>
  <div class="div">6</div>
  <div class="div">7</div>
</div>

image

例子 2:

html
<div class="container">
  <!-- flex-grow 不起作用 -->
  <div class="div" style="flex-grow: 5;">1</div>
  <div class="div">2</div>
  <div class="div">3</div>
  <div class="div">4</div>
  <div class="div">5</div>
  <div class="div">6</div>
  <div class="div">7</div>
</div>

image

11. flex-shrink

  • 定义了项目的缩小比例,默认为 1。
  • 不能设置为负数。越大越缩小。
  • 仅在里面所有元素的宽度之和大于容器的时候才会发生收缩。
  • 若所有 itemflex-shrink 属性都为 1,当空间不足时,都将等比例缩小。
  • 若某个 item 设置为 0, 其他 item 都为 1,则空间不足时它不收缩,其它的等比例都收缩。

举例如何计算收缩了多少:

  1. 计算多出的部分 120 * 7 - 600 = 240
  2. 计算加权综合可得 2160 = 240 * 2 + 240 * 2 + 240 * 1 + 240 * 1 + 240 * 1 + 240 * 1 + 240 * 1
  3. 计算溢出的量 1 和 2 溢出: (240 * 2 / 2160) * 240 = 53 其它溢出: (240 * 1 / 2160) * 240 = 27
  4. 最后结果的值 1 和 2 值为: 120 - 53 = 67 其它值为: 120 - 27 = 93
html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
    display: flex;
  }

  .div {
    width: 120px;
    height: 120px;
    background-color: green;
    border: 1px solid #ff0000;
  }
</style>

<div class="container">
  <div class="div" style="flex-shrink: 2;">1</div>
  <div class="div" style="flex-shrink: 2;">2</div>
  <div class="div">3</div>
  <div class="div">4</div>
  <div class="div">5</div>
  <div class="div">6</div>
  <div class="div">7</div>
</div>

image

12. flex-basis

  • 如果没有设置 flex-basis 属性,那么 flex-basis 的大小就是项目的 width 属性的大小
  • 如果没有设置 width 属性,那么 flex-basis 的大小就是项目内容(content)的大小
  • flex-basiswidth 同时存在,则 width 属性被忽略
  • flex-basismin-widthmax-width 同时存在, flex-basis 被忽略
html
<style type="text/css">
  .container {
    width: 600px;
    height: 300px;
    border: 1px solid blue;
    display: flex;
  }

  .div {
    width: 100px;
    height: 100px;
    background-color: green;
    border: 1px solid #ff0000;
  }

  .div:nth-of-type(1) {
    flex-basis: 60px;
    width: 10px; /* 被忽略 */
  }
</style>

<div class="container">
  <div class="div">1</div>
  <div class="div">2</div>
  <div class="div">3</div>
</div>

image

13. flex

flex-grow flex-shrink flex-basis 的简写,后两个属性可选。 默认值为 0 1 auto;

14. align-self

  • auto(默认值) | flex-start | flex-end | center | baseline | stretch;
  • align-items 属性多了一个 auto
  • 继承父容器的 align-items 属性
  • 可覆盖父元素的 align-items 的属性