在以前頁(yè)面布局多依賴于table不从,但table標(biāo)簽太多买雾,于是有了absolute布局藻丢,float布局等剪撬,但它們小問(wèn)題特別多,要用好并不容易悠反。CSS3里引入了Flexible Box彈性盒模型残黑,專門(mén)用于布局。
先看一下Flexible Box彈性盒子(也有翻譯成伸縮盒模型)的基本術(shù)語(yǔ)斋否,直接W3C盜圖:
Flexible Box彈性盒子有兩根軸梨水,main-axis和cross-axis。兩軸的開(kāi)始/結(jié)束位置為main-start/end和cross-start/end茵臭。盒子內(nèi)的各元素在兩軸上的空間為main-size和cross-size疫诽。
Flexible Box彈性盒子由于歷史原因,分成舊版本旦委,混合版本奇徒,新版本。如果你要兼容舊版本的瀏覽器的話(尤其是IE10)噩夢(mèng)就來(lái)了缨硝,你需要準(zhǔn)備多套語(yǔ)法摩钙,開(kāi)發(fā)測(cè)試成本很高。當(dāng)然前景是光明的查辩,等舊式瀏覽器逐漸被淘汰胖笛,彈性盒子的布局必將大放異彩。
先看語(yǔ)法宜岛,以下子屬性設(shè)在容器上:
- diaplay
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
以下子屬性設(shè)在內(nèi)部元素上:
- flex-grow
- flex-shrink
- flex-basis
- flex
- order
- align-self
先看設(shè)在容器上的子屬性
display
應(yīng)用Flexible Box很簡(jiǎn)單匀钧,display屬性新增了flex
和inline-flex
(不特殊說(shuō)明,均為新語(yǔ)法谬返,下同)分別將原本的盒模型改成彈性盒模型之斯。效果見(jiàn)圖。你也可以自行參照例子頁(yè)面(但希望是新式瀏覽器遣铝,用IE就悲劇了…)
.flex {display: flex;} //上圖
.inline-flex {display: inline-flex;} //下圖
<div class="pDivflex"> //下圖將類flex改成inline-flex即可
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
可見(jiàn)一旦將父div設(shè)成display:flex或inline-flex佑刷,就能使內(nèi)部獲得彈性布局的效果,原本應(yīng)該垂直排列的4個(gè)子div酿炸,被默認(rèn)從左到右水平排列了瘫絮。
舊語(yǔ)法:display值不是flex和inline-flex而是box
和inline-box
(且需要加上各瀏覽器前綴,如display: -webkit-box;)
混合版:(主要針對(duì)IE10填硕,因此下面均加上了-ms-前綴)display值不是flex和inline-flex而是-ms-flexbox
和-ms-inline-flexbox
flex-direction
flex-direction用于設(shè)置容器的方向麦萤,值為row
(默認(rèn)值)鹿鳖,row-reverse
,column
壮莹,column-reverse
翅帜。一圖勝千言(圖來(lái)源于阮一峰的博客,但原圖順序似乎不對(duì)…稍作修改)
舊語(yǔ)法:不是flex-direction而是2個(gè)子屬性box-orient
和box-direction
box-orient用于設(shè)置容器排列方式,值為horizontal
(默認(rèn)值)诈唬,vertical
韩脏,inline-axis
,block-axis
铸磅。horizontal或inline-axis等價(jià)于新語(yǔ)法的row骤素,vertical或block-axis等價(jià)于新語(yǔ)法的column。另外inline-axis表示內(nèi)部元素沿著內(nèi)聯(lián)軸排列愚屁,試下來(lái)和horizontal看不出什么區(qū)別济竹。block-axis表示內(nèi)部元素沿著塊軸排列,試下來(lái)和vertical看不出什么區(qū)別霎槐。如果誰(shuí)知道區(qū)別麻煩告訴我送浊,謝謝。
box-direction用于設(shè)置容器排列順序丘跌,值為normal
(默認(rèn)值)袭景,reverse
。因此設(shè)好box-orient后闭树,再加上box-direction: reverse;等價(jià)于新語(yǔ)法的row-reverse/column-reverse耸棒。
混合版:相比新版只需加上-ms-前綴,即-ms-flex-direction
报辱,值同新語(yǔ)法
flex-wrap
flex-wrap用于指定放不下后如何換行与殃。值為nowrap
(默認(rèn)值),wrap
碍现,wrap-reverse
幅疼。你可以參照例子頁(yè)面,并拖動(dòng)頁(yè)面大小昼接,隨著頁(yè)面變窄爽篷,nowarp會(huì)自動(dòng)調(diào)整元素寬度以保持不換行,wrap不改變?cè)貙挾嚷@示不下就換行逐工。wrap-reverse顯示不下?lián)Q行的同時(shí)铡溪,調(diào)整行的順序(恕我經(jīng)驗(yàn)淺薄,wrap-reverse真不知道有什么卵用)
舊語(yǔ)法:不是flex-wrap而是box-lines
泪喊,默認(rèn)值single
表示項(xiàng)目一行或一列顯示棕硫,multiple
表示自動(dòng)換行或多列表示。
混合版:相比新版只需加上-ms-前綴窘俺,即-ms-flex-wrap
饲帅,值同新語(yǔ)法
flex-flow
flex-flow用于合并指定flex-direction和flex-wrap屬性复凳,默認(rèn)值為row nowrap
瘤泪。該屬性單純?yōu)榱撕?jiǎn)化代碼而已,不贅述育八。
舊語(yǔ)法:無(wú)該屬性
混合版:相比新版只需加上-ms-前綴对途,即-ms-flex-flow
,值同新語(yǔ)法
justify-content
justify-content用于main-axis的對(duì)齊髓棋,值為flex-start
实檀,flex-end
,center
按声,space-between
膳犹,space-around
。一圖勝千言签则,不贅述须床。你可以參照例子頁(yè)面
box-pack
,可設(shè)start
渐裂,end
豺旬,center
,justify
(等價(jià)于新語(yǔ)法的space-between)
混合版:不是justify-content而是-ms-flex-pack
柒凉,可設(shè)start
族阅,end
,center
膝捞,justify
(等價(jià)于新語(yǔ)法的space-between)坦刀,distribute
(等價(jià)于新語(yǔ)法的space-around)。
align-items
align-items用于corss-axis的對(duì)齊蔬咬,可設(shè)flex-start
求泰,flex-end
,center
计盒,baseline
(根據(jù)元素的基線)渴频,stretch
。一圖勝千言北启,為展示效果設(shè)置了3和4的font-size卜朗,這樣可以清楚地看出baseline的效果拔第。還設(shè)置了1和2的height,這樣可以看出stretch時(shí)3和4被拉伸了场钉。你可以參照例子頁(yè)面
box-align
蚊俺,可設(shè)start
,end
逛万,center
泳猬,baseline
,stretch
宇植,和新語(yǔ)法相比就值名不同得封。
混合版:不是align-items是-ms-flex-align
,值同舊語(yǔ)法指郁。
align-content
align-content和justify-content有點(diǎn)像忙上,值也類似可設(shè)flex-start
,flex-end
闲坎,center
疫粥,space-between
,space-around
腰懂,stretch
梗逮。區(qū)別是justify-content用于main-axis的對(duì)齊,而align-content用于多行在容器內(nèi)的對(duì)齊方式绣溜。因此一定要多行(必須flex-wrap: wrap且容器不足以將所有元素放入一行內(nèi))才能出效果慷彤,如果容器內(nèi)就一行是沒(méi)有效果的。一圖勝千言涮毫,你可以參照例子頁(yè)面
舊語(yǔ)法:無(wú)該屬性
混合版:不是align-content是-ms-flex-inline-pack
瞬欧,可設(shè)start
,end
罢防,center
艘虎,justify
(等價(jià)于新語(yǔ)法的space-between),distribute
(等價(jià)于新語(yǔ)法的space-around)咒吐,stretch
上面介紹的都是在外層容器上設(shè)的彈性盒子的屬性野建,現(xiàn)在看看給內(nèi)部元素設(shè)的彈性盒子的屬性。
flex-grow
flex-grow將剩余空間按比例擴(kuò)展恬叹。即當(dāng)容器空間大于內(nèi)部元素空間之和時(shí)候生,剩余部分將根據(jù)各元素指定的flex-grow按比例分配,使各元素增大绽昼。默認(rèn)值為0唯鸭,表示剩余空間不分配。
例如硅确,外層div總寬300px目溉,第一個(gè)p長(zhǎng)度80px明肮,第二個(gè)p長(zhǎng)度160px,且兩個(gè)p均不設(shè)flex-grow缭付。這樣后面剩余寬度60px
現(xiàn)在給兩個(gè)p都設(shè)flex-grow:1;
因?yàn)閮蓚€(gè)p的flex-grow值是一樣的柿估,意味原本后面剩余的60px將被均分,每個(gè)p都額外得到30px陷猫。因此第一個(gè)p的寬度80px->110px秫舌,第二個(gè)p的寬度160px->190px
如果第一個(gè)p的flex-grow:2,第二個(gè)p的flex-grow:1不變绣檬。這樣原本后面剩余的60px將被分為3份足陨,第一個(gè)p額外得到40px,寬度80px->120px河咽,第二個(gè)p額外得到20px钠右,寬度160px->180px
因此當(dāng)外層容器寬度大于內(nèi)部元素寬度之和時(shí)赋元,內(nèi)部元素的flex-grow值越大忘蟹,分配到的剩余空間的比例越高,元素就越大搁凸。
舊語(yǔ)法:用box-flex
媚值,具體參見(jiàn)下面
混合版:用-ms-flex
,具體參見(jiàn)下面
flex-shrink
flex-shrink將溢出空間按比例收縮护糖。即當(dāng)容器空間小于內(nèi)部元素空間之和時(shí)褥芒,溢出部分將根據(jù)各元素指定的flex-shrink按比例分配,使各元素縮小嫡良。默認(rèn)值為1锰扶,表示溢出時(shí)等比例縮小
例如,外層div總寬200px寝受,第一個(gè)p長(zhǎng)度80px坷牛,第二個(gè)p長(zhǎng)度160px,且兩個(gè)p都設(shè)flex-shrink:0;很澄,這樣后面將溢出40px
現(xiàn)在給兩個(gè)p都設(shè)flex-shrink:1;京闰,或直接將flex-shrink屬性刪掉(默認(rèn)值就是1)
因?yàn)閮蓚€(gè)p的flex-shrink一樣,原本溢出的40px將被等比例分配甩苛。但這里的等比例和上面flex-grow不同蹂楣,這里的等比例的意思是保持元素原有的比例。原先第一個(gè)p的寬度是80px讯蒲,第二個(gè)p的寬度是160px痊土,比例1:2,因此溢出的40px將仍舊1:2比例分配墨林。第一個(gè)p的寬度80px->66.7px赁酝,第二個(gè)p的寬度160px->133.3px
如果第一個(gè)p的flex-shrink:2反浓,第二個(gè)p的flex-shrink:1不變。原本兩個(gè)p的寬度比是1:2赞哗,現(xiàn)在flex-shrink的比例是2:1雷则。因此溢出的40px將按3:3比例分配,等于均分肪笋。第一個(gè)p縮減為60px月劈,第二個(gè)p縮減為140px
因此當(dāng)外層容器寬度小于內(nèi)部元素寬度之和時(shí),內(nèi)部元素的flex-shrink值越大藤乙,分配到的溢出空間的比例越高猜揪,元素就越小。
舊語(yǔ)法:用box-flex
坛梁,具體參見(jiàn)下面
混合版:用-ms-flex
而姐,具體參見(jiàn)下面
flex-basis
flex-basis定義了剩余或溢出的基準(zhǔn)值。什么是基準(zhǔn)值呢划咐?比如你某元素寬度100px拴念,你將其flex-basis:600px,則該元素將以600px來(lái)計(jì)算剩余或溢出褐缠。默認(rèn)值為auto政鼠,表示基準(zhǔn)值就是元素原始尺寸。
例如队魏,外層div總寬600px公般,5個(gè)p的寬度均為100px:
現(xiàn)在給第3個(gè)p設(shè)flex-basis:600px;(注意不是將其width改成600px)。這樣彈性盒子在計(jì)算時(shí)會(huì)將第3個(gè)p的寬度按600px來(lái)計(jì)算胡桨,這樣5個(gè)p的總寬度為1000px官帘,而容器的寬度是600px,超出了400px昧谊。由于未設(shè)flex-shrink默認(rèn)值為1刽虹,保持原始尺寸比例,因此將按1:1:6:1:1來(lái)分配這溢出的400px揽浙。很容易計(jì)算得出第3個(gè)p將縮小240px状婶,寬度為600px->360px。其他p將縮小40px馅巷,寬度為100px->60px
舊語(yǔ)法:無(wú)該屬性
混合版:用-ms-flex
膛虫,具體參見(jiàn)下面
flex
flex用于合并指定flex-grow和flex-shrink和flex-basis屬性,默認(rèn)值為0 1 auto
钓猬。還有兩個(gè)快捷值auto
等價(jià)于1 1 auto稍刀,none
等價(jià)于0 0 auto。該屬性單純?yōu)榱撕?jiǎn)化代碼而已,不贅述账月。
舊語(yǔ)法:不是flex而是box-flex
综膀,即舊語(yǔ)法中不分flex-grow,flex-shrink統(tǒng)一用box-flex來(lái)設(shè)定局齿,如果容器空間大于元素之和就相當(dāng)于flex-grow剧劝,反之就相當(dāng)于flex-shrink。沒(méi)有flex-basis抓歼。
混合版:相比新版只需加上-ms-前綴讥此,即-ms-flex
,值同新語(yǔ)法
order
order用于指定內(nèi)部元素的顯示順序谣妻,默認(rèn)值0表示元素是根據(jù)DOM的先后順序來(lái)顯示的萄喳,有了該屬性可以輕松調(diào)整順序。值就是順序的序號(hào)蹋半。例如原始不設(shè)order他巨,元素根據(jù)DOM順序顯示。
box-ordinal-group
觉痛,默認(rèn)值為1
混合版:不是order而是-ms-flex-order
役衡,默認(rèn)值為0
align-self
上面介紹過(guò)用align-items為容器指定對(duì)齊方式茵休,你還可以用align-self單獨(dú)為內(nèi)部元素指定對(duì)齊方式。默認(rèn)值auto表示繼承容器的align-items值手蝎,可設(shè)flex-start
榕莺,flex-end
,center
棵介,baseline
钉鸯,stretch
。效果同align-items邮辽。見(jiàn)下圖唠雕,容器的align-items:flex-start,然后分別給2345號(hào)元素指定align-self為flex-end吨述,center岩睁,baseline,stretch揣云。
舊語(yǔ)法:無(wú)該屬性
混合版:不是align-self而是-ms-flex-item-align
捕儒,值為auto
,start
,end
刘莹,center
阎毅,baseline
,stretch
總結(jié)
Flexible Box最大的問(wèn)題就是各瀏覽器廠商間的標(biāo)準(zhǔn)各有不同点弯,導(dǎo)致開(kāi)發(fā)成本很高扇调。雖然有了新版的語(yǔ)法,但如果要兼顧舊版瀏覽器(尤其是IE)的話就有點(diǎn)抓狂了抢肛。好在前景是光明的肃拜,等那些舊版瀏覽器死透透了,F(xiàn)lexible Box必將綻放光芒雌团。下一篇介紹一下它在布局上應(yīng)用燃领,感受一下它的優(yōu)勢(shì)。