文章簡介:新css屬性為我們提供了更加便捷的網頁布局方式。來自微軟的thomas lewis將帶你認識去Grid Alignment,Flexibox Box以及Multi-column Layout這三大領域。 |
新css屬性為我們提供了更加便捷的網頁布局方式。來自微軟的thomas lewis將帶你認識去Grid Alignment,Flexibox Box以及Multi-column Layout這三大領域。
這篇文章最早出現在 the April 2012 issue (226)這期的.net雜誌上-這雜誌是面向網頁設計者以及開發人員,全球銷量最高的雜誌。
按照以往來說,用CSS來布局看起來總是一樣非常繁雜的工作。然而,隨著一個個新標準的推出,網頁設計者已經能夠實現非常輕鬆地進行布局工作了。
主流的瀏覽器,在W3C的推動下,已經開始實現多種新型的布局方式,而且我們現在已經可以開始使用了。舉個例子,W3C開始把CSS3 Multicolumn Layout Module考慮進來。這就意味著W3C非常願意看到瀏覽器在將來能夠對上面的模組實現出來。
首碼(Vendor prefixes)
雖然一些瀏覽器對屬性普遍的認知,但這並不代表著你就不能採用這些屬性。在現在,我們可以通過添加首碼來獲得一些主流瀏覽器對屬性的支援,直到這些屬性得到了穩定的支援,我們才有可能不用添加這些首碼。Jonathan Snook說,添加供應商首碼就相當於做了兩件事情:
- 讓開發人員在調試新功能的時候,不用擔心轉換瀏覽器有不相容的情況。
- 可以告誡網頁開發人員這些東西是不穩定的。
存在某些爭議的首碼一文中人們在討論是否需要添加首碼的時候,這個做法確實為人們在標準完全確定之前提供了一個提前體驗這些屬性的機會,當然了,人們在這時候使用這些屬性都還需要小心翼翼的。下面我們會看到這些布局屬性各種瀏覽器的使用範圍,一般來說,你也許不需要這些瀏覽器都需要支援這些屬性,但還是很有必要對這些有個宏觀的瞭解。
多欄版面配置(Multi-column)
下面我來介紹第一個布局特徵,讓我們就從簡單的開始,css的Multi-column布局模組。(下面統稱Multi-column)你可能想得到,這個模組給予了我們脫離position和float這些屬性,就能在網頁欄目上布局的能力。
同樣,根據容器的大小,就可以控制建立欄目的數量,這是非常了不起的一個特點。舉個例子,如果你需要一個欄目寬度為13em(用ps作為長度單位也是可以的)的容器,並且根據這個容器的大小,建立數量適合的欄目數,上代碼!
#mcexample { column-width: 13ems; }
看到了沒,簡單吧!你還可以自己定義欄目的數量,在這個時候,這些欄目就會自動平均分配欄目寬度,盡量充滿容器的寬度。
#mcexample { column-count: 3; }
如果你想更具體地控制你的欄目,也行!舉個例子,下面的代碼,可以讓你控制欄目的數目,欄目的自身寬度,欄目與欄目之間的間隔等樣式。上代碼!
#mcexample{ columns: auto 13em;/* column-count,column-width*/ column-gap: 1em; column-rule: 1em solid black;/* width, style, color */ }
一些其他的屬性有如下功能:
- 定義欄目的最大限度
- 定義在多欄目中的間隔大小
- 在多個欄目中平均分配好顯示內容
Multi-column好就好在能夠自動為你安排好流體內容,你用不著計算確定欄目的數量,讓他們排排站好就行了!
然而,在使用Multi-column的時候,你還是有東西要注意下的,你要注意設定欄目的高度,否則別人在訪問網站的時候,就因為高高的欄目,看個欄目內容還要上拉下拉捲軸那麼費勁,這使用者體驗那該有多不好。
大部分的案頭瀏覽器和行動瀏覽器都支援Multicolumn(對於IE來說,你現在只能在IE10的平台上來預覽一下)。一個快速查詢一個屬性是否被瀏覽器支援的方法就是到caniuse.com尋找主流的案頭和行動瀏覽器是否都支援這些屬性。我們要記住的是,也許一個屬性是被支援的,但是也是添加瀏覽器供應商首碼,有些瀏覽器也不完全對屬性進行支援,總之,我們一定要多測試,這才能更好地解決問題,避免不必要的麻煩。
伸縮性布局(Flexbox)
Flexible Box 的css布局模組,在w3.org/TR/css3-flexbox中可以查得到。為了方便起見,下面這一模組統稱 Flexbox。
Flexbox 賦予了我們能夠對一個父級容器中子級元素進行水平以及垂直的定位,並且在這些子級元素的彼此之間都添加間距的能力。
舉個例子,在IE10中使用Flexbox,首先就要用到display屬性,上代碼!
#fbexample { display: -ms-flexbox; background: black; }
同樣,我們還可以設定子級元素排列的方向,不過我們需要在添加相應的的瀏覽器供應商的首碼(對於IE10來說,我們需要在開頭的地方添加-ms-flexbox
),上代碼!
#fbexample { display: -ms-flexbox; -ms-flex-direction: row; }
Flexbox讓我們能夠以多種方式排列子級元素:從左至右,從右至左,從上到下,從下到上。在這時候我們或許需要定義子級元素的排列座標軸方向。
下面的代碼同樣控制了每個子級元素都在父級容器中間顯示,同樣,對於每個子級元素來說上下的空間分配都是一樣的
#fbexample { display: -ms-flexbox; -ms-flex-direction: row; -ms-flex-align: center; }
我們還可以用另一個屬性flex-pack
,這個屬性控制子級元素如何分配剩餘的空間。舉個例子來說,首先我們要使得子級元素按照一定的方向在父級元素中排列:
#fbexample { display: -ms-flexbox; -ms-flex-direction: row; -ms-flex-align: center; -ms-flex-pack: start; }
但是我們如果有過多的子級元素,而且我們不希望他們的尺寸被壓縮到一個不是我們想要的情況的時候該怎麼辦呢?好吧,在這個時候我們採用flex-wrap
把子級元素擦除之後,仍然可以讓瀏覽器繼續正常顯示:
#fbexample { display: -ms-flexbox; -ms-flex-direction: row; -ms-flex-align: center; -ms-flex-pack: start; -ms-flex-wrap: wrap; }
現在我們知道怎麼建立起容器了,那該怎麼控制好我們的子級元素呢?首先我們要在html把這些元素設定成Flexbox元素的子級元素,代碼如下:
<style> #fbexample { display: -ms-flexbox; } #fbchild1 { background: blue; } #fbchild2 { background: green; } #fbchild3 { background: red; } </style> :: <div id="fbexample"> <div id="fbchild1">1</div> <div id="fbchild2">2</div> <div id="fbchild3">3</div> </div>
為了驗證子級元素的自適應性。我們可以把flex
的屬性值設定為0,這代表著沒有了自適應性,或者設定數值為1或2,代表著子級元素將要佔據多少份額的空間.
圖解說明:當Flexbox被運用到元素當中,很容易就對子級元素進行豐富多樣的布局,在這裡我們看得到的是一個水平布局和包圍起來的布局。
舉個例子來說,我們有三個子級元素,第一個子級元素的數值設定為0,第二個子級元素的數值設定為1,第三個子級元素的數值設定為2。第一個子級元素將會保留原來的尺寸大小,也就是說他沒有自適應性,第二個子級元素將會和第三個子級元素共同分享多出來的空間,第二個子級元素佔據其中的3分之1長度,而第三個子級元素就佔據其中的3分之2長度。其中最值得稱道的就是,在這個過程當中瀏覽器將會自動為你計算當中的長度,媽媽再也不用擔心我的計算了!
#fbchild1 { background: blue; } #fbchild2 { background: green; -ms-flex: 1; } #fbchild3 { background: red; -ms-flex: 2; }
在此時此刻,敏銳的你一定會發現,最新準則上面的一些屬性不一定看起來完全正確,現在的Flexbox僅僅就是W3C所考慮的一個工作草圖,這隻是早期的一個標準。作為一個在發展的項目,經常變化是很正常的一件事情,下面,我們來看下最近準則的推出時間:
- November 29, 2011
- March 22, 2011
- July 23, 2009
如果你在 caniuse.com中尋找Flexible Box布局模組,你將會看到使用的Flexbox屬性前面都會出現供應商的首碼。一些供應商依據的是2009年的準則(可以參考上面的例子)而不是最新的2011年9月的那個。這就是為什麼我們不僅僅要參考準則上是否支援,還要在實踐當中理解這些屬性是否真的支援。
然而讓人欣慰的是,我們不用擔心在面對更新準則帶來的轉變難以適應,舉個例子,就像現在這樣子,說明一個元素是Flexbox就可以了,翠花,上代碼!
#fbexample { display: -ms-flexbox; }
講多一句,由於這仍然是一個工作草圖,所以這個準則還在變化當中,要記得添加的完整供應商首碼,省得一個個測試。
Flexbox中示範的範例程式碼,在原文的基礎上做了修改。因為在ie10下使用的是flexbox,以及對應的子屬性也做相應的調整。詳細請參閱Flexbox系列教程。
——大漠
Grid Layout
按照以往來說,在對標準革新的支援方面,IE是公認的最遲鈍的瀏覽器。但是在最新的版本更迭當中,IE一改以往反應慢的頹勢,來了個華麗麗的逆襲。舉個例子,在最新的IE10的平台當中,支援基於CSS 的網格布局。相關說明你可以在 w3.org/TR/css3-grid-layout 中,而且該說明由微軟在最近的四月份向W3C組織提交,截至到目前為止,IE10是唯一對該網格布局進行支援的瀏覽器。
圖例說明:在網格系統當中,我們不再糾結定位(position)與浮動(float)的問題,而是以更加簡單快捷的方式來設定rows和columns的方式進行表格版面配置。
網格布局是在網頁設計之前就要考慮的基礎,所以說,瀏覽器對它的普遍支援僅僅是一個時間上的問題罷了。而它正是最有希望成為html中的table元素的終結者!這個標準將會能夠讓我們使用rows和columns對頁面進行布局而且在我們保持布局與內容相互獨立的時候可以讓內容跨越單位行來顯示。首先, 我們在開始網格布局之前還是得添加供應商首碼,上代碼:
#gridexample { display: -ms-grid; }
我們可以設定columns(列)和rows(行)的大小規格:
#gridexample { display: -ms-grid; -ms-grid-rows: 30px 5em auto; -ms-grid-columns: auto 70px 2fr 1fr; }
什嗎?那麼多的屬性值讓你很頭暈?好吧,我們來慢慢分析,一個一個地瞭解真相吧。上面的代碼會向我們呈現四行三列的網格。
- 第一行的高度將會是30px。
- 第二行的高度將會是5em。
- 第三行的高度根據剩下的空間大小自動調整
- 第一列的寬度根據剩下的空間大小自動調整
- 第二列的寬度是70px
- 第三列的寬度將會是剩餘寬度的三分之二
- 第四列的寬度講會是剩餘寬度的三分之一
現在我們也可以在我們的網格中為子級定製特別的位置。如果我們希望我們的子級元素位於第一行,第二列,我們就可以這麼幹,上代碼:
#griditem1 { -ms-grid-row: 1; -ms-grid-column: 2; }
記住,這個跟Flexbox差不多,我們的子級元素需要被定義為網格元素的子級。還有,我們如果希望元素跨行顯示,那麼我們就可以使用grid-row-span,上代碼!
#griditem1 { -ms-grid-row: 1; -ms-grid-column: 2; -ms-grid-row-span: 2; }
而且我們還可以通過使用grid-row-align和grid-colum-align來排列元素。這些屬效能夠是你定義內容在行列當中置中顯示,你還可以在水平或者垂直對其排列元素。舉個例子吧,如果要使元素在欄目中置中顯示,我們可以這樣幹:
#griditem1 { -ms-grid-row: 1; -ms-grid-column: 2; -ms-grid-column-align: center; }
在過去的日子當中,HTML的基於table的布局總會帶來不少的麻煩,那是因為這些元素只會獨來獨往,這都導致了在面對不同顯示裝置時候所產生的不穩定因素。但是在網格布局中,我們可以通過使用一些像Media Queries通過依據我們的裝置寬度,高度,等等參數來為我們提供多種樣式。
圖解:Griddle是一款來自微軟的應用程式,這是一個運用了Multi-column,Flexbox和Grid Layout等技術與Dribble相聯絡的app。
總結
如果你更多地追求視覺上的享受,我建議你看看 Markus Mielke’s presentation,在這裡討論了這篇文章提及或者沒有提及的布局特點,而且討論了他們是怎麼同樣運用在app上的。
在這篇文章當中,我們提及的布局特徵都是被所有瀏覽器普遍支援的,而且一些僅僅剛剛成型。這些可能會讓人感覺實用性不強,這種感覺或許在某一方面是對的,但是呢,作為設計師我們應該對這些東西都統統接受理解,我們要面對css的一切東西,而且那些天天被我們使用的css屬性,不都是這樣一步步發展過來的嗎?