要掌握的三個最重要的CSS概念是浮動、定位和框模型。這些概念控制在頁面上安排和顯示元素的方式,形成CSS的基本佈局。如果你習慣於用表格控制佈局,那麼這些概念初看上去可能有點兒奇怪。實際上,大多數人只有在使用CSS開發站點一段時間之後,才能完全掌握框模型的複雜性、絕對定位和相對定位之間的差異以及浮動和清理的實際工作方式。在切實掌握這些概念之後,使用CSS開發站點就會變得容易多了。
在本章中,你將學習:
- 框模型的複雜性和特性。
- 如何以及爲什麼使用空白邊疊加。
- 絕對定位和相對定位之間的差異。
- 浮動和清理是如何工作的。
2.1 框模型概述
#myBox {
margin: 10px;
padding: 5px;
width: 70px;
}
填充、邊框和空白邊可以應用於一個元素的所有邊,也可以應用於單獨的邊。空白邊還可以是負值,並且在多種技術中都要使用負值的空白邊。
2.1.1 IE/Win 和框模型
不幸的是,IE 5.x 和 IE 6 在怪異模式中使用自己的非標準框模型。這些瀏覽器的 width 屬性不是內容的寬度,而是內容、填充和邊框的寬度總和。這實際上有一定的意義,因爲在現實世界中框具有固定的尺寸,而且填充是放在框裏面的。添加的填充越多,給內容留下的空間就越少。儘管符合邏輯,但是這些 IE 版本不符合規範,這會造成嚴重的問題。例如,在前面的示例中,在 IE 5.x 中框的總寬度只有 90 像素。這是因爲 IE 5.x 認爲 每個邊上 5 像素的填充是 70 像素的寬度的一部分,而不是在寬度之外附加的 (見圖 2-3)。
幸運的是,有幾個方法快可以解決這個問題,這些方法的細節可以在第 9 章中找到。但是,目前最好的解決方案是迴避這個問題。也就是,不要給元素添加具有指定寬度的填充,而是嘗試將填充或空白邊添加到元素的父元素或子元素。
2.1.2 空白邊疊加
空白邊疊加是一個相當簡單的概念。但是,在實踐中對網頁進行佈局時,它會造成許多混淆。簡單地說,當兩個垂直空白邊相遇時,它們將形成一個空白邊。這個空白邊的高度等於兩個發生疊加的空白邊的高度中的較大者。
當一個元素出現在另一個元素上面時,第一個元素的底空白邊與第二個元素的頂空白邊發生疊加 (見圖 2-4)。
這就是一系列空的段落元素佔用的空間非常小的原因,因爲它們的所有空白邊都疊加到一起,形成一個小的空白邊。
空白邊疊加初看上去可能有點兒奇怪,但是它實際上是有意義的。以由幾個段落組成的典型文本頁面爲例 (見圖 2-8)。第一個段落上面的空間等於段落的頂空白邊。如果沒有空白邊疊加,後續所有段落之間的空白邊將是相鄰頂空白邊和底空白邊的和。這意味着段落之間的空間是頁面頂部的兩倍。如果發生空白邊疊加,段落之間的頂空白邊和底空白邊疊加在一起,這樣各處的距離就一致了。
*****只有普通文檔流中塊框的垂直空白邊纔會發生空白邊疊加。行內框、浮動框或絕對定位框之間的空白邊不會疊加。*****
2.2 定位概述
既然已經熟悉了框模型,我們就來看看視覺格式化模型和定位模型。理解這兩個模型的細微差異是非常重要的,因爲它們一起控制着如何在頁面上佈置每個元素。
2.2.1 視覺格式化模型
p、h1 或 div 等元素常常稱爲塊級元素。這意味着這些元素顯示爲一塊內容,即 "塊框"。與之相反,strong 和 span 等元素稱爲行內元素,因爲它們的內容顯示在行中,即 "行內框"。
可以使用 display 屬性改變生成的框的類型。這意味着,通過將 display 屬性設置爲 block,可以讓行內元素 (比如錨) 表現得像塊級元素一樣。還可以通過將 display 屬性設置爲 none ,讓生成的元素根本沒有框。這樣,這個框及其所有內容就不顯示,不佔用文檔中的空間。
****CSS 中有三種基本的定位機制:普通流、浮動和絕對定位。****
除非專門指定,否則所有框都在普通流中定位。顧名思義,普通流中元素框的位置由元素在 (X)HTML 中的位置決定。
塊級框從上到下一個接一個地排列;框之間的垂直距離由框的垂直空白邊計算出來。
行內框在一行中水平佈置。****可以使用水平填充、邊框和空白邊調整它們的水平間距 (見圖2-9) 。但是,垂直填充、邊框和空白邊不影響行內框的高度。****由一行形成的水平框稱爲行框,****行框的高度總是足以容納它包含的所有行內框。但是,設置行高可以增加這個框的高度。****
在這種情況下,這個框稱爲無名塊框,因爲它不與專門定義的元素相關聯。
塊級元素內的文本行也會發生類似的情況。假設有一個包含三行文本的段落。每行文本形成一個無名行框。無法直接對無名塊或行框應用樣式,因爲沒有可以應用樣式的地方。但是,這有助於理解在屏幕上看到的所有東西都形成某種框。
2.2.2 相對定位
相對定位是一個非常容易掌握的概念。如果對一個元素進行相對定位,它將出現在它所在的位置上。然後,可以通過設置垂直或水平位置,讓這個元素 "相對於" 它的起點進行移動。如果 top 設置爲 20 像素,那麼框將出現在原位置頂部下面 20 像素的地方。如果將 left 設置爲 20 像素,那麼會在元素左邊創建 20 像素的空間,也就是將元素向右移動 (見圖 2-10) 。
在使用相對定位時,無論是否進行移動,元素仍然佔據原來的空間。因此,移動元素會導致它覆蓋其他框。
2.2.3 絕對定位
相對定位實際上被看作普通流定位模型的一部分,因爲元素的位置相對於它在普通流中的位置。與之相反,絕對定位使元素的位置與文檔流無關,因爲不佔據空間。普通文檔流中其他元素的佈局就像絕對定位的元素不存在時一樣 (見圖 2-11) 。
絕對定位的元素的位置相對於最近的已定位祖先元素。如果元素沒有已定位的祖先元素,那麼它的位置相對於最初的包含塊。根據用戶代理的不同,最初的包含塊可能是畫布或HTML 元素。
與相對定位的框一樣,絕對定位的框可以從它的包含塊向上、下、左、右移動。這提供了很大的靈活性。可以直接將元素定位在頁面上的任何位置。
對於定位的主要問題是要記住每種定位的意義。相對定位是 "相對於" 元素在文檔流中的初始位置,而絕對定位是 "相對於" 最近的已定位祖先元素,如果不存在已定位的祖先元素,那麼是最初的包含塊。
因爲絕對定位的框與文檔流無關,所以它們可以覆蓋頁面上的其他元素。可以通過設置 z-index 屬性來控制這些框的堆放次序。z-index 值越高,框在堆中的位置就越高。
絕對定位的元素的位置相對於最近的已定位祖先元素,這使我們能夠實現一些非常有意思的效果。例如,假如希望讓一個文本段落對準一個大框的右下角。只需對包含框進行相對定位,然後相對於這個框對段落進行絕對定位:
#branding {
width: 700px;
height: 100px;
position: relative;
}
#branding .tel {
position: absolute;
right: 10px;
bottom: 10px;
text-align: right;
}
<div id="branding">
<p class="tel">Tel: 0845 838 6163</p>
</div>
相對於相對定位的祖先元素對框進行絕對定位,這在大多數現代瀏覽器中實現得很好。
*****但是,在 Windows 上的 IE5.5 和 IE6 中有一個 bug。如果試圖相對於相對定位的框的右邊或底部設置絕對定位的框的位置,那麼需要確保相對定位的框已經設置了尺寸。如果沒有,那麼 IE 會相對於畫布定位這個框。****
在第9章可以進一步瞭解這個 bug 和修復方法。簡單的解決方案是爲相對定位的框設置寬度和高度,從而避免這一問題。
在進行頁面佈局時,絕對定位是非常有用的工具,尤其是在使用相對定位的祖先元素的情況下。完全可能只使用絕對定位創建出整個設計。爲此,這些元素需要具有固定尺寸,這樣就能夠將它們定位在任何地方而不會有重疊的風險。
因爲絕對定位的元素與文檔流無關,所以它們不影響普通流中的框。如果擴大絕對定位的框 (例如,通過增加字號),周圍的框不會重新定位。因此,尺寸的任何改變會導致絕對定位的框產生重疊,從而破壞精心調整過的佈局。
固定定位
固定定位是絕對定位的一個子類別。差別在於固定元素的包含塊是視口。這使我們能夠創建總是出現在窗口中相同位置的浮動元素。這種情況的一個示例可以在 snook.ca 上看到 (見圖 2-12)。博客評論表單採用固定定位,這使它在頁面滾動時一直出現在屏幕上的相同位置。這有助於改進易用性,用戶不必爲了發表評論而一直滾動到頁面底部。
不幸的是,IE6和更低版本不支持固定定位。爲了解決這個問題,Jonathan Snook 使用 JavaScript 在 IE 中重現了這個效果。
2.2.4 浮動
最後一種定位模型是浮動模型。浮動的框可以左右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊緣。
****因爲浮動框不在文檔的普通流中,所以文檔的普通流中的塊框表現得就像浮動框不存在一樣。****
如圖 2-13 所示,當把框 1 向右浮動時,它脫離文檔流並且向右移動,直到它的右邊緣碰到包含框的右邊緣。