这篇文章发布于 2019年12月22日,星期日,15:52,归类于 CSS相关。 阅读 59020 次, 今日 11 次 45 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9132
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
CSS flex属性属性还是很难理解的,但是flex布局要想玩得溜溜溜,这一关必须得过,来来来,一起看看究竟是什么意思,如何更容易理解与记忆。
一、flex属性是一种简写
首先flex
属性是flex-grow
,flex-shrink
和flex-basis
的缩写。
等下,已经晕了!
flex-grow
是谁?flex-shrink
是哪位?flex-basis
又是何人?
稍安稍安,这3个CSS属性我们后面会详细展开,这里就先三言两句稍微提一下他们的作用。
这flex布局就好像是有钱人家分家产。
故事是这样的,范闲和林婉儿生了5个孩子,分别叫做范张,范鑫,范旭,范帅和范哥。
要是只有一个孩子,那好说,家产100%继承。但是现在5个孩子,要是不提早定好家产分配规则,万一哪天提前翘辫子,那分家产时候扯皮事情就多了,说不定还会兄弟反目,甚至闹出人命。
而这个flex
属性的作用就是制定了每个人该如何分配到家产的规则。
flex-basis
就是分配固定的家产数量。flex-grow
就是家产剩余家产仍有富余的时候该如何分配。flex-shrink
就是家产剩余家产不足的时候该如何分配。
具体分配细节这里先不展开,当务之急,我们先捋一捋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;
//zxx: 评论有人反馈,IE和Chrome的默认值不一样,因此,建议实际开发都写全3个值。
文字表述
- 1个值
- 如果flex的属性值只有一个值,则:
- 如果是数值,例如
flex: 1
,则这个1
表示flex-grow
,此时。更正为:此时flex-shrink
和flex-basis
都使用默认值,分别是1
和auto
flex-shrink
和flex-basis
的值分别是1
和0%
,注意,这里的flex-basis
的值是0%
,而不是默认值auto
。 - 如果是长度值,例如
flex: 100px
,则这个100px
显然指flex-basis
,因为3个缩写CSS属性中只有flex-basis
的属性值是长度值。此时更正为:此时flex-grow
和flex-shrink
都使用默认值,分别是0
和1
。flex-grow
和flex-shrink
都是1
,注意,这里的flex-grow
的值是1
,而不是默认值0
。
- 如果是数值,例如
- 2个值
- 如果flex的属性值有两个值,则第1个值一定指
flex-grow
,第2个值根据值的类型不同表示不同的CSS属性,具体规则如下:- 如果第2个值是数值,例如
flex: 1 2
,则这个2
表示flex-shrink
,此时更正为:此时flex-basis
使用默认值auto
。flex-basis
计算值是0%
,并非默认值auto
。 - 如果第2个值是长度值,例如
flex: 1 100px
,则这个100px
指flex-basis
,此时flex-shrink
使用默认值0
。
- 如果第2个值是数值,例如
- 3个值
- 如果
flex
的属性值有3个值,则这长度值表示flex-basis
,其余2个数值分别表示flex-grow
和flex-shrink
。下面两行CSS语句的语法都是合法的,且含义也是一样的:/* 下面两行CSS语句含义是一样的 */ flex: 1 2 50%; flex: 50% 1 2;
三、flex属性值深入
下面到了最后一步,对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-shrink:1
,因此,会缩小,表现效果就是文字换行。如下:关键CSS代码和HTML代码如下:
.container { display: flex; }
<div class="container"> <item>范张</item> <item>范鑫</item> <item>范旭</item> <item>范帅</item> <item>范哥</item> </div>
您可以狠狠地点击这里:CSS flex:initial布局效果demo
- auto
flex:auto
等同于设置"flex: 1 1 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布局效果demo
- none
flex:none
等同于设置"flex: 0 0 auto"
。图示如下:
其行为表现文字描述为:
子项会不会增长变大占据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布局效果demo
flex财产分配三剑客
最后再说说一开始提到的flex-grow
,flex-shrink
和flex-basis
。
一定要牢记这3个属性默认值,不然遇到只有1~2个参数时候,根本不知道什么意思。
- flex-grow
flex-grow
指定了容器剩余空间多余时候的分配规则,默认值是0
,多余空间不分配。- flex-shrink
flex-shrink
指定了容器剩余空间不足时候的分配规则,默认值是1
,空间不足要分配。- flex-basis
flex-basis
则是指定了固定的分配数量,默认值是auto
。如会忽略设置的同时设置width
或者height
属性。flex-basis
包含大量的细节知识,这个可以专门开一篇文章深入探讨。
首先解释下,为什么会有容器剩余空间多余和不足的情况出现?
我们还是要分配财产的例子去说明。
范闲的财产分配遗嘱是自己50岁时候制定的。由于范张,范鑫和范旭都已经成家立业,自己在外独立生活,因此,给这三人分配了固定数目的财产,每人100万;而范帅和范哥尚未成年,和范闲还住在一起,所以,遗嘱就是剩下的财产两人评分,按照50岁时候的资产,也是人均100万的样子。
但是世事难料,谁知没过几年,家道中落,范闲总资产已经不足300万,此时,扣除答应范张,范鑫和范旭的300万,已经没有都与家产了,范帅和范哥就要喝西北风了,这就是容器剩余空间不足的情况。
为了应对各种状况出现,因此,财产分配规则制定的时候,一定要明确好基本财产数量flex-basis
,财产有多余时候的分配规则flex-grow
,以及财产不足时候的分配规则flex-shrink
。
案例
请实现:
HTML结构如下:
<div class="container"> <item clas="zhang">范张</item> <item clas="xin">范鑫</item> <item clas="xu">范旭</item> <item clas="shuai">范帅</item> <item clas="ge">范哥</item> </div>
大家可以想想CSS代码该怎么写……
拿出纸和笔,自己写写看……
假设你自己已经写好了,可以对比看一下是不是下面我写的一样:
.container { /* 范闲:来,家产分配开始了~ */ display: flex; } .zhang { /* 老大不会争夺多余财产,但是会在财产不足时候分出老二老三分出的2倍的财产,这是作为老大应有的姿态 */ flex: 0 2 100px; } .xin, .xu { /* 老二和老三不会争夺多余财产,但是会在财产不足时候分出部分财产,照应老四和老幺 这里也可以直接写成:flex: 100px*/ flex: 0 1 100px; } .shuai { /* 老四会争夺多余财产,且会在财产不足时候享用哥哥们分出的财产,确保能够活下去,感谢三位哥哥的照顾 */ flex: 3 0 20px; } .ge { /* 老五会争夺多余财产,不过比例比哥哥少一点,且会在财产不足时候享用哥哥们分出的财产,感谢哥哥们的照顾 */ flex: 2 0 20px; }
最终的效果参见下面的GIF录屏+实时标注说明:
极端情况下,几个哥哥会财产小到几乎饿死,而依然保证两位弟弟有20万的保底财产,多么感人的兄弟情啊!
如果你现在已经理解上面这个兄弟5个分配财产的案例,则说明你对flex的学习和理解已经更上一层楼了,可以顺利毕业了。
眼见为实,您可以狠狠地点击这里:CSS flex属性综合应用布局demo
四、结语碎碎念
有些人在使用flex
实现一些效果的时候,会配合min-width
/max-width
属性,让规律子项的布局更加智能,实际上,是多余的,多此一举,虽然最终实现的效果看上去不错啊,实际上,只需要一个flex
属性就可以搞定了,这个打算在下一篇文章,flex-basis属性深入的时候介绍。
好,本文的内容就这么多。
如果你觉得本文的内容不错,欢迎分享,分享加分享。
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9132
(本篇完)
- flex:0 flex:1 flex:none flex:auto应该在什么场景下使用? (0.959)
- 写给自己看的display: flex布局教程 (0.897)
- Oh My God,CSS flex-basis原来有这么多细节 (0.828)
- flex-end为什么overflow无法滚动及解决方法 (0.241)
- 粉丝群第1期CSS小测点评与答疑 (0.179)
- 让CSS flex布局最后一行列表左对齐的N种方法 (0.145)
- 一万年了,CSS text-align-last终于可以用了 (0.138)
- CSS高宽不等图片固定比例布局的三重进化 (0.131)
- CSS columns轻松实现两端对齐布局效果 (0.103)
- 纯CSS实现微信列表左滑显示按钮的交互效果 (0.103)
- 深入理解CSS3 gradient斜向线性渐变 (RANDOM - 0.007)
感谢作者写的文章,很有帮助
厉害,受教了
谢谢,很形象
当父元素为200px时,帅哥都分20px;
张新旭分别压缩2倍1倍1倍的内容显示在剩下的尺寸里;
怎么计算出 张 为30px 新旭各位65px呢?
厉害了,看了之后豁然开朗
flex: 1 100px,则这个100px指flex-basis,此时flex-shrink使用默认值0。
此处有误,
正确应该为:flex-grow:1; flex-shrink:1; flex-basis:100px;
第一次看云里雾里 今天看一遍再结合自己最近的项目明白了
儿子们名字虽然起的low,但是讲的是真的好
最后财产分配案例,HTML结构中 item项的 class 都缺少一个 s
父容器flex,column布局,子元素一个固定高度height:200px,另外一个flex:1瓜分剩余高度,第二个子元素的子元素怎么继承父元素高度?
就是都进去哦额
话说不用浮动,flex怎么可以实现文字环绕图片的效果
精品,如果只有如果只有300w,是否两个弟弟还是都有20w
网上看了一堆水文,醍醐灌顶的唯有这篇,感谢!!!
.shuai {
/* 老四会争夺多余财产,且会在财产不足时候分出财产,感谢哥哥们的照顾,不过我的保底家底也小 */
flex: 3 0 20px;
}
对这里有点疑问,【且会在财产不足时候分出财产】flex: 3 0 20px; 的flex-shrink值是0,在不足的时候应该不会缩小自己的空间吧?求大神解答,拜谢
这里表述有歧义,我修改下
你好,请教两个问题。
1、flex布局怎么设置间距,类似grid-gap:
2、一个Div里面有N个P标签,默认所有P标签内容居中显示,请问怎么实现,当有任意一个P标签里面内容发生换行的时候,所以P标签内容居左显示,Div为宽度自适应。
麻烦请解答一下,最好以邮件方式回复,944743144#qq.com 当然最好带附上dome
在此感谢
固定间距可以用子元素margin再加上父元素负margin来实现。
至于第二个问题,你想本来内容是居中的,当内容超过一行就左对齐,才疏学浅,做不到
一看就是大妈shende
主要是看到,范闲和林婉儿的图片才点进来的,手动狗头
超级赞
flex: 1 表示的是 flex: 1 1 0, flex-basis 的默认值是 0。
我记得以前 chrome 的表现是 1 1 auto; 忘记版本了,但是 chrome 79 中的 flex: 1 表现是 1 1 0;
参考:
https://stackoverflow.com/questions/37386244/what-does-flex-1-mean
这个问题应该是前两年的了,现在都9102年了当然是需要什么学什么。所谓的学习成本其实没有你预想的高,只不过你自己给他设置了门栏 框架掌握都是基础
总共只有40万怎么办?
张鑫旭为0,帅哥各20万?
总共不到40万怎么办?
溢出,你可以理解为借债了
文章很好,就是读起来一股浓浓的直男癌风
第四个孩子,他不是叫“范帅和”吗?\(^o^)/~
ie的默认值和chrome不同, 所以建议每次都写全3个值..
flex-shrink
flex-grow指定了容器剩余空间不足时候的分配规则,默认值是1,空间不足要分配。
flex-grow,应该是flex-shrink
厉害了,我的弓长金金金九日哥
形象生动
想听听大佬对目前前端框架的理解,现在新的框架层出不穷,VUE,react已经是很多公司招前端必须要会的,但是学习成本又很高,让人苦恼
shrink 为零的时候为什么还会捐出财产(⊙⊙?)
讲的透彻,以前一直对这个使用不是得心应手,要细细再品品
学习了
印象深刻的就是:张鑫旭帅哥!
嘿嘿嘿,不应该是“能大能小的鸡鸡”吗?
我不这样认为的
打搅了
> 子项会不会增长变大占据flex容器中额外的剩余空间(flex-grow:1),也不会收缩变小以适合容器(flex-shrink:1),尺寸根据自身宽高属性进行调整(flex-basis:auto)。
关键字 none 的部分有编辑错误。
如果第2个值是长度值,例如flex: 1 100px,则这个100px指flex-basis,此时flex-shrink都使用默认值0。
—–
flex-shrink的默认值是1,这里写成0了
赞 flex-shrink的默认值是1
配合min-width/max-width很真实了哈哈哈,学到了,以后用basis
入木三分
前排占座