深入淺出Flexbox

簡書的Markdown貌似不支持插入iframe,所以文章里的JSFiddle示例都改做截圖了漏益,如果有需要可以點擊下面的鏈接,到眾成查看深胳,英文版鏈接一并附上绰疤。
譯者:kangflict(飛揚)
鏈接:http://www.zcfy.cc/article/966
原文:https://bocoup.com/weblog/dive-into-flexbox

簡介

Flexbox 是 CSS3 中提出的新布局模型,用于適應現(xiàn)代網(wǎng)絡開發(fā)中日益復雜的布局需求稠屠。 近來峦睡,F(xiàn)lexbox 的語法逐漸穩(wěn)定下來,本文來為大家揭開它的神秘面紗权埠,并盤點其技術細節(jié)榨了。瀏覽器支持將會快速增長,因此當對 Flexbox 的支持足夠廣泛以至達到實用水平時攘蔽,你將會在這場游戲當中拔得頭籌龙屉。如果想要了解它的工作方式和原理,那么就繼續(xù)讀下去吧满俗!

為什么需要 Flexbox转捕?

長期以來,人們使用 table唆垃、float五芝、inline-block 以及其他 CSS 特性來對站點內容進行布局。然而辕万,這些工具沒有一個是為當前的復雜網(wǎng)頁或網(wǎng)絡應用設計的枢步。像垂直居中這樣的簡單的需求都需要費點兒力氣才能滿足,以至于我們通常認為單槍匹馬實現(xiàn)靈活柵格布局這樣的需求不太現(xiàn)實渐尿,因此各種 CSS 柵格布局框架獲得了巨大的成功醉途。

規(guī)范進展與瀏覽器支持

Flexbox 規(guī)范的相關工作已經(jīng)進行 3 年之久,很多瀏覽器廠商都發(fā)布了其實驗性質的實現(xiàn)砖茸。2012 年 9 月隘擎,針對 Flexbox 語法的第三次主要修訂進入了 W3C 的候選推薦階段。這說明 W3C 對當前的語法是滿意的凉夯,并鼓勵瀏覽器廠商進行實現(xiàn)货葬。

Flexbox 規(guī)范大事年表:

  • 2009 年 7 月,工作草案(display: box;)
  • 2011 年 3 月劲够,工作草案(display: flexbox;)
  • 2011 年 11 月宝惰,工作草案(display: flexbox;)
  • 2012 年 3 月,工作草案(display: flexbox;)
  • 2012 年 6 月再沧,工作草案(display: flex;)
  • 2012 年 9 月,候選推薦(display: flexe;)

各個瀏覽器都在積極地接納 Flexbox尊残。本文寫就之時炒瘸,Chrome 22+淤堵、Opera 12.1+ 以及 Opera Mobile 12.1+ 均已支持 Flexbox。Firefox 18Blackberry 10 也將馬上跟進顷扩。我建議使用支持 Flexbox 的瀏覽器來閱讀本文拐邪,以便觀察示例如何工作。

相關概念和術語

盡管在 Flexbox 的幫助下隘截,以前千辛萬苦才能實現(xiàn)或者根本不敢想象的布局都能輕而易舉地實現(xiàn)扎阶,但要真正習慣以 Flexbox 的方式進行布局還是需要一定的時間。在使用 Flexbox 時婶芭,新的術語或概念都可能成為攔路虎东臀,因此我們先來討論一下術語和概念的問題。

Flexbox 布局涉及 Flex 容器(Flex Container)和 Flex 項目(Flex Item)犀农。Flex 容器的 display 屬性為 flexflexbox惰赋。flex 屬性使得容器渲染為塊級元素,而 inline-flex 則使其渲染為行內元素呵哨。

下面是聲明 Flex 容器的示例:

.flex-container {
  display: -webkit-flex;
  display: flex;
}

本文中的所有代碼示例都將包含全面的瀏覽器廠商前綴赁濒。

Flex 容器的任何子元素都是 Flex 項目,并且 Flex 項目可以有任意多個孟害。Flex 容器之外的任何元素以及 Flex 項目內的元素都將照常渲染拒炎。簡而言之,F(xiàn)lex 容器決定 Flex 項目在其內部的布局方式挨务。

Flex 布局線(Flex Line)

在Flex容器內击你,F(xiàn)lex 項目沿 Flex 布局線 排布。默認情況下耘子,每個容器只有一條 Flex 布局線果漾。

Flex 容器

上圖的示例展示了默認情況下兩個項目在容器中的排布:從左到右,沿水平 Flex 布局線排列谷誓。

Paste_Image.png

書寫模式(Writing Modes)

使用 Flexbox 進行富有創(chuàng)造性的布局不可避免地要改變 Flex 布局線的方向绒障。默認情況下,F(xiàn)lex 布局線與文本書寫方向一致:從左到右捍歪,從上到下户辱。

W3C 有一個工作草案,是關于一項稱作書寫模式(Writing Modes)的新特性的糙臼。書寫模式為從右至左或縱向的文字排布提供了新的實現(xiàn)方式庐镐,在對特定的語言進行排版時常會遇到這樣的需求。

書寫模式仍然處于半成品狀態(tài)变逃,不過 direction 屬性已經(jīng)在 Chrome 中得到了支持必逆。上面的示例中,如果如果我們將 direction 的值設置為 rtl (從右到左),那么不光文本內容會從右往左渲染名眉,F(xiàn)lex 布局線的方向也會改變粟矿,從而影響頁面的布局。

Paste_Image.png

這或許就是很多與 Flexbox 相關的術語非常抽象的原因损拢。如果不能確定頁面語言的話陌粹,我們就不能簡單地用“上”“下”“左”“右”來代表布局方向。

主軸與側軸(Main Axis and the Cross Axis)

Flexbox 通過引入概念主軸(Main Axis)和側軸(Cross Axis)來體現(xiàn)對書寫模式的支持福压。Flex 布局線與主軸的方向一致掏秩,而側軸則與主軸正交。

主軸與側軸

每條軸的起點荆姆、終點以及方向的名字如下所示:

  • 主軸起點(Main Start)
  • 主軸終點(Main End)
  • 主軸方向(Main Direction蒙幻,有時也稱作流方向,即 Flow Direction)
  • 側軸起點(Cross Start)
  • 側軸終點(Cross End)
  • 側軸方向 (Cross Direction)

主軸和側軸兩個術語非常重要胞枕,我們有必要在繼續(xù)之前將其徹底搞懂杆煞。在使用 Flexbox 進行布局的時候,任何東西都與此有關腐泻。本文所有的示例中决乎,書寫模式都是從左往右從上往下的,但是我們必須了解并不一定所有情況下都是如此派桩。

Flex 容器之屬性

flex-direction

flex-direction 能夠改變 Flex 容器的軸向构诚。flex-direction 的默認值為 row,即按照 writing-mode 的方向對 Flex 項目進行排布铆惑,默認情況下從左到右范嘱,從上往下。其他可能的值如下:

  • row-reverse:主軸起點和終點對換员魏。如果書寫模式(writing-mode)從左往右丑蛤,那么此時 Flex 項目會由右往左進行排布;
  • column:主軸與側軸對換撕阎。如果書寫系統(tǒng)為水平方向的受裹,那么 Flex 項目將沿縱向排布;
  • column-reverse:與column的效果相同虏束,只是軸向翻轉棉饶。

將前面示例中的 flex-direction 值改為 column

Paste_Image.png

現(xiàn)在镇匀,F(xiàn)lex 項目變?yōu)榭v向排列的了照藻。

justify-content

Flex 容器的 justify-content 屬性用于控制 Flex 項目在主軸上的位置『骨郑可能的值有:

  • flex-start(默認值)
  • flex-end
  • center
  • space-between
  • space-around

justify-content 的值設置為 center 能夠讓 Flex 項目沿主軸居中:

Paste_Image.png

flex-start幸缕、flex-end 以及 center 的含義相當直截群发,但是 space-betweenspace-around 這兩個用于確定 Flex 項目間留白的屬性值的含義就不那么明顯了。下面這張來自規(guī)范的示意圖對各個屬性值做出了最佳詮釋:

justify-content示例
justify-content示例

align-items

align-items 是對 justify-content 的補充发乔,它確定的是 Flex 項目在側軸上的位置也物。可能的取值有:

  • flex-start(默認值)
  • flex-end
  • center
  • baseline
  • stretch

我們將 align-items 的值設置為 center列疗,從而讓 Flex 項目在側軸居中排布:

Paste_Image.png

flex-startflex-endcenter 的含義仍舊直截了當浪蹂,strech 也相當簡單:讓 Flex 項目充滿從側軸起點到側軸終點的所有空間抵栈。baseline 則使得 Flex 項目沿基線對齊±ご危基線是由 Flex 項目的內容計算得出的古劲。下面出自 Flexbox 規(guī)范的示意圖對此做出了最佳闡釋:

align-items示意圖
align-items示意圖

flex-wrap

到現(xiàn)在為止,每個 Flex 容器都只有一條 Flex 布局線缰猴,利用 flex-wrap 屬性产艾,就可以得到有多條 Flex 布局線的的容器。flex-wrap 可選的值如下:

  • nowrap(默認值)
  • wrap
  • wrap-reverse

如果 flex-wrap 的值為 wrap滑绒,那么當一條 Flex 布局線無法容納所有 Flex 項目時闷堡,多余的項目就會折轉到附加的 Flex 布局線上。新添的 Flex 布局線沿側軸的方向排列疑故。

這里有一個使用 flex-wrap 的示例:

Paste_Image.png

wrap-reverse 的效果與 wrap 相同杠览,只是 Flex 布局線將沿與側軸相反的方向添加。

align-content

align-content 能夠影響 flex-wrap 的行為纵势。它與 align-items 類似踱阿,但是并不是用于對齊 Flex 項目,而是用于對齊 Flex 布局線钦铁。正如你所想软舌,它們可能的取值也非常相似:

  • stretch(默認值)
  • flex-start
  • flex-end
  • center
  • space-between
  • space-around

這些值的效果與它們在 align-items 中的表親基本相同。

這里牛曹,我們將 align-content 設為 center

Paste_Image.png

flex-flow

flex-flowflex-directionflex-wrap 的簡寫:

flex-flow: [flex-direction] [flex-wrap]

例如:

gistfile1.css

.flex-container {
  -webkit-flex-flow: column nowrap;
  flex-flow: column nowrap;
}

Flex 項目之屬性

Flex 項目是 Flex 容器的直接子元素佛点,F(xiàn)lex 容器中的文字段落也會被當做 Flex 項目處理。

Flex 項目的內容則會照常渲染躏仇。例如恋脚,float 屬性對 Flex 項目不起作用,但是 Flex 項目內部卻可以存在浮動元素焰手。

我們稱 Flex 項目有主軸尺寸側軸尺寸糟描。主軸尺寸是 Flex 項目在主軸方向上的尺寸,側軸尺寸則是 Flex 項目在側軸方向上的尺寸书妻。事實上船响,通常 Flex 項目的寬和高分別就是它的主軸尺寸和側軸尺寸躬拢,不過這取決于 Flex 容器的軸的設置。

下面的屬性能夠影響 Flex 項目的行為见间。

order

order 最為簡單聊闯,它控制著 Flex 項目的渲染順序。本例中米诉,我們將一個 Flex 項目的 order 屬性設置為 -1菱蔬,從而使其顯示在所有其他元素之前。

Paste_Image.png

這對可訪問性來說可能非常有用史侣,因為有時我們需要文檔結構和頁面展示以不同的順序出現(xiàn)拴泌。

margin

你或許已經(jīng)對 margin: auto; 在通常情況下的效果非常熟悉了。在 Flexbox 的世界里惊橱,它仍然發(fā)揮著相似的作用蚪腐,只不過更加的強大∷捌樱“自動”邊距能夠吸收掉多余的空白回季,從而將 Flex 項目推到不同的位置上去。

這里正林,我們?yōu)榈谝粋€ Flex 項目設定 margin-right: auto;泡一,從而使得該項目右邊所有多余的空白都被吸收掉:

Paste_Image.png

接著,我們使用 margin: auto; 來摘取 CSS 排版的圣杯:真正的垂直居中卓囚!

Paste_Image.png

align-self

Flex 項目的 align-self 屬性能夠覆蓋 Flex 容器為其指定的 align-items 屬性瘾杭。兩個屬性具有相同的取值范圍:

  • stretch(默認)
  • flex-start
  • flex-end
  • center
  • baseline

此例中,我們?yōu)槊總€ Flex 項目指定了不同的 align-self 值:

Paste_Image.png

上例中有兩個 Flex 項目的 align-items 值為 baseline哪亿,這是因為 baseline 項目是以彼此為參照來進行對齊的粥烁。

flex

終于到 Flexbox 中的 flex 屬性了。flex 確定了 Flex 項目在主軸剩余空間排布時的策略蝇棉。

讓我們來逐一過目 flex 的常見取值:

flex: [數(shù)字]

該語法通過指定一個數(shù)字讨阻,來確定當前 Flex 項目占主軸剩余空間的比例。

本例中篡殷,第一個 Flex 項目占剩余空間的 2/4钝吮,其余兩個 Flex 項目各占 1/4:

Paste_Image.png

將每個項目的 flex 屬性都設置為 1 是一項非常有用的技巧,此時主軸剩余空間將被平均分配給各個 Flex 項目板辽。

Paste_Image.png

flex: initial

flex 屬性為 initial 的項目將會失去彈性伸縮能力奇瘦,但是在必要的時候仍然能夠縮小(被擠芯⑾摇)耳标。

flex: auto

flex 屬性為 auto 的項目擁有在主軸上進行彈性伸縮的所有能力。

目前邑跪,Opera 12.11 能夠支持 auto次坡,但是 Chrome 23.0.1271.95 還不可以呼猪。實際上,我們只需要使用 flex: 1 就可以繞過這個問題砸琅。

flex: none

flex 屬性為 none 的項目在任何情況下都不具備彈性伸縮的能力宋距。

flex 進階

事實上,flexflex-grow症脂、flex-shrinkflex-basis 的簡寫:

flex: [flex-grow] [flex-shrink] [flex-basis]

不過谚赎,多數(shù)情況下我們都不需要這樣寫,它需要對 flex 背后的算法更為精深的理解诱篷。如果你覺得自己是真正的猛士沸版,看這里的規(guī)范

我們也可以為 flex-grow兴蒸、flew-shrink 以及 flex-basis 分別指定屬性值。但是我強烈建議你不要這樣做细办,因為當使用 flex 簡寫形式時橙凳,瀏覽器會為沒有值的屬性指定更有意義的默認值。

visibility

如果有實現(xiàn)支持的話笑撞,對于 Flex 項目岛啸,visibility: collapse; 應當表現(xiàn)得與 visibility: hidden;display: none; 不同。具有該屬性的 Flex 項目將會影響所在 Flex 容器的側軸尺寸茴肥,但是并不占據(jù)主軸方向的空間义起,也不可見裁替。這對動態(tài)添加移除 Flex 項目非常有用,同時也不影響 Flex 容器的側軸尺寸。

目前诱渤,visibility: collapse; 貌似在任何瀏覽器上都沒有得到正確的支持。當前的實現(xiàn)中拘荡,visibility: collapse; 的行為看上去與 visibility: hidden; 相同勿锅。我期待這種情況趕緊得以改觀。

這里有一個還不錯的 collapse 模擬實現(xiàn)皆警,能夠讓你看到規(guī)范中 collapse 是如何工作的拦宣。

總結

如你所見,F(xiàn)lexbox 是一種強大的新式布局工具信姓,將從根本上變革我們現(xiàn)有的網(wǎng)站布局手段鸵隧。亦如所見,它需要我們使用全新的思考方式來進行布局意推。我希望這篇文章能夠在你開始使用 Flexbox 對網(wǎng)站進行布局時幫你一把豆瘫。不知道你信不信,反正我是看到了光明的未來左痢。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末靡羡,一起剝皮案震驚了整個濱河市系洛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌略步,老刑警劉巖描扯,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異趟薄,居然都是意外死亡绽诚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門杭煎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恩够,“玉大人,你說我怎么就攤上這事羡铲》渫埃” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵也切,是天一觀的道長扑媚。 經(jīng)常有香客問我,道長雷恃,這世上最難降的妖魔是什么疆股? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮倒槐,結果婚禮上旬痹,老公的妹妹穿的比我還像新娘。我一直安慰自己讨越,他們只是感情好两残,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著把跨,像睡著了一般磕昼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上节猿,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天票从,我揣著相機與錄音,去河邊找鬼滨嘱。 笑死峰鄙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的太雨。 我是一名探鬼主播吟榴,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼囊扳!你這毒婦竟也來了吩翻?” 一聲冷哼從身側響起兜看,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狭瞎,沒想到半個月后细移,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡熊锭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年弧轧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碗殷。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡精绎,死狀恐怖,靈堂內的尸體忽然破棺而出锌妻,到底是詐尸還是另有隱情代乃,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布仿粹,位于F島的核電站襟己,受9級特大地震影響,放射性物質發(fā)生泄漏牍陌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一员咽、第九天 我趴在偏房一處隱蔽的房頂上張望毒涧。 院中可真熱鬧,春花似錦贝室、人聲如沸契讲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捡偏。三九已至,卻和暖如春峡迷,著一層夾襖步出監(jiān)牢的瞬間银伟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工绘搞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留彤避,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓夯辖,卻偏偏與公主長得像琉预,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蒿褂,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內容