淺談 CSS3 Flexible Box Layout

希望有機會成為「淺談 CSS3」系列文章。

要在 HTML 中做排版(layout)一直是前端工程中的一件苦差事,最初人們都是使用

元素作為排版的輔助工具,甚至許多 WYSIWYG 編輯器、GWT 等工具也都是這麼做,可是利用這種方式作排版,除了彈性不高之外,也容易堆疊出過份冗長的 HTML 碼,後來前端工程師、設計師們開始瞭解可以利用 CSS 中的 float, inline-block 等屬性來完成排版的需要。然而,伴隨而來的卻是更不直覺的程式碼,而且還要處理更多對齊、水平垂直置中的問題。

CSS3 中的 Flexible Box Layout module 試著制定出更有彈性、更簡單的 layout 方法。直接以一個例子來看,很多網站會做出像這樣的三欄式版面:

當然,就算不使用任何 CSS3 的功能也可以做出像這樣的版面,只是你可能會絞盡腦汁去想到底要怎麼完美搭配 floatposition:absolutemarginclear 以及

的排列來達到你的效果。但要是我用 CSS3 來做這樣的版面,code 大概會像是這樣(以 WebKit 系的瀏覽器作示範):

[HTML部份]

...
...
...

[CSS 部份]


#container {
...
display: -webkit-box;
-webkit-box-align: stretch;
-webkit-box-orient: horizontal;
}
#mid {
-webkit-box-flex: 1;
}
.sidebar {
...
width: 180px;
}

如此一來便能輕鬆、直覺地做出三欄式的版面,可以到這裡看一下顯示的效果(記得用 Safari/Chrome 這類 WebKit 系的瀏覽器開啟)。

簡單地解釋一下這個例子,我們在 #container 中設定了 -webkit-box-orient 的屬性,瀏覽器便會依照設定的值來排版 #container 的子元素(也就是 #left, #mid#right),在此例中由於 #left, #mid#right 是以水平方式排列,所以將值設定為 horizontal;而 -webkit-box-align 的屬性則是指定子元素在排列時如何對齊母元素,可以設定 start|end|center|baseline|stretch 等值,這裡設定成 stretch 是為了讓子元素的高度變成與母元素相同(因為 box-orienthorinzontal,所以 stretch 會往垂直的方向延伸)。

(思考一下:所以水平、垂直置中就簡單多了吧~)

至於左右兩個 sidebar 沒就沒什麼特別,只是單純地用 width: 180px 來指定大小而已,有趣的是 #mid-webkit-box-flex 屬性,它可以設定該元素在剩餘空間中的佔有比例,預設為0.0(可用浮點數)。在這個例子中,#left#right 都已經設定了 width: 180px,那若是 #mid 設定了 -webkit-box-flex: 1,則表示 #mid 會佔有 #container 剩餘的空間。如果你覺得這樣的說明很難懂,那下面有個簡單的例子:

[HTML]

Left
Right

[CSS]


#container 與上述同
#left { -webkit-box-flex: 1 }
#right { -webkit-box-flex: 1}

這樣一來,#left#right 會在 #container 下佔有 1 : 1 的比例,也就是說這兩個元素會平分 #container 的空間。若是將 CSS 的部份改為:

[CSS]


#left { -webkit-box-flex: 1 }
#right { -webkit-box-flex: 2}

那佔有比例就會成為 1:2#left 佔有 1/3 的空間,而 #right 則佔有 2/3-webkit-box-flex 的值預設為 0.0,所以若是該 box 沒有指定大小的話,則會依照內容的大小動態決定。

當然,CSS3 的 Flexible Box 還有其它調整排版的屬性及效果,如果有興趣的話則可以參考 W3C 的規格書草案:[Ref] CSS3: Flexible Box Layout Module。瞭解之後,你是不是能夠利用這個模組隨心所欲地做出你想要的排版呢?