隨著對分離HTML元素的語義重要性與其表現的影響的不斷強調,CSS在HTML5元素佈局方面的作用越來越重要。 1. 定位內容 控制內容最簡單的方式就是通過定位,這允許你使用瀏覽器改變元素的佈局方式。 1.1 設置定位類型 position 屬性設置了元素的定位方法。 position 屬性的不同值指 ...
隨著對分離HTML元素的語義重要性與其表現的影響的不斷強調,CSS在HTML5元素佈局方面的作用越來越重要。
1. 定位內容
控制內容最簡單的方式就是通過定位,這允許你使用瀏覽器改變元素的佈局方式。
1.1 設置定位類型
position 屬性設置了元素的定位方法。
position 屬性的不同值指定了元素定位所針對的不同元素。使用 top、bottom、left 和 right 屬性設置元素的偏移量的時候,指的是相對與 position 屬性指定的元素的偏移量。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> img {top: 15px; left: 150px; border: medium double black; width: 150px;} </style> </head> <body> <p> There are lots of different kinds of fruit - there are over 500 varieties of banana alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. </p> <p> One of the most interesting aspects of fruit is the variety available in each country. I live near London, in an area which is know for its apples. </p> <img src="imgs/banana.png" id="banana" alt="small banana" /> <p> When travelling Asia, I was struck by how many different kinds of banana were available - many of which had unique flavours and which were only available within a small region. </p> <p> <button>Static</button> <button>Relative</button> <button>Absolute</button> <button>Fixed</button> </p> <script> var buttons = document.getElementsByTagName("button"); for( var i = 0; i < buttons.length; i++){ buttons[i].onclick = function(e){ document.getElementById("banana").style.position = e.target.innerHTML; } } </script> </body> </html>
在上面的代碼中,為頁面添加了一個小腳本,它可以基於被按下的按鈕改變img元素的position屬性的值。這裡將left屬性設置為150px,將top屬性設置為5px,意思是只要position值不設為static,img元素就將沿水平軸偏移150像素,沿垂直軸偏移15像素。下圖展示了 position 值從static到relative的變化。
relative值為元素應用top、bottom、left和 right屬性,相對於 static 值確定的位置重新定位元素。從圖中可以看到,left屬性和top屬性的取值引起img元素向右、向下移動。
absolute值根據position值不是static的最近祖先元素的位置來定位元素。在這個示例中不存在這樣的元素,也就是說元素是相對於body元素定位的,如下圖所示:
註意一下,如果滾動瀏覽器頁面,img元素會跟剩餘的內容一起移動。可以將這個情況跟fixed值比較一下,如下圖就是fixed值定位效果:
使用fixed值,元素是相對於瀏覽器視窗定位的。也就是說元素始終占據同樣的位置,無論剩餘內容是否向上向下滾動。
1.2 設置元素的層疊順序
z-index 屬性指定元素顯示的層疊順序。
z-index 屬性的值是數值,且允許取負值。值越小,在層疊順序中就越靠後。這個屬性只有在元素重疊的情況下才會派上用場。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> img {border: medium double black; background-color: lightgray; position: fixed;} #banana { z-index: 1; top: 15px; left: 150px; } #apple { z-index: 2; top: 25px; left: 120px; } </style> </head> <body> <p> There are lots of different kinds of fruit - there are over 500 varieties of banana alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. </p> <p> One of the most interesting aspects of fruit is the variety available in each country. I live near London, in an area which is know for its apples. </p> <img src="imgs/banana-small.png" id="banana" alt="small banana" /> <img src="imgs/apple.png" id="apple" alt="small apple" /> <p> When travelling Asia, I was struck by how many different kinds of banana were available - many of which had unique flavours and which were only available within a small region. </p> </body> </html>
此例中,創建了兩個固位置的img元素,設置了它們top 和left 值使兩者部分圖像重疊。id值為apple的img元素的z-index值比id值為banana元素的z-index值要大,因此蘋果圖像顯示在香蕉圖像上面。
z-index 屬性的預設值是0,因此瀏覽器預設將圖像顯示在p元素上。
2. 創建多列佈局
多列特性允許在多個垂直列中佈局內容,跟報紙的排版方式類似。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> div { column-count: 3; column-fill: balance; column-rule: medium solid black; column-gap: 1.5em; } img { float: left; border: medium double black; background-color: lightgray; padding: 2px; margin: 2px; } </style> </head> <body> <div> There are lots of different kinds of fruit - there are over 500 varieties of banana alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. <img src="imgs/banana-small.png" id="banana" alt="small banana" /> One of the most interesting aspects of fruit is the variety available in each country. I live near London, in an area which is know for its apples. <img src="imgs/apple.png" id="apple" alt="small apple" /> When travelling Asia, I was struck by how many different kinds of banana were available - many of which had unique flavours and which were only available within a small region. And, of course, there are fruits which are unique - I am put in mind of the durian, which is widely consumed in SE Asia and is know as the "king of fruits". The durian is largely unknow in Europe and the USA - if it is know at all, it is for the overwhelming smell, which is compared to a combination of almonds, rotten onions and gym socks. </div> </body> </html>
PS:暫發現IE、Edge、Opera瀏覽器顯示有效,火狐和谷歌不支持。
從上圖可以看出,div元素中的內容從一列流向另一列,跟報紙中排版很像。在這個例子中,為img元素應用了float屬性,這樣div元素中的文本內容就可以流暢地環繞在圖像周圍。
上面的示例中使用了column-count屬性將頁面佈局分為三列。如果視窗大小調整,瀏覽器會自行調整寬度,從而保留佈局中的列數。另一種方法是指定列寬度。
<style type="text/css"> p { column-width: 10em; column-fill: balance; column-rule: medium solid black; column-gap: 1.5em; } img { float: left; border: medium double black; background-color: lightgray; padding: 2px; margin: 2px; } </style>
如果應用column-width 屬性,瀏覽器會通過添加或者刪除列數維持指定寬度。
3. 創建彈性盒佈局
彈性盒佈局(也稱伸縮盒)在CSS3中得到了進一步加強,為display屬性添加了一個新值(flexbox),並定義了其他幾個屬性。使用彈性佈局可以創建對瀏覽器視窗調整響應良好的流動頁面。這是通過在包含元素之間分配容器塊中未使用的空間來實現的。規範為彈性佈局定義瞭如下新屬性:
* flex-align
* flex-direction
* flex-order
* flex-pack
不過建議規範和實現之間還有差異,頂定義一下彈性盒要解決的問題。下麵代碼展示了一個有問題的簡單佈局。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> p { float: left; width: 150px; border: medium double green; } </style> </head> <body> <div> <p id="first"> There are lots of different kinds of fruit - there are over 500 varieties of banana alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. </p> <p id="second"> One of the most interesting aspects of fruit is the variety available in each country. I live near London, in an area which is know for its apples. </p> <p id="third"> When travelling Asia, I was struck by how many different kinds of banana were available - many of which had unique flavours and which were only available within a small region. </p> </div> </body> </html>
在上面代碼中,div元素包含了三個p元素。將p元素顯示在水平行中,用float屬性很容易就能做到這一點。
這裡能使用彈性盒解決的問題是處理頁面上p元素右邊的空間塊。解決這個問題有很多方式。在這個例子中,可以使用百分比寬度,但彈性盒解決方案更優雅,頁面看起來流動性也會好很多。下表列出了實現彈性盒核心功能的三個 -webkit 屬性(簡單起見,表中省略了-webkit首碼):
3.1 創建簡單的彈性盒
可以使用 display屬性創建彈性盒。標準值是 flexbox, 不過在標準完成和實現之前,必須使用 -webkit-box 。 使用 box-flex 屬性告訴瀏覽器如何分配元素之間的未使用空間。 display 屬性的新值和 box-flex 屬性如下麵代碼所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> p { width: 150px; border: medium double green; background-color: lightgray; margin: 2px; } #container{ display: -webkit-box;} #second {-webkit-box-flex: 1;} </style> </head> <body> <div id="container"> <p id="first"> There are lots of different kinds of fruit - there are over 500 varieties of banana alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. </p> <p id="second"> One of the most interesting aspects of fruit is the variety available in each country. I live near London, in an area which is know for its apples. </p> <p id="third"> When travelling Asia, I was struck by how many different kinds of banana were available - many of which had unique flavours and which were only available within a small region. </p> </div> </body> </html>
display 屬性會應用到彈性盒容器。彈性盒容器是具有多餘空間,且想對其中的內容應用彈性佈局的元素。box-flex 屬性會應用到彈性盒容器內的元素,告訴瀏覽器當容器大小改變時哪些元素的尺寸是彈性的。在這個例子中,選擇了id值為second的p元素。
PS:從p元素樣式聲明中刪除了float屬性。可伸縮元素不能包含浮動元素。
可以從下圖看出瀏覽器如何伸縮選擇元素的尺寸:
3.2 伸縮多個元素
應用box-flex 告訴瀏覽器伸縮多個元素的尺寸。設置的值決定了瀏覽器分配空間的比例。修改前面例子的CCS文件如下:
<style type="text/css"> p { width: 150px; border: medium double green; background-color: lightgray; margin: 2px; } #container{ display: -webkit-box;} #first { -webkit-box-flex: 3;} #second {-webkit-box-flex: 1;} </style>
這裡將box-flex 屬性應用到了id值為first的p元素。此處box-flex屬性的值是3,意思是瀏覽器為其分部的多餘空間是為id值為second的p元素的三倍。當創建此類比例時,指的是元素的可伸縮性。只是使用這個比例來分配多餘的空間,或者減少元素的尺寸,而不是改變它的首選尺寸。從下圖可以看到這個比例時怎麼應用到元素的。
3.3 處理垂直空間
box-align 屬性告訴瀏覽器如何處理多餘的垂直空間。預設情況下垂直拉伸元素以填充多餘的空間。上面的例子就是這種情況,前兩個p元素的尺寸是調整過的,內容下麵多出了空的空間。
下麵的代碼展示了元素樣式變為應用box-align屬性。註意這個屬性應用到可伸縮容器上,而不是內容元素。
p { width: 150px; border: medium double green; background-color: lightgray; margin: 2px; } #container{ display: -webkit-box; -webkit-box-direction: reverse; -webkit-box-align: end; } #first { -webkit-box-flex: 3;} #second {-webkit-box-flex: 1;}
此例中,使用了 end 值,這代表內容元素會沿著容器元素的底邊放置,垂直方向任何多餘的空間都會顯示到內容元素上方。其呈現效果如下圖所示:
3.4 處理最大尺寸
彈性盒伸縮時不會超過內容元素的最大尺寸。如果存在多餘空間,瀏覽器會伸展元素,知道達到最大允許尺寸。box-pack屬性定義了在所有的可伸縮元素均可達到最大尺寸的情況下,多餘空間仍未分配完畢時應該如何處理。
修改前面示例的CSS文件如下:
p { width: 150px; max-width: 250px; border: medium double green; background-color: lightgray; margin: 2px; } #container{ display: -webkit-box; -webkit-box-direction: reverse; -webkit-box-align: end; -webkit-box-pack: justify; } #first { -webkit-box-flex: 3;} #second {-webkit-box-flex: 1;}
這屬性的效果如下圖所示。在可伸縮p元素達到最大寬度後,瀏覽器開始在元素之間分配多餘空間。註意,多餘空間只是分配到元素與元素之間,第一個元素之前或者最後一個元素之後都沒有分配。
4. 創建表格佈局
使用 table 元素如此普遍的原因是它解決了一種常見的佈局問題:創建承載內容的簡單網格。幸好,我們可以使用CCS表格佈局特性來設置頁面佈局,這很像使用 table 元素,但不會破壞語義重要性。創建CSS表格佈局使用display屬性。下表列出了跟這個特性相關的值。表中的每個值都與一個HTML元素對應。
其中幾個值的用法如下麵代碼所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> #table { display: table;} div.row {display: table-row; background-color:lightgray; } p { display: table-cell; border: thin solid green; padding: 15px; margin: 15px;} img { float: left;} </style> </head> <body> <div id="table"> <div class="row"> <p id="first"> There are lots of different kinds of fruit - there are over 500 varieties of banana alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. </p> <p id="second"> One of the most interesting aspects of fruit is the variety available in each country. I live near London, in an area which is know for its apples. </p> <p id="third"> When travelling Asia, I was struck by how many different kinds of banana were available - many of which had unique flavours and which were only available within a small region. </p> </div> <div class="row"> <p> This is an apple. <img src="imgs/apple.png" alt="apple" /> </p> <p> This is a banana. <img src="imgs/banana-small.png" alt="banana" /> </p> <p> No picture here. </p> </div> </div> </body> </html>
這些取值的效果如下圖所示:
CSS表格佈局的一個優點是自動調整單元格大小,因此,行是由該行中內容最高的單元格決定的,列是由該列中內容最寬的單元格決定的,這從上圖也能看出來。