最近遇到個問題: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