最近遇到个问题:flex:1;
跟flex:1 1 0;
是否等价。按照我以前对W3C属性值语法的理解,flex:1;
应该是flex:1 1 auto;
的缺省写法,剩下的两个flex-shrink
和flex-basis
的坑应该分别对应1
和auto
。嗯,若是我没记错的话,简写属性(shorthand)有个特性:对于缺省值会重置为对应的单个属性的初始值(详情请参看《CSS权威指南第三版》P130)。这里的flex-shrink
和flex-basis
就是缺省的单个属性。但是常规测试(弹性子项未填充内容)都不能让人明显感知到flex:1;
跟flex:1 1 0;
的区别。那么问题来了:How Can We Feel The Difference?css
首先,肯定咱们要作什么?经过实验了解flex的缺省auto跟0有何区别。html
而后,给出代码(能够去个人Github上找到名为shorthand_flex_test的两个文件查看源代码):git
.contain { background: #aec; height: 100px; display: flex; justify-content: space-around;/*设置主轴方向均分对齐*/ flex-flow: row wrap;/*设置正常水平排列*/ align-items: stretch;/*设置全部弹性子项拉伸到弹性容器高度*/ } .item { border: 3px solid rgba(0,0,0,.2); padding: 10px; background: #eac; color: #fff; font-size: 2em; font-weight: bold; text-align: center; }
效果图:github
接下来,看实验。web
第一步:flex:1;
和 flex:1 1 auto;
根据官方定义,缺省值就是初始值,两个实现出来的效果就应该相同。chrome
给.item设置flex:1;
,效果图以下:app
给.item设置flex:1 1 auto;
,效果图:编辑器
WTF?不对!工具
先别急,F12看下设置flex:1;
时devtool窗口里的计算值测试
再看看设置flex:1 1 auto;
时的计算值(这句是废话,请自动省略)
小结:原来缺省的时候不是取的单项的初始值啊(flex-shrink:1
和flex-basis:auto
)。那么这个0%
是否是就等价于0
呢?
第二步,此次改成设置flex:1 1 0;
图仍是这样的,但是计算值不同啊,以下
小结:其实百分比的计算值是以父类容器的宽度为基数计算的,而长度值0
直接取值不用再计算,可是0%
和0
的最终计算值都是0px
。
因此说开始的疑问获得解答了:flex:1;
跟flex:1 1 0;
的视觉效果和最终计算值是同样的,只不过是计算过程不一样。
Part 1. 既然都作实验了,那么能够“顺便”研究一下,flex
的几个经常使用值的几种写法,这里是drafts.csswg.org的连接。
第一种:
flex:initial;
等价于flex:0 1 auto;
,也等价于flex:0 auto;
给.item设置flex:initial;
计算值
小结:这里是auto
自适应获得的10%
。这个属性声明获得的效果就是使得弹性子项在有多余空间的时候不拉伸,在空间不足时收缩到最小的宽度/高度(由主轴方向决定具体的计算基数)。这里的宽度/高度可能涉及到弹性子项内部的文本内容,内容的有无使得auto
跟另外一个flex-basis
的属性content
有差别,后面讲。另外,当设置为这个属性值的时候,弹性容器上设置的主轴方向对齐效果和margin:auto;
居中效果才能生效。
第二种:
flex:auto;
等价于flex:1 1 auto;
给.item设置flex:auto;
计算值
小结:这使得弹性子项在有多余空间时拉伸,在空间不足时收缩。这时候弹性子项才有完整的弹性效果,而当多个弹性子项设置不一样的flex
属性声明时,任何多余空间都将被设置了auto
属性值的弹性子项“吸取”掉。
第三种,
flex:none
等价于flex:0 0 auto;
给.item设置flex:none
计算值
小结:这使得弹性子项彻底失去弹性效果。效果跟设置auto
属性值差很少,可是一旦内容溢出弹性容器,这里的弹性子项是不会收缩的。
Part 2. 继续,看看以前提到的content
是怎么回事。
第一步,咱们来跟initial
的等价值作个对照。initial
的就不贴了,Part1的第一种里有。直接看flex:0 1 content;
计算值
分析:什么状况?!flex
的计算值呢?前面的none
都会有计算值的,这里居然不见了!稍等,可不能够这样理解,在设置content
的时候,前面两个值能够忽略?
第二步,设置flex:content;
计算值
分析:果真是一毛同样的。BUT,WHY?content
究竟是干啥子的?
标准里说这个属性值设置会使得弹性子项的宽度/高度直接由其中的内容决定。哦~,难怪对照效果中明显是上面那组的弹性子项“们”是被内容撑开了的。
でも、这岂不是跟不设置flex
属性没两样了!书读少勿欺我!保险起见,我只能开“大招”了:
-webkit-flex: content; -moz-flex: content; -ms-flex: content; -o-flex: content; flex: content;
计算值里仍是找不到flex
的影子
第三步,再在第二步的“大招”基础上加个width:100px;
计算值里还只没影儿
分析:这里给每一个弹性子项设置了固定宽度(由于这水平轴就是主轴),由于没有flex
属性的伸展因子flex-grow
和收缩因子flex-shrink
的影响,每一个弹性子项都“老老实实的”按照justify-content: space-around
的指令水平对齐了(嘴上说着不要“身体”仍是挺老实的嘛,啧啧)。
好吧,只能认可,content
是个无效的属性值。对!它并非属性值。好大一个玩笑(轻点,别打脸)。它只是表示弹性子项的宽度/高度由内容决定,即被内容撑开。而这个撑开的宽度/高度则做为伸展因子和收缩因子的基数进行相应弹性变化的计算。
Part 3. 凭什么说被内容撑开的宽度/高度就是连体因子(舌头打结了)的计算基数?不服来辩!
第一步,先看不设置flex
属性时上面对照实验中上面一组的数据(记得“关了”width
),从左至右:
能够看到第一个no1和第三个no3的宽度是相同的84.297,第二个是290.875。这里要注意由于box-sizing
初始值是content-box
,因此内容区宽就是width
的取值,边距边框都不用管。
第二步,设置一个伸展因子flex:1 1 auto;
这里必须设置flex-basis:auto;
由于缺省后就是flex-basis:0%;
了,至关于以撑开的宽度/高度做为的基数置零了。效果图就不上了,对应前面的flex:auto;
,下面是计算值
能够看到此次的第一个no1和第三个no3的宽度是126.813,第二个是333.391。而后让咱们搬出伸展因子的计算公式:
flex-basis + flow-grow / sum( flow-grow ) * remain
这里的flow-grow指的就是flex-flow
方向上的伸展因子的数值,而因为设置了flex-basis:auto;
主轴的基数flex-basis的计算值应该就是第一步的数据84.29七、290.875和84.297;remain则是容器总宽度减去第一步中的全部宽度总和的结果:
665 - ( 84.2969 + 290.875 + 84.2969) - (10 + 3) * 2 * 3 = 127.5312
这里由于是算的弹性容器内的区域因此要把内边距和边框都加上,另外以前在盒模型里显示的84.297不是精确值,最下面的计算值清单里的精确值是84.2969,以避免引发后面结果错误。
最后套入公式:
第二部中第一个和第三个弹性子项的宽:
84.2969 + ( 1 / 3 ) * 127.5312 = 126.8073 (这里跟126.813很接近,可是我找不出那里算漏了的,有知道的朋友麻烦告知,谢谢)
第二个弹性子项的宽:
290.875 + (1 / 3 ) * 127.5312 = 333.3854(待查错)
这一部分先到这里吧。花了我很久时间,好晚了。
flex
的缺省值并不是是单一属性的初始值,而且还有经常使用的简写属性值initial
、auto
和none
;当弹性子项没有设置固定宽度(对于水平的状况,也就是宽度自己是auto
的)时,flex-basis
若是也是auto
,那么flex-basis
的使用值就是弹性子项的内容自己撑起来的宽度(对于水平的状况)
操做系统:window 7 ultimate 64bit
chrome内核版本:45.0.2454.101
编辑器:Sublime Text 3
在查找资料过程当中,发现一些不错的东西,分享加收藏一下。
不明觉厉的网站和文章:http://ptb2.me/
CSS Flexbox试验场:http://vagor.cc/demo/flexbox-demo/index.html
Flexbox-推陈出新:https://css-tricks.com/old-flexbox-and-new-flexbox/
先这样了,为了发完这文章熬夜了。熊猫君思密达。
对了代码能够去个人Github上找,说完了。
再补一点信息,必定不要忘了标准的文档开篇说的:
Publication as a Candidate Recommendation does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.1