flex布局理解

前言

首先flex属性是flex-growflex-shrinkflex-basis的缩写。

flex属性的作用就是制定了每个人该如何分配到家产的规则

  • flex-basis就是分配固定的家产数量。
  • flex-grow就是家产剩余家产仍有富余的时候该如何分配。
  • flex-shrink就是家产剩余家产不足的时候该如何分配。
语法
1
flex: none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

首先是单管道符|。表示排他。也就是这个符号前后的属性值都是支持的,且不能同时出现。因此,下面这些语法都是支持的:

1
2
3
4
flex: auto;
flex: none;

flex: [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

接下来是[ ... ]这一部分。其中方括号[]表示范围。也就是支持的属性值在这个范围内。我们先把方括号[]内其他特殊字符去除,可以得到下面的语法:

1
2
3
4
flex: auto;
flex: none;

flex: [ <'flex-grow'> <'flex-shrink'> <'flex-basis'> ]

这就是说,flex属性值支持空格分隔的3个值,因此,下面的语法都是支持的。

1
2
3
4
flex: auto;
flex: none;
/* 3个值 */
flex: 1 1 100px;

然后我们再看方括号[]内的其他字符,例如问号?,表示0个或1个。也就是flex-shrink属性可有可无。因此,flex属性值也可以是2个值。因此,下面的语法都是支持的。

1
2
3
4
5
6
flex: auto;
flex: none;
/* 2个值 */
flex: 1 100px;
/* 3个值 */
flex: 1 1 100px;

然后我们再看双管道符||,是或者的意思。表示前后可以分开独立合法使用。也就是flex: flex-grow flex-shrink?flex-basis都是合法的。于是我们又多了2种合法的写法:

1
2
3
4
5
6
7
8
9
10
11
12
flex: auto;
flex: none;
/* 1个值,flex-grow */
flex: 1;
/* 1个值,flex-basis */
flex: 100px;
/* 2个值,flex-grow和flex-basis */
flex: 1 100px;
/* 2个值,flex-grow和flex-shrink */
flex: 1 1;
/* 3个值 */
flex: 1 1 100px;
文字表述
1个值

如果flex的属性值只有一个值,则:

  • 如果是数值,例如flex: 1,则这个1表示flex-grow,此时flex-shrinkflex-basis的值分别是10%,注意,这里的flex-basis的值是0%,而不是默认值auto
  • 如果是长度值,例如flex: 100px,则这个100px显然指flex-basis,因为3个缩写CSS属性中只有flex-basis的属性值是长度值。此时flex-growflex-shrink都是1,注意,这里的flex-grow的值是1,而不是默认值0
2个值

如果flex的属性值有两个值,则第1个值一定指flex-grow,第2个值根据值的类型不同表示不同的CSS属性,具体规则如下:

  • 如果第2个值是数值,例如flex: 1 2,则这个2表示flex-shrink,此时flex-basis计算值是0%,并非默认值auto
  • 如果第2个值是长度值,例如flex: 1 100px,则这个100pxflex-basis,此时flex-shrink使用默认值0
3个值

如果flex的属性值有3个值,则这长度值表示flex-basis,其余2个数值分别表示flex-growflex-shrink。下面两行CSS语句的语法都是合法的,且含义也是一样的:

1
2
3
/* 下面两行CSS语句含义是一样的 */
flex: 1 2 50%
flex: 50% 1 2;
关键字属性值

initial

初始值。flex:initial等同于设置"flex: 0 1 auto"。可以理解为flex属性的默认值。任意打开一个页面,我们打开控制台执行下面的代码:

1
2
window.getComputedStyle(document.body).flex;
// 结果就是"flex: 0 1 auto"

也就是flex属性默认值是"0 1 auto",等同于initial关键字的计算值。

flex财产分配三剑客

最后再说说一开始提到的flex-growflex-shrinkflex-basis

一定要牢记这3个属性默认值,不然遇到只有1~2个参数时候,根本不知道什么意思。

  • flex-grow

    flex-grow指定了容器剩余空间多余时候的分配规则,默认值是0,多余空间不分配。

  • flex-shrink

    flex-shrink指定了容器剩余空间不足时候的分配规则,默认值是1,空间不足要分配。

  • flex-basis

    flex-basis则是指定了固定的分配数量,默认值是auto。如会忽略设置的同时设置width或者height属性。flex-basis包含大量的细节知识,这个可以专门开一篇文章深入探讨。

参考地址