Flexbox(伸縮布局盒) 是 CSS3 中一個新的布局模式,為了現代網絡中更為復雜的網頁需求而設計。本文將介紹 Flexbox 語法的技術細節。瀏覽器的支持越來越快,所以當 Flexbox 被廣泛支持並應用時你將會快人一步。如果你想知道它是什么並是如何工作的,不妨仔細了解下吧!
為什么需要伸縮布局盒(Flexbox)?
作者長期以來使用表格、浮動、行內塊元素和其他 CSS 屬性來布局網站內容。然而,這些並不是為復雜的頁面和網頁應用而設計的。不管是簡單的垂直居中,還是靈活的網格布局都很難靠一己之力輕易實現,因此成就了 CSS 網格框架。但是,如果真的需要那么多項目來實現做這些事,為什么不讓它來的更簡單些呢?Flexbox 的目的就是改變這一切。
規范狀態和瀏覽器支持情況
Flexbox 規范的相關工作已經進展了3年。不同的瀏覽器也實現了不同的實驗版本。在2012年9月,Flexbox 語法的第三個主要修訂版本進入到候選推薦階段。這意味着 W3C 認為當前的語法是穩定的,並鼓勵瀏覽器開發商去實現它。
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 也很快就會實現。我推薦大家使用已經支持的瀏覽器來閱讀本文和查看例子。
概念和術語
雖然現在我們可以使用 Flexbox 輕松創建布局,而不會像以前那樣難以理解,但我們仍然需要花一些時間去熟悉到底如何使用 Flexbox。新的術語和概念可能會是我們使用 Flexbox 時的一個障礙,所以讓我們先來了解以下它們。
Flexbox 由 伸縮容器 和 伸縮項目 組成。通過設置元素的 display 屬性為 flex
或 inline-flex
可以得到一個伸縮容器。設置為 flex
的容器被渲染為一個塊級元素,而設置為 inline-flex
的容器則渲染為一個行內元素。
這里的示例創建了一個伸縮容器。
.flex-container { display: -webkit-flex; display: flex; }
本文中所有的示例都會帶有相應的瀏覽器廠商前綴。
伸縮容器中的每一個子元素都是一個伸縮項目。伸縮項目可以是任意數量的。伸縮容器外和伸縮項目內的一切元素都不受影響。簡單地說,Flexbox 定義了伸縮容器內伸縮項目該如何布局。
Flex Lines 伸縮行
伸縮項目沿着伸縮容器內的一個 伸縮行 定位。通常每個伸縮容器只有一個伸縮行。
這個示例展示了2個項目在默認情況下的定位:沿着一個水平伸縮行從左至右顯示。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <style type="text/css"> .flex-container { display: -webkit-flex; display: flex; width: 300px; height: 240px; background-color: Silver; } .flex-item { background-color: DeepSkyBlue; width: 100px; height: 100px; margin: 5px; } </style> <body> <div class="flex-container"> <div class="flex-item">flex item 1</div> <div class="flex-item">flex item 2</div> </div> </body> </html>
伸縮容器的屬性
flex-direction 伸縮流的方向
flex-direction
允許你更改伸縮容器的主軸方向。flex-direction
的默認值是 row
。該值表示伸縮項目根據書寫模式
的方向布局。再次提醒,默認是從左至右,從上到下。其他的值如下:
- row-reverse: 主軸起點和主軸終點交換。如果書寫模式是從左至右,伸縮項目則是從右往左顯示。
- column: 主軸和側軸交換。如果書寫系統是垂直的,那么伸縮項目也是垂直顯示的。
- column-reverse: 和 column 一樣,但是方向相反。
讓我們把前一個示例中的 flex-direction
改為 column
。
現在我們的伸縮項目就是垂直顯示的了。
justify-content 主軸(水平方向)對齊
伸縮容器的 justify-content
屬性用於調整主軸上伸縮項目的位置。可能的值為:
- flex-start:伸縮項目向一行的起始位置靠齊(默認值)
- flex-end:伸縮項目向一行的結束位置靠齊(默認值)
- center:居中
- space-between:平均分布在行里,第一個元素在一行中的最開始位置,最后一個元素在一行中的最終位置
- space-around:平均分布在行里,兩端保留一半的空間
這里我們設置 justify-content
為 center
讓伸縮項目在主軸上居中對齊:
align-items 側軸(垂直方向)對齊
align-items
是一個和 justify-content
相呼應的屬性。align-items
調整伸縮項目在側軸上的定位方式。可能的值有:
- flex-start
- flex-end
- center:居中
- baseline:根據元素的基線對齊
- stretch:默認值
這里我們設置 align-items
為 center
讓伸縮項目在側軸上居中對齊:
和之前一樣,flex-start
, flex-end
, 和 center
的意義顯而易見。stretch
也很簡單:它會將伸縮項目從側軸起點拉伸到側軸終點。baseline
則是讓伸縮項目與它們的基線對齊。基線根據伸縮項目的內容計算得到。下面這張來自W3C標准的圖例很好的解釋了這些屬性:
flex-wrap 伸縮行換行
目前為止,每個伸縮容器都有且只有一個伸縮行。使用 flex-wrap
你可以為伸縮容器創建多個伸縮行。這個屬性接受以下值:
- nowrap:單行顯示(默認值)
- wrap:多行顯示
- wrap-reverse
如果 flex-wrap
設置為 wrap
,在一個伸縮行容不下所有伸縮項目時,伸縮項目會換行到一條新增的伸縮行上。新增的伸縮行根據側軸的方向添加。
我們使用 flex-wrap
來看個例子:
wrap-reverse
和 wrap 一樣,只是新的伸縮行會被添加到側軸的反方向上。
align-content 堆棧伸縮行
align-content
會更改 flex-wrap
的行為。它和 align-items
相似,但是不是對齊伸縮項目,它對齊的是伸縮行。可能你已經想到了,它接受的值也很相似:
- stretch (默認)
- flex-start:各行向伸縮容器的起點位置堆疊
- flex-end:各行向伸縮容器的結束位置堆疊
- center:各行向伸縮容器的中間位置堆疊
- space-between:各行向伸縮容器中平均分布
- space-around:各行向伸縮容器的中平均分布,在兩邊各有一半控件
這些值與 justify-content
和 align-items
中的值一樣。
flex-flow 伸縮方向與換行
flex-flow
是 flex-direction
和 flex-wrap
的縮寫。
flex-flow: [flex-direction] [flex-wrap]
舉個例子:
.flex-container { -webkit-flex-flow: column nowrap; flex-flow: column nowrap; }
伸縮項目的屬性
一個伸縮項目是一個伸縮容器的子元素。伸縮容器中的文本也被視為一個伸縮項目。
伸縮項目中內容與普通流一樣。舉例來說,當一個伸縮項目被設置為浮動,你依然可以在這個伸縮項目中放置一個浮動元素。
伸縮項目都有一個 主軸長度(Main Size) 和一個 側軸長度(Cross Size)。主軸長度是伸縮項目在主軸上的尺寸。側軸長度是伸縮項目在側軸上的尺寸。或者說,一個伸縮項目的寬或高取決於伸縮容器的軸,可能就是它的主軸長度或側軸長度。
下面的屬性可以調整伸縮項目的行為:
order 顯示順序
order
是最簡單明了的屬性。設置伸縮項目的 order 可以調整它們渲染時的順序。在這個例子中,我們設置其中一個伸縮項目(flex item 2)的order
為 -1,於是它被提前到了其他伸縮項目的最前面。
如果需要文檔順序和顯示順序不同時,這就是個很有用的功能了。
margin 外邊距
你應該對 margin: auto;
的這種用法很熟悉。在伸縮盒中,它也能做同樣的事情,但是更加強大。一個 "auto" 的 margin 會合並剩余的空間。它可以用來把伸縮項目擠到其他位置。
這里我們在第一個伸縮項目上聲明了 margin-right: auto;
,導致了所有的剩余空間被合並到那個元素的右邊去了:
這里我們使用 margin: auto;
來重現經典CSS布局中的聖杯:真·垂直居中:
flex 伸縮性
現在我們終於要開始設置伸縮盒的伸縮性了。flex
指定了一個伸縮項目該如何分配主軸上的剩余空間。
讓我們一次把所有的常見值都看一遍吧。
flex: [number]
這個語法指定了一個數字,代表了這個伸縮項目該占用的剩余空間比例。
在這個例子中,第一個伸縮項目占用了 2/4 的剩余空間,而另外兩個各占用了 1/4 的剩余空間。
如果把每個伸縮項目都設置為 1 的話,那么剩余空間就會被平均分配了。
flex: initial
一個 flex
屬性值被設為 initial
的伸縮項目,在有剩余空間的情況下不會有任何變化,但是在必要的情況下會被收縮。
flex: auto
一個 flex
屬性值被設為 auto
的伸縮項目,會根據主軸自動伸縮以占用所有剩余空間。
auto
目前僅在 Opera 12.11 尚有效,在 Chrome 23.0.1271.95 上無效。你可以通過使用 flex: 1;
來達到一樣的效果。
flex: none
一個 flex
屬性值被設為 none
的伸縮項目,在任何情況都不會發生伸縮。
flex 縮寫
flex
也可以把 flex-grow
, flex-shrink
, 和 flex-basis
這3個縮寫為1個聲明:
flex: [flex-grow] [flex-shrink] [flex-basis]
大多數情況下沒必要使用這種語法。另外,它需要一個更容易理解的伸縮算法。如果你覺得自己挺厲害的,到規范里看一下吧。
當然你也可以將 flex-grow
, flex-shrink
, 和 flex-basis
作為單個屬性分開來設置。但我強烈反對這種方式:當使用flex
縮寫時,即使沒有某些值沒有設置也能獲得更合理的默認值。
visibility 疊加項目
當該值生效時,應用 visibility: collapse;
和 visibility: hidden;
與 display: none;
的效果是不一樣的。如果是 collapse
,該元素會影響伸縮容器的側軸長度,但不會被現實或占用主軸的空間。如果你想動態添加或移除伸縮項目又不會影響伸縮容器的側軸長度,這將會非常有用。
目前為止,visibility: collapse;
還沒有被讓任何瀏覽器正確的實現。現在 visibility: collapse;
還和visibility: hidden;
實現着一樣的效果。我希望能盡快得到改觀。
你可以在 這里 看到 collapse
應該是如何工作的。
總結
如你所見,伸縮布局盒(Flexbox) 是一個強大的新型布局模式,將會給網站帶來革命性的布局方法,但它也需要一種全新的思考方式。希望這篇文章能為你使用伸縮布局盒構建網站帶來幫助。我不知道你怎么想,但是在我看來未來是美好的。
原文:Dive into Flexbox (http://weblog.bocoup.com/dive-into-flexbox)
參考資料:Css3-flexbox (http://www.w3.org/html/ig/zh/wiki/Css3-flexbox)
轉自:[譯]深入了解 Flexbox 伸縮盒模型:http://c7sky.com/dive-into-flexbox.html
本文轉自:http://www.w3cplus.com/blog/666.html