CSS flex属性的深层次理解

目录
文章目录隐藏
  1. flex 属性的语法
  2. flex 属性值深入
  3. 结语

在 CSS 中,flex 属性是使用来设置或检索弹性盒模型对象的子元素如何分配空间,是 flex-grow 属性、flex-shrink 属性和 flex-basis 属性的简写属性。flex 属性针对的是弹性盒模型对象的子元素,对于其它元素,flex 属性不起任何作用。但是 flex 布局要想玩得溜溜溜,还是需要我们对 flex 属性深入的理解才行,一起来看一下。

flex 属性的语法

语法

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

上面这种 CSS 语法被称为格式化语法,大部分 CSS 属性值都比较简单,格式化语法看不出有什么优势。但是如果 CSS 属性值比较的复杂,规则较多,例如 CSS 渐变或者这里的 flex 属性,则格式化语法就比较重要了,可以知道一些平时没有注意到的语法上的细节,也能一看就知道语法规则。

有人会反驳,你这是在扯犊子吧,“一看就知道语法规则”,我看上面各种交错的字符,根本就不知道说的什么意思,还不如直接给我展示几个例子实际呢!

这种体验类似使用 Markdown 语法写文章,在不了解 Markdown 语法的时候,还是觉得可视化操作来得实用。但是如果 Markdown 语法很熟悉,对吧,是不是“真香”就来了?

CSS 语法规则也是一样的,觉得看起来吃力不方便是因为不理解规则。

所以,要想 CSS 学得专业且深入,CSS 语法规则一定要很熟悉。

回到这里,我们一点点对语法进行解构,顺便带大家了解下 CSS 语法中的一些特殊符号的含义。

语法解构

CSS 语法中的特殊符号的含义绝大多数就是正则表达式中的含义,例如单管道符|,方括号[],问号?,个数范围花括号{}等。具体说明:

首先是单管道符|。表示或者。也就是这个符号前后的属性值都是支持的。因此,下面这些语法都是支持的:

flex: auto;
flex: none;

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

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

flex: auto;
flex: none;

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

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

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

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

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

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

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-shrink 和 flex-basis 都使用默认值,分别是 1 和 auto。
  • 如果是长度值,例如 flex: 100px,则这个 100px 显然指 flex-basis,因为 3 个缩写 CSS 属性中只有 flex-basis 的属性值是长度值。此时 flex-grow 和 flex-shrink 都使用默认值,分别是 0 和 1。

2 个值

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

  • 如果第 2 个值是数值,例如 flex: 1 2,则这个 2 表示 flex-shrink,此时 flex-basis 使用默认值 auto。
  • 如果第 2 个值是长度值,例如 flex: 1 100px,则这个 100px 指 flex-basis,此时 flex-shrink 都使用默认值 0。

3 个值

如果 flex 的属性值有三个值,则这 3 个值分别表示 flex-grow,flex-shrink 和 flex-basis。这个顺序该如何记忆,时间久了岂不是很容易忘记。这个告诉大家我的邪恶记忆法,叫做“能大能小的鸡鸡”。grow 是增加变大意思,shrink 是收缩变小的意思,而 basis 是基(鸡)础基(鸡)准的意思,于是连起来就是“能大能小的鸡鸡”。

帅气

flex 属性值深入

关键字属性值

initial

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

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

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

该默认值图形示意如下:

初始值分解示意

其行为表现文字描述为:

不会增长变大占据 flex 容器中额外的剩余空间(flex-grow:0),会收缩变小以适合容器(flex-shrink:1),尺寸根据自身宽高属性进行调整(flex-basis:auto)。

案例

于是如果我们只给容器设置 display:flex,同时子项元素内容都很少,就会有下图所示的效果:

flex:initial 布局效果

如果子项内容很多,由于 flex-shrink:1,因此,会缩小,表现效果就是文字换行。如下:

内容很多时候的表现

关键 CSS 代码和 HTML 代码如下:

.container {
    display: flex;
}

<div class="container">
    <item>码云</item>
    <item>笔记</item>
    <item>程序</item>
    <item>前端</item>
    <item>开发</item>
</div>

auto

flex:auto 等同于设置”flex:1 1 auto”。

图示如下:

auto 关键字分解示意

其行为表现文字描述为:

子项会增长变大占据 flex 容器中额外的剩余空间(flex-grow:1),会收缩变小以适合容器(flex-shrink:1),尺寸根据自身宽高属性进行调整(flex-basis:auto)。

案例

HTML 不变,子项元素的 CSS 增加 flex:auto 的设置:

.container {
    display: flex;
}
.container item {
    flex: auto;
}

结果就是下面这样,子项宽度变大填满了剩余空间,由于每一个子项元素的 flex-grow 的值都是 1,因此,5 等分填充。

CSS flex:auto 布局效果

none

flex:none 等同于设置”flex:0 0 auto”。

图示如下:

none 的分解示意图

其行为表现文字描述为:

子项会不会增长变大占据 flex 容器中额外的剩余空间(flex-grow:0),也不会收缩变小以适合容器(flex-shrink:0),尺寸根据自身宽高属性进行调整(flex-basis:auto)。

案例

HTML 不变,每个子项内容很多,同时子项元素的 CSS 增加 flex:none 的设置:

.container {
    display: flex;
}
.container item {
    flex: none;
}

结果就是下面这样,子项宽度超过了容器的尺寸,由于 flex-shrink 的值都是 0,因此,不会收缩变小导致子项的内容撑爆了容器。

CSS flex:none 布局效果

结语

有些人在使用 flex 实现一些效果的时候,会配合 min-width/max-width 属性,让规律子项的布局更加智能,实际上,是多余的,多此一举,虽然最终实现的效果看上去不错啊,实际上,只需要一个 flex 属性就可以搞定了,这个打算在下一篇文章,flex-basis 属性深入的时候介绍。

内容学习整理来源:张鑫旭老师《CSS flex 属性深入理解

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » CSS flex属性的深层次理解

发表回复