純 CSS 打造多列等高並不像想象中那麼容易。本文著重講述多列布局出現的問題,之後提供一個在所有浏覽器都正常工作的簡單解決方案。這個方法 100% 無 CSS hack,無圖片,無 Javascript,甚至可以用在最嚴格編碼的網站上。
多列等高的問題
上例中有包含不同內容的 3 列,可以看出存在的問題是列的背景色隨著其包含內容的高度而自適應展開。這是我們要解決的問題。如何使所有的列等高?或具體的說,如何使所有列的高度等於最高列的高度?這很棘手,因為我們不清楚每列將會多高,哪一列是最高的。不能簡單的給所有列一個固定的高度,如果內容很少將會導致頁面底部有大片空白;如果內容太多則會在文字顯示完全前關閉。兩種情形都不妥。實際上,內容的長度是動態的,所以每列的高度也是動態的。必須意識到 Web 上沒有固定的東東,鄉民們有不同的屏幕分辨率,浏覽器中的文字也可能被設置為任意大小,所有這些都會影響內容的高度。
分離列內容與其背景色
解決等高問題的第一步是把能分離的破開。方法是每列用兩個 div 替代原來的一個。第一個 div 用來放內容,另一個用來作背景色。分離使我們可以單獨控制這些額外的元素,之後用更有效的方法把它們放在一起。答案呼之欲出。
浮動的容器的高度始終取決於其浮動的內容(高度)
這是本文多列等高方法的核心。 使一個 div 的高度等於最高列高度的唯一方法是這個 div 包含所有的列。換句話說,通過把所有的列放在一個容器中,容器的高度就是最高列的高度。這是個非常有用的結構。
3列 Html div 結構
上例中 3 個內容列在一個 div 容器中。
<div id="container1">
<div id="col1">Column 1</div>
<div id="col2">Column 2</div>
<div id="col3">Column 3</div>
</div>
3 列 CSS
下面是使 div 容器等高於最高列的 CSS。
#container1 {
float:left;
width:100%;
}
#col1 {
float:left;
width:30%;
background:red;
}
#col2 {
float:left;
width:40%;
background:yellow;
}
#col3 {
float:left;
width:30%;
background:green;
}
為了讓這一結構在所有浏覽器中正確工作,容器 div 必須浮動(左或右),同時每一個內容列的 div 也要浮動,哪種方式並不重要。浮動內容 div 的進程使它們在頁面中排列在一條水平線上。浮動容器使其自適應到最高列的高度。如果不浮動容器,內容 div 將會從容器底部溢出,容器不會擁有正確的高度。事實上在此例中,容器不浮動的話其最終高度為0。
增加額外嵌套的容器
下一步是增加額外的容器,它們彼此嵌套。我們需要容器的數量等於列的數量:3。這 3 個容器用作各列的背景。請注意,我們去除了原始列的背景色,並將其加至容器上。
3列 Html div 結構
兩個額外的容器加至下面的 Html 中。
<div id="container3">
<div id="container2">
<div id="container1">
<div id="col1">Column 1</div>
<div id="col2">Column 2</div>
<div id="col3">Column 3</div>
</div>
</div>
</div>
3 列 CSS
所有元素左浮動,容器寬度設為100%,使他們占滿頁面的寬度。背景色從內容 div 移除並加至容器上。
#container3 {
float:left;
width:100%;
background:green;
}
#container2 {
float:left;
width:100%;
background:yellow;
}
#container1 {
float:left;
width:100%;
background:red;
}
#col1 {
float:left;
width:30%;
}
#col2 {
float:left;
width:40%;
}
#col3 {
float:left;
width:30%;
}
用相對定位移動容器
現在用相對定位把容器移至新的位置。移動後 div 如下圖所示。即等高列背景容器的層疊和位置。為了顯示右側的綠色列 container2 向左移了30%,為了顯示中間的黃色列 container1 向左移動了40%,與此同時紅色部分依然可見作為左側列。
相對定位的 CSS
下面是添加了相對定位的CSS。
#container3 {
float:left;
width:100%;
background:green;
}
#container2 {
float:left;
width:100%;
background:yellow;
position:relative;
right:30%;
}
#container1 {
float:left;
width:100%;
background:red;
position:relative;
right:40%;
}
#col1 {
float:left;
width:30%;
}
#col2 {
float:left;
width:40%;
}
#col3 {
float:left;
width:30%;
}
將每列的內容移回
下一步是把每列的內容移回到頁面上,使之排列在下面的背景色上。再次使用簡單的相對定位來完成它。
最後在最外面的容器 container3 上添加overflow:hidden
,砍去超出容器的部分。
相對定位的 CSS
下面是增加了相對定位和溢出的 CSS 規則。請注意 container3 上額外的position:relative
; 這是為了解決一個 IE bug ,阻止overflow:hidden;
工作。
#container3 {
float:left;
width:100%;
background:green;
overflow:hidden;
position:relative;
}
#container2 {
float:left;
width:100%;
background:yellow;
position:relative;
right:30%;
}
#container1 {
float:left;
width:100%;
background:red;
position:relative;
right:40%;
}
#col1 {
float:left;
width:30%;
position:relative;
left:70%;
}
#col2 {
float:left;
width:40%;
position:relative;
left:70%;
}
#col3 {
float:left;
width:30%;
position:relative;
left:70%;
}
對列增加 padding
最後還需對列增加 padding,這樣每列邊緣的文字不至於顯得擁擠。如果我們增加 padding,一些浏覽器中可能正常顯示,但不是所有。IE 錯誤的盒模型,導致其估算擁有 padding 的元素寬度異常。一個 200px 寬 20px padding 的 box 在 IE 中被視為 200px 寬,在其他浏覽器中則為正確的 240px。padding 應該加在元素的寬度上。凸微軟!
不過不用擔心...我們可以用完全不依賴於 padding 的方法來解決這個問題。相反,我們把列弄窄一點(列寬減去兩側的 padding),之後用相對定位把它們移至正確的位置。在我們的例子中我們用了 2% 的 padding,則 30% 的列將減至 26%,40% 的列減至 36%。用相對定位移回列時需謹記,現在列變窄了,所以當它們一起像最初那樣左浮動時,每一個需要比上一個移動更遠的距離。
完整的CSS
為了使布局保持在小寬度我在每個內容列增加了overflow:hidden
; 這將切去超出列寬的東東,並阻止其干擾其他布局。重申一下,這只是 IE 的問題,其他所有浏覽器會保持正確的布局,不管列內是蝦米。如果你真想這樣做,可以用 IE 條件注釋只對 IE 寫規則。
#container3 {
float:left;
width:100%;
background:green;
overflow:hidden;
position:relative;
}
#container2 {
float:left;
width:100%;
background:yellow;
position:relative;
right:30%;
}
#container1 {
float:left;
width:100%;
background:red;
position:relative;
right:40%;
}
#col1 {
float:left;
width:26%;
position:relative;
left:72%;
overflow:hidden;
}
#col2 {
float:left;
width:36%;
position:relative;
left:76%;
overflow:hidden;
}
#col3 {
float:left;
width:26%;
position:relative;
left:80%;
overflow:hidden;
}
好了,就是這樣。我希望這篇文章對你有用。可以自己弄一下 CSS 看一下它是如何工作的。你可以搞很多列,只要容器和內容列的數目相等。不要忘記看看我的 demo:2 列 , 3 列, 4 列,以及 5 列。