CSS3 標准裡引入了一些新的盒子模型參數,在 CSS2 的基礎上,我們將能更靈活地調整頁面上各個容器的大小和位置。詳細的說明可以看這個文檔。
通過學習和測試,我發現這種新的盒子模型布局對建立自適應布局的頁面帶來很大的好處。在這篇文章中,我的所有例子都基於以下 HTML代碼:
以下為引用的內容:
<body> <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> </body>
容器的排列
在通常的情況下,頁面上所有容器的順序都按照載入的順序排列。而使用 CSS3 提供的功能後,我們可以在不改變 HTML 結構的前提下隨意改變容器顯示的位置,這樣不但給排版帶來極大的方便,我們也可以利用這些功能進行流量整形。
在需用使用靈活盒子模型(Flexible Box Module)的時候,我們需要先把其父容器的 Display 屬性設置為 box 或者 inline-box 。
水平分布和垂直分布
我們可以通過 box-orient 屬性指定容器的分布軸,當這個屬性的值為 vertical 時其子容器將垂直分布(也可以為 block-axis ),當值為 horizontal 時其子容器講水平分布(也可以為 inline-axis )。在本文的第一個例子裡我使用了以下的 CSS :
以下為引用的內容:
#exemple1 .content{ -moz-box-orient : horizontal; -webkit-box-orient : horizontal; box-orient : horizontal; } #exemple1 .boite{ -moz-box-flex : 1; -webkit-box-flex : 1; box-flex : 1; }
具體的效果可以看這個 DEMO ,三個子 Div 容器都橫向並列了。
注:這個效果在 CSS2 裡理論上也可以通過 Display: inline; 實現,但由於某些浏覽器的 BUG ,沒人會這樣做。
反序排列
box-direction 屬性可以讓我們隨意改變容器的顯示順序。我們知道,在默認的情況下,block 級元素是按照加載順序從上到下排列, inline 級元素是從左到右排列的,但現在通過 box-direction 屬性我們可以讓最後加載的 block 級元素顯示在最頂部,最後加載的 inline 級元素顯示在左邊。
但在使用這個屬性的時候要注意它可能會改變元素的某些屬性,產生一些不能控制的效果。
在第二個例子裡,我使用了以下的 CSS :
以下為引用的內容:
#exemple2 .content{ -moz-box-orient : vertical; -moz-box-direction : reverse; -webkit-box-orient : vertical; -webkit-box-direction : reverse; box-orient : vertical; box-direction : reverse; } #exemple2 .boite{ -moz-box-flex : 1; -webkit-box-flex : 1; box-flex : 1; }
效果大家可以看這個 DEMO。可以發現,在不改變 HTML 結構的情況下,容器的排列順序改變了。
按指定順序排列
我們不但可以讓一組同級容器反序排列,而且還可以讓它們按自己喜歡的順序排列,box-ordinal-group 屬性可以幫我們做到這一點。通過 box-ordinal-group 為各個容器指定一個序號,默認情況下他們將會按照序號遞增的順序排列。要注意的是:沒有指定序號的容器默認都為 1 ,並且序號相同的元素將按照加載順序排列。大家可以看一下下面的 CSS :
以下為引用的內容:
#exemple3 .content{ -moz-box-orient : vertical; -moz-box-direction : reverse; -webkit-box-orient : vertical; -webkit-box-direction : reverse; box-orient : vertical; box-direction : reverse; } #exemple3 .boite{ -moz-box-flex : 1; -webkit-box-flex : 1; box-flex : 1; } #exemple3 .v1{ -moz-box-ordinal-group : 2; -webkit-box-ordinal-group : 2; box-ordinal-group : 2; } #exemple3 .v2{ -moz-box-ordinal-group : 2; -webkit-box-ordinal-group : 2; box-ordinal-group : 2; } #exemple3 .v3{ -moz-box-ordinal-group : 1; -webkit-box-ordinal-group : 1; box-ordinal-group : 1; }
在上面的 CSS 裡,我把第一和第二個容器的序號都定為 2 ,第三個容器序號為 1 ,因此最終效果應該是 v3 排在第一,v1 和 v2 則根據加載順序,v1 排在 v2 前面。效果可以看這個 DEMO。
後記
CSS3 真的非常強大,我相信在它普及以後,我們做網頁的時候將可以減少大量的 JavaScript 。關於 CSS3 盒子模型的介紹還沒完,這篇文章只介紹了一下容器的排序,下一次將說說容器的尺寸。歡迎訂閱本博客,以即時獲知最新的更新。
說說 CSS3 裡盒子模型的尺寸。本文的 HTML 框架繼續沿用《CSS3 靈活的盒子模型(Flexible Box Module) – 1》。
在 CSS2 裡,要把一個容器分成三欄的話比較簡便的方法是把三個字容器的 width 都設為 33.3%,這種方法無法把父容器的寬度完全填充,在父容器的寬度足夠大的時候留下的空白會是頁面變得很不美觀。令一種方法是通過計算把子容器的 width 都設為一個固定值,這種方法比較繁瑣,而且在一些情況下無法使子容器的寬度完全相等(例如父容器的寬度為 100px)。當我們邁入 CSS3 時代後,這種問題將迎刃而解。
box-flex 屬性
box-flex 應用在需要分欄的子容器上,它的值必須是一個自然數或小數。當父容器裡有多個帶有 box-flex 屬性的子容器時,浏覽器將會把這些子容器的 box-flex 的值相加,然後根據它們各自的值占總值的比例,再在父容器剩余的空間裡分配它們的尺寸(說的啰嗦,其實一看 DEMO 就懂)。也就是說,我們需要注意 box-flex 屬性必須在父框架具有具體的 width 或者 height 的時候才能正常渲染。
靈活的尺寸
在這個例子裡,我將使子容器2和3的寬度相等,並且子容器1的寬度為它們的兩倍。由於使用了 box-flex 屬性,如果再插入一個子容器的話,已有的容器寬度將會自動調整。CSS 如下:
以下為引用的內容:
#exemple4 .content{ -moz-box-orient : horizontal; -webkit-box-orient : horizontal; box-orient : horizontal; } #exemple4 .v1{ -moz-box-flex: 2; -webkit-box-flex: 2; box-flex: 2; } #exemple4 .v2{ -moz-box-flex: 1; -webkit-box-flex: 1; box-flex: 1; } #exemple4 .v3{ -moz-box-flex: 1; -webkit-box-flex: 1; box-flex: 1; }
效果可以看這個 DEMO。大家也可以下載這個 DEMO,嘗試添加一個新的子容器,它是不是自動適應了。
自適應子容器和固定尺寸子容器的混合使用
box-flex 的另一個強大之處是可以和具有固定尺寸的容器混合使用。我把上面的例子改一改,子容器3改成固定寬度160px,其它的保持不變,看看有什麼效果。
以下為引用的內容:
#exemple5 .content{ -moz-box-orient: horizontal; -webkit-box-orient: horizontal; box-orient: horizontal; } #exemple5 .v1{ -moz-box-flex: 2; -webkit-box-flex: 2; box-flex: 2; } #exemple5 .v2{ -moz-box-flex: 1; -webkit-box-flex: 1; box-flex: 1; } #exemple5 .v3{ width: 160px; }
大家可以看這個 DEMO 的效果。我們可以發現,子容器1和子容器2的寬度是在父容器寬度減去子容器3的寬度以後剩下的空間裡分配的,這點和使用百分比作為 width 時直接根據父容器的寬度進行計算有很大的不同,使用 box-flex 能使子容器自動適應尺寸的變化,節省了很多調試時間。
空間的分配
因為我們可以把具有固定尺寸和靈活尺寸的子容器混合使用,並且也可以給父容器賦予靈活的尺寸。因此在最終的成品裡我們可能會遇到父容器空間過余或者不足的情況。為了更合理地利用父容器提供的空間,box-align 和 box-pack 屬性可以幫助我們。
box-pack 屬性
box-pack 屬性可以用於設置子容器在水平軸上的空間分配方式,它共有四種可能值:start,end,justify 和 center。這些值的含義如下:
start :所有子容器都分布在父容器的左側,右側留空
end :所有子容器都分布在父容器的右側,左側留空
justify :所有子容器平均分布(默認值)
center :平均分配父容器剩余的空間(能壓縮子容器的大小,並且有全局居中的效果)
box-align 屬性
box-align 屬性用於管理子容器在豎軸上的空間分配方式,共有五個值:start,end,center,baseline 和 stretch。
start :子容器從父容器頂部開始排列
end :子容器從父容器底部開始排列
center :子容器橫向居中(有點奇怪)
baseline :所有子容器沿同一基線排列(很難理解)
stretch :所有子容器和父容器保持同一高度(默認值)
box-align 和 box-pack 屬性通常混合使用,我們可以用下面的 CSS 測試一下:
以下為引用的內容:
#exemple6 .content{ -moz-box-orient: horizontal; -moz-box-pack: center; -moz-box-align: center; -webkit-box-orient: horizontal; -webkit-box-pack: center; -webkit-box-align: center; box-orient: horizontal; box-pack: center; box-align: center; }
在線的 DEMO,大家可以 Firebug 禁用 box-align 和 box-pack 屬性看看它們的區別和效果。
防止子容器溢出
CSS3 並沒有更好地解決內容溢出的問題,反而在加入和新的盒子模型參數後,溢出的情況變得更加頻繁。因此最好的方法還是多做試驗,更好地管理你的內容。overflow: hidden 正能臨時起點作用而已。