2.2.4 浮動
最後一種定位模型是浮動模型。浮動的框可以左右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊緣。因為浮動框不在文檔的普通流中,所以文檔的普通流中的塊框表現得就像浮動框不存在一樣。
2-13所示,當把框1向右浮動時,它脫離文檔流並且向右移動,直到它的右邊緣碰到包含框的右邊緣。
圖2-13 向右浮動的元素
在圖2-14中,當把框1向左浮動時,它脫離文檔流並且向左移動,直到它的左邊緣碰到包含框的左邊緣。因為它不再處於文檔流中,所以它不佔據空間,實際上覆蓋住了框2,使框2從視圖中消失。如果把所有三個框都向左浮動,那麼框1向左浮動直到碰到包含框,另外兩個框向左浮動直到碰到前一個浮動框。
圖2-14 向左浮動的元素
如果包含塊太窄,無法容納水平排列的三個浮動元素,那麼其他浮動塊向下移動,直到有足夠空間的地方(見圖2-15)。如果浮動元素的高度不同,那麼當它們向下移動時可能會被其他浮動元素“卡住”。
圖2-15 如果沒有足夠的水平空間,浮動元素將向下移動,直到有足夠空間的地方
行框和清理
浮動框旁邊的行框被縮短,從而給浮動框留出空間,行框圍繞浮動框。實際上,建立浮動框使文本可以圍繞映像(見圖2-16)。
圖2-16 浮動框旁邊的行框被縮短
要想阻止行框圍繞在浮動框的外邊,需要對這個框應用clear。clear屬性的值可以是left、right、both或none,它表示框的哪些邊不應該挨著浮動框。為了實現這種效果,在被清理元素的頂空白邊上面添加足夠的空間,使元素的頂邊緣垂直下降到浮動框下面(見圖2-17)。
圖2-17 清理元素的頂空白邊,為前一個浮動框留出足夠的垂直空間
浮動元素脫離了文檔流,不影響周圍的元素。但是,對元素進行清理實際上為前面的浮動元素留出了垂直空間。
這是一個有用的布局工具,它讓周圍的元素為浮動元素留出空間。這解決了前面看到的絕對位置的問題,也就是垂直高度的改變不影響周圍的元素,從而破壞了設計。
我們來更詳細地看看浮動和清理。假設有一個圖片,希望讓它浮動到一個文字區塊的左邊。希望將這個圖片和文本包含在另一個具有背景顏色和邊框的元素中。你可能會編寫下面這樣的代碼:
.news{
background-color: gray;
border: solid 1px black;
}
.news img {
float:left;
}
.news p{
float:right;
}
<div class="news">
<img src="news-pic.jpg" />
<p>some text</p>
</div>
但是,因為浮動元素脫離了文檔流,所以包圍圖片和文本的div不佔據空間。如何讓包圍元素在視覺上包圍浮動元素呢?需要在這個元素中的某個地方應用clear(見圖2-18)。
圖2-18 因為浮動元素不佔據空間,所以容器元素不包圍它們。添加一個進行清理的空元素可以迫使容器元素包圍浮動元素
不幸的是,沒有現有的元素可以應用清理,所以需要添加一個空元素並且清理它。
.news{
background-color: gray;
border: solid 1px black;
}
.news img {
float:left;
}
.news p{
float:right;
}
.clear{
clear:both;
}
<div class="news">
<img src="news-pic.jpg" />
<p>some text</p>
</div>
這會實現我們希望的效果,但是要添加不必要的代碼。常常有元素可以應用clear,但是有時候不得不為了進行布局而添加無意義的標記。
還可以不對浮動的文本和映像進行清理,而是選擇對容器div進行浮動:
.news{
background-color: gray;
border: solid 1px black;
float:left;
}
.news img {
float:left;
}
.news p{
float:right;
}
<div class="news">
<img src="news-pic.jpg" />
<p>some text</p>
</div>
這也會產生我們想要的結果。不幸的是,下一個元素會受到這個浮動元素的影響。為瞭解決這個問題,有些人選擇對布局中的幾乎所有東西進行浮動,然後使用適當的有意義元素(常常是網站的頁尾)對這些浮動元素進行清理。這有助於減少或消除不必要的標記。但是,浮動會變得複雜,而且一些老式瀏覽器在處理有許多浮動元素的布局時有困難。因此,許多人喜歡添加少量的額外標記。
應用值為hidden或auto的overflow屬性會自動地清理包含的任何浮動元素,而不需要添加額外的標記。這個方法並不適合所有情況,因為設定框的overflow屬性會影響它的表現。
最後,一些人使用CSS產生的內容或JavaScript對浮動元素進行清理。這兩種方法的基本概念是相同的。並不直接向標記中添加進行清理的元素,而是將它動態地添加到頁面中。
對於這兩種方法,需要指定進行清理的元素應該出現在哪裡,而且常常要添加一個類名:
<div class="news clear">
<img src="news-pic.jpg" />
<p>some text</p>
</div>
在使用CSS方法時,結合使用:after偽類和內容聲明在指定的現有內容的末尾添加新的內容。在這個樣本中,我添加了一個句點,因為它是個非常小的不引人注意的字元。不希望新內容佔據垂直空間或者在頁面上顯示,所以需要將height設定為0,將visibility設定為hidden。因為被清理的元素在它們的頂空白邊上添加了空間,所以產生的內容需要將它的display屬性設定為block。
這樣設定之後,就可以對產生的內容進行清理:
.clear:after {
content: ".";
height:0;
visibility: hidden;
display: block;
clear:both;
}
這個方法在大多數現代瀏覽器中是有效,但是在IE 6和更低版本中不起作用。有各種解決方案,其中許多記錄在www.positioniseverything.net/easyclearing.html中。最常用的解決方案涉及使用Holly招數(見第8章),從而迫使IE 5-6應用“布局”(見第9章)和不正確地清理浮動元素。
.clear{
display: block;
}
/* holly hack targets ie win only \*/
* html .clear {height:1%;}
.clear {display:block;}
/* end holly hack */
但是,由於其複雜性,這個方法可能不適合所有人採用。
對JavaScript方法的解釋超出了本書的範圍,但是需要簡要地提及一下。與前面的方法不同,JavaScript方法在所有主流瀏覽器上都是有效(在開啟指令碼功能的情況下)。但是,如果使用這個方法,就需要確保在關閉指令碼功能的情況下內容仍然是可讀的。
2.3 小結
在本章中,學習了框模型的一些性質。看到了相鄰垂直空白邊的疊加如何形成單一空白邊,以及Windows上的IE 5.x如何以與其他瀏覽器不同的方式解釋width屬性。理解了絕對位置和相對定位之間的差異,以及在相對定位的容器中進行絕對位置是多麼有用。最後,還看到了浮動在各種情況下的表現,學習了如何通過增加頂空白邊對元素進行清理。
具備了這些知識之後,我們就可以開始運用它們了。在本書的下一部分中,我們將講解許多CSS核心概念,你將看到如何使用這些概念建立各種有用且實用的技術。開啟慣用的文字編輯器,我們要開始編程了。