我能夠確定,您對於頁面上水平或垂直排列的樣式元素已經瞭解得夠多了。可是,CSS 還缺乏適用於此任務的合適機制。瞭解 CSS3 彈性方框模型(簡稱 Flexbox)php
該草案將 Flexbox 描述以下:css
[...]針對接口設計而優化的 CSS 框模型。除了 CSS 中已有的佈局系統以外,該模型還提供了一個額外的佈局系統。[CSS21] 在這個新的框模型中,框的子代採用水平或垂直佈局,並且可將未使用的空間分配給特定的子代,或者經過「彈性」分配給應展開的子代,在各子代間進行分配。這些框的嵌套(水平嵌套在垂直中,或垂直嵌套在水平中)可用於在兩個維度中構建佈局。該模型是以 XUL 用戶界面語言的模型爲基礎的,適用於多種基於 Mozilla 應用程序(例如 Firefox)的用戶界面。
太棒了。對於您這樣的開發人員,哦不對,是佈局架構師™來講,這意味着什麼呢?html
Flexbox 爲 display
屬性賦予了一個新的值(即 box 值),還爲咱們提供了 8 個新的屬性:html5
box-orient
box-pack
box-align
box-flex
box-flex-group
box-ordinal-group
box-direction
box-lines
8 個新屬性啊?沒錯,是否是以爲太多了?那好,咱們來分別介紹一下。css3
display: box
box-orient
horizontal
|
vertical
|
inherit
inline-axis
(真正的默認值)和
block-axis
,可是它們分別映射到水平和垂直方向。
box-pack
start
|
end
|
center
|
justify
box-orient
軸的框排列方式。所以,若是
box-orient
是水平方向,就會選擇框的子代的水平排列方式,反之亦然。
box-align
start
|
end
|
center
|
baseline
|
stretch
box-pack
的同級屬性。設置框的子代在框中的排列方式。若是方向是水平的,該屬性就會決定垂直排列,反之亦然。
box-flex
0
| 任意整數
1
的子代佔據父代框的空間是彈性比爲
2
的同級屬性的兩倍。其默認值爲
0
,也就是不具備彈性。
上面的 box-flex-group
、box-ordinal-group
、box-direction
和 box-lines
屬性我就不介紹了,由於老實說,您的大部分 Flexbox 做品都未必會用到這些。若是您在使用中想了解這些屬性,請訪問摘要中的連接。web
關於語法的說明:目前,要在 Webkit 和 Gecko 中實施 Flexbox,就必須使用供應商前綴。在本教程中,爲了清晰起見,我略去了大部分此類內容。有關詳情,請參閱瀏覽器支持部分。瀏覽器
box-flex
樣式屬性定義了 Flexbox 的子代是彈性仍是非彈性的,而且有助於定義該子代相對其同級的彈性比。咱們來演示一下這到底是什麼意思。首先,咱們從 3 個框開始。架構
<divid="flexbox"><p>child 1</p><p>child 2</p><p>child 3</p></div>
如今,咱們要將它們水平相鄰排列,並且不管其中的內容如何都要始終保持一樣的高度。目前您會怎樣處理這個問題?大部分人可能不假思索地就浮動這些段落,也許向父代添加 overflow:hidden;
以便清除浮動定位。沒什麼特別的招數。可是利用 Flexbox,咱們就能輕鬆實現一樣的目的。佈局
#flexbox { display: box; box-orient: horizontal;}
在上面的代碼中,咱們只需告知父代根據此 Flexbox 模型進行操做,並沿水平軸排列其全部子代。不用任何浮動。好耶!flex
子代的寬度仍保留指定值(或者在未指定的狀況下保留其固有寬度)。這意味着若是全部子代的總寬度小於父代的總寬度,咱們就會獲得這樣的效果:
默認狀況下,Flexbox 的子代仍爲非彈性。這可能看起來有點奇怪,可是這樣就使得子代有機會加入彈性體驗。可是若是您但願第一和第二個子代具備特定寬度,而第三個子代根據父代中的可用空間自行調整寬度,那要怎麼作呢?這種狀況下就輪到 Flexbox 大顯身手了:
#flexbox { display: box; box-orient: horizontal;}#flexbox > p:nth-child(3) { box-flex:1;}
咱們將最後一個子代設爲彈性的,以佔據可用空間。因爲咱們只對一個元素分配了空間,它將佔據全部可用空間。
請注意,該元素只有在框的軸向上是具備彈性的;在本例中,也就是在水平方向上具備彈性。
box-flex 的值是相對值。所以,若是咱們將第二和第三個子代設爲彈性的:
#flexbox { display: box; box-orient: horizontal;}#flexbox > p:nth-child(2),#flexbox > p:nth-child(3) { box-flex:1;}
它們將各佔據一樣大小的可用空間,實際上就是平分了可用空間。
如今,咱們也能夠將 3 個子代的 box-flex
分別設爲 1
、2
和 3
,而後它們就會按照這樣的比例吸取其父代的多餘空間。讓咱們實際操做看看。
查看下面的代碼和結果:
懸停在某個框上,查看彈性框的實際效果:當懸停目標展開時,其他的框就會縮小,可是總寬度始終和父代框的大小保持一致。
此處採用的樣式其實只有兩種:display: box
將內容轉爲 Flexbox 模式,而後子代的 box-flex: 1
在彈性模式下運行這些內容,從而佔據全部額外空間。默認方向爲水平,所以 box-orient: horizontal
其實並非必需的,可是爲了表達清晰和便於維護,最好仍是加上。默認的 box-align
是彈性的,所以這些 div 佔據了其父代框的整個高度。還不錯吧?您能夠在拉斐爾·戈特 (Raphael Goetter) 製做的這一演示中瞭解此技術在導航中的應用。
讓咱們更深刻一些。
在 CSS 中,將對象在水平和垂直方向上的居中一直以來都是個挑戰。在僅限 CSS 的前提下,咱們能拿出的最佳解決方案就是 position:absolute; left: 50%; top: 50%;
與等於一半寬度/高度的負左側/頂部邊距相結合。而這隻能搭配大小肯定的元素。啊!
詹姆斯·約翰·馬爾科姆 (James John Malcom) 寫道,有一種方法能夠根據至少有 6 年曆史的 display:table-cell;
(杜桑·亞諾夫斯基 (Dušan Janovský) 曾在 2004 年寫過)來垂直對齊。詹姆斯在此記錄了完整的水平和垂直解決方案。此方案甚至不須要大小肯定的元素便可生效。
藉助 Flexbox,咱們能夠更輕鬆地實現這一點:
咱們並不在子代上設置 box-flex
,由於咱們不但願它使用額外空間。咱們只但願它不管大小如何都居中。這樣作的一大優點在於,咱們無需知道明確的尺寸便可將其居中。一般,咱們可使用塊或內聯對象來完成此操做。就是這麼好用。
那麼您如今就能在工做中使用彈性框模型嗎?還不行,至少不是對全部瀏覽器都有效。目前,咱們還沒有在 IE9 或 Opera 10.60 中實現 Flexbox,可是它曾在 IE9 Platform 的某個預覽中出現過,所以微軟有可能在將來某個時間添加此功能。
Caniuse.com 列出了當前支持的瀏覽器,即 Firefox 3 及更高版本、Safari 3 及更高版本以及 Chrome 瀏覽器。若是您要開發的是移動 Webkit,那麼 Flexbox 將是標準佈局方案的絕佳替代品。
固然,全部這些仍處於實驗階段,所以您仍是應該使用供應商前綴:
/* i wish it was as easy as this: */ display: box; box-orient: horizontal; box-pack: center; box-align: center;
/* but in reality you'll need to do this: */ display:-webkit-box;-webkit-box-orient: horizontal;-webkit-box-pack: center;-webkit-box-align: center; display:-moz-box;-moz-box-orient: horizontal;-moz-box-pack: center;-moz-box-align: center; display: box; box-orient: horizontal; box-pack: center; box-align: center;
若是您以爲這牽涉到不少分類,艾利克斯·拉塞爾 (Alex Russell) 將全部這些選項概括成了一些實用的幫助類別。
即便不考慮其餘 4 個屬性,也已經存在了不少可能性。要進一步瞭解 Flexbox,請參閱 Isotoma 的 Flexbox 演示和 Mozilla Hacks 上關於 Flexbox 的帖子。W3C Flexbox 規範。開始動手設計些佈局吧。盡情體驗吧!