這個背後有一個悲傷的故事,所以就取了個這麼有點像標題黨的標題,具體什麼我就不說了。很早之前就知道css3裡面有這麼個東西,而且隨著規范的改變,它的版本也改了幾次。
也就是因為這個flexbox伸縮盒布局太強大了,以至於我沒在意它也是display的一個屬性。
要想解決這個布局問題,我們還是先了解一些基礎的問題。先回顧下display有哪些屬性吧:
none:隱藏對象。與visibility屬性的hidden值不同,其不為被隱藏的對象保留其物理空間
inline:指定對象為內聯元素。block:指定對象為塊元素。
list-item:指定對象為列表項目。inline-block:指定對象為內聯塊元素。(CSS2)
table:指定對象作為塊元素級的表格。類同於html標簽<table>(CSS2)
inline-table:指定對象作為內聯元素級的表格。類同於html標簽<table>(CSS2)
table-caption:指定對象作為表格標題。類同於html標簽<caption>(CSS2)
table-cell:指定對象作為表格單元格。類同於html標簽<td>(CSS2)
table-row:指定對象作為表格行。類同於html標簽<tr>(CSS2)
table-row-group:指定對象作為表格行組。類同於html標簽<tbody>(CSS2)
table-column:指定對象作為表格列。類同於html標簽<col>(CSS2)
table-column-group:指定對象作為表格列組顯示。類同於html標簽<colgroup>(CSS2)
table-header-group:指定對象作為表格標題組。類同於html標簽<thead>(CSS2)
table-footer-group:指定對象作為表格腳注組。類同於html標簽<tfoot>(CSS2)
run-in:根據上下文決定對象是內聯對象還是塊級對象。(CSS3)
box:將對象作為彈性伸縮盒顯示。(伸縮盒最老版本)(CSS3)
inline-box:將對象作為內聯塊級彈性伸縮盒顯示。(伸縮盒最老版本)(CSS3)
flexbox:將對象作為彈性伸縮盒顯示。(伸縮盒過渡版本)(CSS3)
inline-flexbox:將對象作為內聯塊級彈性伸縮盒顯示。(伸縮盒過渡版本)(CSS3)
flex:將對象作為彈性伸縮盒顯示。(伸縮盒最新版本)(CSS3)
inline-flex:將對象作為內聯塊級彈性伸縮盒顯示。(伸縮盒最新版本)(CSS3)
可以看到,目前最新的版本是display:flex ;當然要是用以前過度版本的估計還有用,但我們還是跟著最新的規范來。
我們再了解下伸縮盒的定義和一些概念的東西吧:
Flexbox(伸縮布局盒) 是 CSS3 中一個新的布局模式,為了現代網絡中更為復雜的網頁需求而設計。
雖然現在我們可以使用 Flexbox 輕松創建布局,而不會像以前那樣難以理解,但我們仍然需要花一些時間去熟悉到底如何使用 Flexbox。新的術語和概念可能會是我們使用 Flexbox 時的一個障礙,所以讓我們先來了解以下它們。
Flexbox 由 伸縮容器 和 伸縮項目 組成。通過設置元素的 display 屬性為 flex 或 inline-flex 可以得到一個伸縮容器。設置為 flex 的容器被渲染為一個塊級元素,而設置為 inline-flex 的容器則渲染為一個行內元素。
Flexbox 規范的相關工作已經進展了3年。不同的浏覽器也實現了不同的實驗版本。在2012年9月,Flexbox 語法的第三個主要修訂版本進入到候選推薦階段。這意味著 W3C 認為當前的語法是穩定的,並鼓勵浏覽器開發商去實現它。總之,伸縮盒布局,是我見過的最操蛋的規范,從2009發布到去年最終定下來,更弦換轍了三次。
Flexbox 規范時間表:
2009年7月 工作草案 (display: box;)
2011年3月 工作草案 (display: flexbox;)
2011年11月 工作草案 (display: flexbox;)
2012年3月 工作草案 (display: flexbox;)
2012年6月 工作草案 (display: flex;)
2012年9月 候選推薦 (display: flex;)
Flexbox 已經被浏覽器快速支持。Chrome 22+, Opera 12.1+, 和 Opera Mobile 12.1+ 已經支持了本文中所描述的 Flexbox。Firefox 18 和 Blackberry 10 也很快就會實現。我推薦大家使用已經支持的浏覽器來閱讀本文和查看例子。雖然如此,但是很多浏覽器廠商都高了一個私有前綴,所以特別麻煩:
div{
display: -webkit-box;
display: -moz-box;
display: -o-box;
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
我們再來看看它有哪些屬性:
Properties
屬性 CSS Version
版本 Inherit From Parent
繼承性 Description
簡介
flex CSS3 無 復合屬性。設置或檢索伸縮盒對象的子元素如何分配空間。
flex-grow CSS3 無 設置或檢索彈性盒的擴展比率。
flex-shrink CSS3 無 設置或檢索彈性盒的收縮比率
flex-basis CSS3 無 設置或檢索彈性盒伸縮基准值。
flex-flow CSS3 無 復合屬性。設置或檢索伸縮盒對象的子元素排列方式。
flex-direction CSS3 無 設置或檢索伸縮盒對象的子元素在父容器中的位置。
flex-wrap CSS3 無 設置或檢索伸縮盒對象的子元素超出父容器時是否換行。
align-content CSS3 無 設置或檢索彈性盒堆疊伸縮行的對齊方式。
align-items CSS3 無 設置或檢索彈性盒子元素在側軸(縱軸)方向上的對齊方式。
align-self CSS3 無 設置或檢索彈性盒子元素自身在側軸(縱軸)方向上的對齊方式。
justify-content CSS3 無 設置或檢索彈性盒子元素在主軸(橫軸)方向上的對齊方式。
order CSS3 無 設置或檢索伸縮盒對象的子元素出?的?序。
1:flex
取值:
none:none關鍵字的計算值為: 0 0 auto
[ flex-grow ]:定義彈性盒子元素的擴展比率。
[ flex-shrink ]:定義彈性盒子元素的收縮比率。
[ flex-basis ]:定義彈性盒子元素的默認基准值。
這裡flex-grow,flex-shrink,flex-basis可以單獨使用例如:flex-grow:1,也可以幾個在一起縮寫使用,例如:flex:1 1 100px;表示不擴展也不伸縮,設置寬度為100px。
看一個DEMO:
這裡面一開始定義了每個Box 400px,所以第一個每個小塊都是133px.第二個box(box2)由於每個塊都設置了擴展和伸縮比率還有基准值100px。這裡我們可以計算得:100+100+100=300px,但是因為它的ID設置了寬度為400px,所以會空出100px,但是它還有設置了擴展比率,所以計算得:100*1+100*2+100*3=600px;,最後我們可以算出每個小塊將要增加的寬度:
第一個:1*100/600*100約等於17px;
第二個小塊:2*100/600*100約等於33px;
第三個小塊:3*100/600*100等於50px
也就是說box2裡第一塊區域的寬度為117px,第二小塊的寬度為133px,第三個小塊的寬度為150px;
同樣的算法你可以去試試box3的各個寬度。
2.flex-flow
flex-flow是個復合屬性,接受這兩類值:[ flex-direction ] [ flex-wrap ]。
要不我們先熟悉下flex-direction和flex-wrap吧
flex-direction用來定義彈性盒子元素的排列方向。
語法:flex-direction:row | row-reverse | column | column-reverse默認值是row,無繼承性。
row:橫向從左到右排列(左對齊),默認的排列方式。row-reverse:反轉橫向排列(右對齊,從後往前排,最後一項排在最前面。column:縱向排列。row-reverse:反轉縱向排列,從後往前排,最後一項排在最上面。
看一個DEMO
再來看看:flex-wrap:nowrap | wrap | wrap-reverse 表示定義彈性盒子元素溢出父容器時是否換行。默認值為nowrap。可取值:nowrap:當子元素溢出父容器時不換行。wrap:當子元素溢出父容器時自動換行。wrap-reverse:反轉 wrap 排列。
看一個DEMO:
現在flex-flow的屬性搞清楚了,我們可以結合兩個來寫一個DEMO:
3.再看看align-content屬性吧:
align-content:flex-start | flex-end | center | space-between | space-around | stretch
用於多行的彈性盒模型容器
各個屬性值的意思:
flex-start: 各行向彈性盒容器的起始位置堆疊。彈性盒容器中第一行的側軸起始邊界緊靠住該彈性盒容器的側軸起始邊界,之後的每一行都緊靠住前面一行。
flex-end: 各行向彈性盒容器的結束位置堆疊。彈性盒容器中最後一行的側軸起結束界緊靠住該彈性盒容器的側軸結束邊界,之後的每一行都緊靠住前面一行。
center: 各行向彈性盒容器的中間位置堆疊。各行兩兩緊靠住同時在彈性盒容器中居中對齊,保持彈性盒容器的側軸起始內容邊界和第一行之間的距離與該容器的側軸結束內容邊界與第最後一行之間的距離相等。(如果剩下的空間是負數,則各行會向兩個方向溢出的相等距離。)
space-between: 各行在彈性盒容器中平均分布。如果剩余的空間是負數或彈性盒容器中只有一行,該值等效於’flex-start’。在其它情況下,第一行的側軸起始邊界緊靠住彈性盒容器的側軸起始內容邊界,最後一行的側軸結束邊界緊靠住彈性盒容器的側軸結束內容邊界,剩余的行則按一定方式在彈性盒窗口中排列,以保持兩兩之間的空間相等。
space-around: 各行在彈性盒容器中平均分布,兩端保留子元素與子元素之間間距大小的一半。如果剩余的空間是負數或彈性盒容器中只有一行,該值等效於’center’。在其它情況下,各行會按一定方式在彈性盒容器中排列,以保持兩兩之間的空間相等,同時第一行前面及最後一行後面的空間是其他空間的一半。
stretch: 各行將會伸展以占用剩余的空間。如果剩余的空間是負數,該值等效於’flex-start’。在其它情況下,剩余空間被所有行平分,以擴大它們的側軸尺寸。
看一個DEMO:
4.align-items
語法:align-items:flex-start | flex-end | center | baseline | stretch
每個值的意思:
flex-start: 彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸起始邊界。
flex-end: 彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸結束邊界。
center: 彈性盒子元素在該行的側軸(縱軸)上居中放置。(如果該行的尺寸小於彈性盒子元素的尺寸,則會向兩個方向溢出相同的長度)。
baseline: 如彈性盒子元素的行內軸與側軸為同一條,則該值與’flex-start’等效。其它情況下,該值將參與基線對齊。
stretch: 如果指定側軸大小的屬性值為’auto’,則其值會使項目的邊距盒的尺寸盡可能接近所在行的尺寸,但同時會遵照’min/max-width/height’屬性的限制。
DEMO:
5.align-self
align-self:auto | flex-start | flex-end | center | baseline | stretch默認值:auto
適用於:彈性盒模型子元素繼承性:無
取值:
auto:
如果’align-self’的值為’auto’,則其計算值為元素的父元素的’align-items’值,如果其沒有父元素,則計算值為’stretch’。
flex-start:
彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸起始邊界。
flex-end:
彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸結束邊界。
center:
彈性盒子元素在該行的側軸(縱軸)上居中放置。(如果該行的尺寸小於彈性盒子元素的尺寸,則會向兩個方向溢出相同的長度)。
baseline:
如彈性盒子元素的行內軸與側軸為同一條,則該值與’flex-start’等效。其它情況下,該值將參與基線對齊。
stretch:
如果指定側軸大小的屬性值為’auto’,則其值會使項目的邊距盒的尺寸盡可能接近所在行的尺寸,但同時會遵照’min/max-width/height’屬性的限制
DEMO木有了
6.justify-content
用於設置或檢索彈性盒子元素在主軸(橫軸)方向上的對齊方式。
當彈性盒裡一行上的所有子元素都不能伸縮或已經達到其最大值時,這一屬性可協助對多余的空間進行分配。當元素溢出某行時,這一屬性同樣會在對齊上進行控制。
語法:
justify-content:flex-start | flex-end | center | space-between | space-around
默認值:flex-start
適用於:彈性盒模型容器
繼承性:無
取值:
flex-start:
彈性盒子元素將向行起始位置對齊。該行的第一個子元素的主起始位置的邊界將與該行的主起始位置的邊界對齊,同時所有後續的伸縮盒項目與其前一個項目對齊。
flex-end:
彈性盒子元素將向行結束位置對齊。該行的第一個子元素的主結束位置的邊界將與該行的主結束位置的邊界對齊,同時所有後續的伸縮盒項目與其前一個項目對齊。
center:
彈性盒子元素將向行中間位置對齊。該行的子元素將相互對齊並在行中居中對齊,同時第一個元素與行的主起始位置的邊距等同與最後一個元素與行的主結束位置的邊距(如果剩余空間是負數,則保持兩端相等長度的溢出)。
space-between:
彈性盒子元素會平均地分布在行裡。如果最左邊的剩余空間是負數,或該行只有一個子元素,則該值等效於’flex-start’。在其它情況下,第一個元素的邊界與行的主起始位置的邊界對齊,同時最後一個元素的邊界與行的主結束位置的邊距對齊,而剩余的伸縮盒項目則平均分布,並確保兩兩之間的空白空間相等。
space-around:
彈性盒子元素會平均地分布在行裡,兩端保留子元素與子元素之間間距大小的一半。如果最左邊的剩余空間是負數,或該行只有一個伸縮盒項目,則該值等效於’center’。在其它情況下,伸縮盒項目則平均分布,並確保兩兩之間的空白空間相等,同時第一個元素前的空間以及最後一個元素後的空間為其他空白空間的一半。
DEMO;
7.order
用於設置或檢索彈性盒模型對象的子元素出?的?序。
用法:order:<integer>
<integer>:用整數值來定義排列順序,數值小的排在前面。可以為負值。
DEMO:
上文介紹了flexbox的基本語法和一些屬性的使用,這裡我們通過實戰來更了解這個伸縮盒布局(彈性盒)
我們知道CSS3 彈性盒,是一種當頁面需要適應不同的屏幕大小以及設備類型時確保元素擁有恰當的行為的布局方式。對於很多應用來講,彈性盒在兩個方面相對於盒模型進行了提升,它既不使用浮動,也不會導致彈性盒容器的外邊距與其內容的外邊距之間發生塌陷。
現在我們再來回顧下彈性盒的概念:
彈性盒布局的定義中,它可以自動調整子元素的高和寬,來很好的填充任何顯示設備中的可用顯示空間,收縮內容防止內容溢出。
不同於盒布局的基於垂直方向以及行內布局的基於水平方向,彈性盒布局的算法是方向無關的。 雖然盒布局在頁面中工作良好,但是其定義不足以支持那種需要根據用戶代理從豎直切換成水平等變化而進行方向切換、大小調整、拉伸、收縮的引用組件。不同於將要出現的網格布局針對目標為大比例布局,彈性盒布局更適用於應用組件和小比例布局。這兩種都是CSS工作組為了能與不同用戶代理、不同書寫模式和其他彈性需要進行協作而做出的努力。
我們可以用display:flex和display:inline-flex來創建彈性盒。flex 值表示彈性容器為塊級。inline-flex 值表示彈性容器為原子行級元素 。裡面的元素就稱為彈性子元素
彈性子元素的注意事項
包含在彈性容器內的文本自動成為匿名的彈性子元素。然而,只包含空白的彈性子元素不會被渲染,就好像它被設定為 display:none 一樣。
彈性容器的絕對定位的子元素會被定位,因此其靜態位置會根據它們的彈性容器的主起始內容盒的角落上開始。
目前由於一個已知的問題,在彈性子元素上指定 visibility:collapse
會導致其好像被指定了 display:none 一樣,但該操作的初衷是使元素具有好像被指定了 visibility:hidden 一樣的效果。在該問題被解決之前建議使用visibility:hidden ,其效果在彈性子元素上等同於 visibility:collapse 。
相鄰的彈性子元素不會發生外邊距合並。使用 auto 的外邊距會在垂直和水平方向上帶來額外的空間,這種性質可用於對齊或分隔臨近的彈性子元素。W3C彈性盒子布局模型的 使用’auto’的外邊距進行對齊 部分有更多信息。
彈性盒子的對齊會進行真正的居中,不像CSS的其他居中方法。這意味著即使彈性容器溢出,子元素仍然保持居中。有些時候這可能有問題,然而即使溢出了頁面的 上沿,或左邊沿(在從左到右的語言如英語;這個問題在從右到左的語言中發生在右邊沿,如阿拉伯文),因為你不能滾動到那裡,即使那裡有內容!在將來的版本 中,對齊屬性會被擴展為有一個“安全”選項。目前,如果關心這個問題,你可以使用外邊距來達到居中的目的,這種方式比較“安全”,在溢出的情況下會停止居 中。在你想要居中的彈性子元素上應用自動外邊距代替align-屬性。在彈性容器的第一個和最後一個子元素的外側應用自動外邊距來代替justify-屬性。自動外邊距會伸縮並假定剩余空間,當有剩余空間時居中彈性子元素,沒有剩余空間時切換會正常對齊模式。然而,如果你想要在多線彈性盒子中用基於外邊距的居中替換justify-content屬性,你可能就沒那麼幸運了,因為你需要在每一線的第一個和最後一個元素上應用外邊距。除非你能提前預測哪個元素是哪一線上的最後一個元素,否則你沒法穩定地在主軸上用基於外邊距的居中代替 justify-content 屬性。
說起雖然元素的顯示順序與源代碼中的順序無關,這種無關僅對顯示效果有效,不包括語音順序和基於源代碼的導航。即使是 order 也不影響語言和導航序列。因此開發者必須小心排列源代碼中的元素以免破壞文檔的可訪問性。
下面我們來看兩個例子:
例子展示了如何對元素應用彈性布局以及在彈性布局中子元素的行為
例子2
這個例子適用於桌面浏覽器網頁必須優化以適應於智能手機屏幕的場景。不僅僅需要元素減小尺寸,它們排列的順序方式也必須改變。彈性布局很容易實現這種需求。