CSS Float是網頁設計最強大的靈活性功能之一。本文介紹CSS
Float的基本原理和行為特徵,並介紹各種瀏器Float特性的Bugs。
內容
- 基本的浮動原理
- 浮動是如何進行的
- 浮動從何處開始
- 水平浮動堆疊
- 反向浮動
- Clearing Floats
基本的浮動原理
任何元素 element
都可以被浮動。段落、div、list、tables,以及映像都可以被浮動,事實上即使是像 span
和 strong
這樣的行內建元素也可以很好地進行浮動。
任何申明為 float
的元素自動被設定為一個"區塊層級元素",
這表示它可以具有申明的"width"和"height"屬性。事實上,floats當前被要求具有一個申明的寬度,但這不是現代瀏覽器製造者的思
路,W3C以及開始同意這樣的作法。現在大多數人的意見是沒有指定寬度的float應當伸縮封裝到浮動內容的寬度。因此,內部帶有圖片的一個float將
和圖片一樣寬,帶有文本的一個浮動將與該浮動內的最長文本行一樣寬。
CSS2.1的浮動規則中這樣講: "如果 width
是以 auto
方式計算得到,使用的值是 shrink-tofit
伸縮到適合的寬度。"
所有現代的瀏覽器已經這樣做,除了IE5/Mac。除非浮動具有某種指定的寬度,否則該瀏覽器會變得錯誤百出。現在大多數聰明的編碼人員會讓瀏覽器伸縮其
沒有寬度屬性的floats,
並使用一個隱藏的專門給IE5/Mac的寬度知識。這可能不算很巧妙,但是它是現在不能滿足該規範的極少數的瀏覽器,同時Mac使用者有幾種更好的選擇。
MS停止了對IE5/Mac的支援,因此尋求像伸縮封裝式浮動這樣有用特性被避免的代價太高了,這樣只有IE5/Mac使用者不會看到錯誤的浮動。
浮動是如何進行的
浮動"從流程中被移除出來",
但是與絕對位置的元素(層次)不同,浮動是在他們前面的最後一個塊元素之後直接被顯示出來(就像塊盒一樣)。如果該浮動是在一個“行塊”中,該浮動的上邊
界被放置在行塊頂部的水平上。當除此以外,浮動與絕對元素相似,原先的塊盒會完全忽略浮動和AP元素。那些靜態塊盒知識保持一個接一個地”跟隨“,就好
像沒有浮動不在那裡一樣。
The following is minimal code for the example graphic:
<div style="float:left; width:40%;"><p>Float text</p></div>
<p>
Paragraph text outside the float
</p>
上例展示了行盒在一個浮動中是如何被削短的。你可以讓行內元素(像文本、映像)在一個浮動的邊上放置並且在它的下面繼續,就好像使用很好的老式(不
過已淘汰)映像的屬性"align=left"。浮動,比這要靈活的多。
認為跟在一個浮動後面的塊元素會被設定為放置在浮動的下方是通常的一個誤解。事實上,只有在哪些塊元素內部的”行盒“才會這樣。
還記得我提到的浮動被從文檔處理流程中移除出來的話嗎?標準要求在一個浮動後面的行盒被進行足夠的削短以保持行盒在外部開放區。這表示文本和行內的
映像永遠不會被浮動覆蓋,除非他們其中之一或兩個在獨立的、指定位置的容器中。這就是說,如果一個浮動被嵌套在一個絕對位置的元素中,並且AP元素被設定
為覆蓋一個段落,在段落中的行盒不會被浮動削短,這是因為他們不同的上下文環境造成的。而且,文本的確會被該浮動覆蓋。
對於浮動的一個常見錯誤是:將文本保留在該浮動的邊界之外。對浮動後面跟著的段落放置padding或設定邊界是不會生效的,因為這些屬性被應用在
跟隨在浮動後面的段落的左邊。正確的方式是對浮動本身設定margins,這樣可以讓行盒正確顯示,浮動要比它呈現的要更大,並且對他們進行相應的削短。
大多數浮動通常只是從按照最靠近文本的邊和底部獲得這樣的邊界資訊。上面浮動的有一個小的右邊界。
同時跟在float後面的塊盒只是被該浮動覆蓋(即使他們的內容已經被移動到邊上)。如果該浮動被設定的非常高,它可以擋住大量堆疊的塊盒上,就像
第二個看到的那樣:
<div style="float:left; width:30%;">
<p>Left float text</p></div>
<div> <!-- first block box -->
<div style="float:right; width:150px;">
<p>Right float text</p>
</div>
<p>Text following the right nested float</p>
</div>
<p>Paragraph</p> <!-- second block box -->
<p>Paragraph</p> <!-- third block box -->
該圖展示了浮動是如何覆蓋多個塊盒的。
如上所示,浮動的另一個行為是他們的”方向”。當一個浮動被定義的時候,總是被給予一個方向值。(“left”或“right”),例如:div{
float:left;}. 這些值簡單地將浮動移到到容器盒的指定邊界。
偶爾,float的新手會試圖使用浮動值,例如{float:up;} or {float:botton;},
但是這些值是無效的,在浮動的標準中並沒有計劃要添加這些值。人們總是可以期待...
浮動從何處開始
如果一個浮動在兩個塊盒之間,它會將其上邊界放置在前置塊盒的下邊界上,並且將其移動到左(或右邊),直到達到外界容器元素的邊界,通常
是<body>元素。
如果浮動被嵌套在第二個塊盒中,並且該容器盒沒有邊框盒填充,浮動呈現樣式,與浮動被放置在塊盒之間是一樣的。但是,如果這些塊盒通過邊距分離,該
浮動的頂部邊界從一個盒與另一個盒邊界的交叉點上開始。在以下中,塊盒右頂部邊界,但是左側的浮動的左邊距已經被移動以顯示預設的動作。:
<p>Paragraph</p> <!-- first block box (complete) -->
<div style="float:left; width:30%;">
<p>Left float text</p></div>
<div> <!-- second block box -->
<div style="float:right; width:150px;">
<p>Right float text</p>
</div>
<p>Text following the right nested float</p>
</div>
該圖展示了浮動可能被放置在不同的位置。
水平浮動堆疊
如果居左的浮動被放置在其容器的左上腳,並且其後跟隨一個同向的浮動,該浮動會被放置在容器右上腳,然後移動到左側,邊界延伸到第一個浮動的右側時
停止。
最後的一種行為讓我們建立整行的floats,每個都被放置在前一個的右側(或者左側,如果使用{float:right;}).
同樣,當一行中沒有足夠的空間時,多出來的floats繞到下一行,非常像行內元素那樣。這對於製作可點擊的映像“簡略圖”非常方便,因為矩陣會自動調整
到螢幕的尺寸,只是簡單地在需要時進行迴繞。
以下是一行彩色的左向浮動。左上方的浮動在原始碼中先出現,右下方的最後。他們都有一個小的邊距以便看起來更好一些。試一下將瀏覽器的尺寸變小一
些,觀察浮動行被迴繞以使用視窗尺寸。
Float 1 Float 2 Float 3 Float 4 Float 5 Float 6 Float 7 Float 8 Float
9 Float 10 Float 11 Float 12 Float 13 Float 14 Float 15
上述浮動會迴繞以使用任何螢幕的尺寸。注意其下段落(不可見)的文本同樣也調整以使用浮動排列的變化。該段落實際上從第一個浮動開始的地方開始,但
是只有在段落文本可見的情況下,該事實才不明顯。中的段落具有邊框盒背景以便顯示實際的位置。
如果浮動被設定為“右側”而不是“左側”,其行為完全相同,知識浮動從右開始,而不是從左開始,後續的浮動被添加到左側行尾而不是右側。兩種情況,
迴繞都是一樣的,除非float的Bugs導致差異。
用這樣的方式思考,一個容器中的浮動首先被移到它能夠到達的最上方的空間(在其定位的方向),然後按設定的浮動反向移動直到到達容器的邊界,或者遇
到另一個浮動。每個連續的浮動都是同樣處理,直到其中一個浮動在另一個浮動的level中無法發現足夠寬的空間。這樣,它會被強制停止到另一個浮動的底
部,然後向之前那樣進行滑行。
Float 1 Float 2 Float 3 Float 4 Float 5 Float 6 Float 7 Float 8 Float
9 Float 10 Float 11 Float 12 Float 13 Float 14 Float 15 Float 16 Float
17 Float 18 Float 19 Float 20
警告!注意上面的浮動的高度不是一樣的。當一個浮動被放置到第二行緊接第一行時,它視圖滑行到邊界,當遇到第一高的浮動時會被停住。當有大量不規則
浮動時,這會造成很醜陋的情況。上面的浮動中包含一些比其他高一些的浮動。
縮小你的瀏覽器以不同的螢幕寬度來測試。
在追著一個大型的簡略圖矩陣時,必須注意確保所有的浮動具有同樣的高度,或者頁面可以輕易地被出軌的浮動重新組裝。
本文中的所有例子都使用了特殊的處理以適應IE5.x/win盒模式的缺點。由於邊框和填充造成了必須特殊處理。
反向浮動
Clearing Floats
以下開始講述關於浮動的最晦澀、最難以理解的部分。
回顧一下跟隨浮動後面的靜態盒。這些盒只是忽略浮動,並且在前一個靜態盒的後面排列顯示。假設你給以下盒一個清除屬性,
{clear:both;}。這是將被清除盒的頂部邊距擴充,將其向下推直到清理浮動的底部。換句話說,該被清理的盒的頂部邊距(無論它之前被設定成什麼
值),都會被瀏覽器增加到需要保證被清理盒位於浮動下回的長度。
這樣的效果是,一個被清理的盒無法與前置浮動保持在同一個水平位置上。它必須出現在其下方。以例展示了效果。
展示一個盒如何清理下方的一個浮動。
記住,浮動實際上並不是真正地被包含在一個塊盒中,即使在原始碼中是怎樣嵌套的。請注意確認,浮動的螢幕開始點是由它所嵌套的位置決定的,之後它只
是在容器盒上展開,就像絕對元素一項。只有包含行內元素的行盒(例如文本),才需要關注浮動在哪裡被顯示。
製作一個看起來封裝一個嵌套浮動的外容器的標準方法是在容器的最後放置一個完整“被清理”的元素:
<div> <!-- float container -->
<div style="float:left; width:30%;"><p>Some content</p></div>
<p>Text not inside the float</p>
<div style="clear:both;"></div>
</div>
由於div沒有被浮動,容器必須識別它並封裝它,並且由於頂部邊距(由於“clear”屬性由瀏覽器添加),該div將容器的底部邊界拉到浮動框的
底部。
的確,這是一個古怪的方法,但是標準就是這樣說的。不過,W3C中有一個討論關於添加一個容器自動封裝一個浮動的規則。這樣就於更加簡單。
事實上,IE盒Opera7已經自動封裝嵌套的浮動,與標準不一樣。Opera6不是這樣,因此看來Opera在跟隨MS的非標準道路。
還可以使用 {clear:left;} 或 {clear:right;}.
這可以讓一個元素清除左側浮動當不影響右側浮動,或者相反。要使用這種控制你需要有相當的想像力。
通常來說,清除可以很好地完成,但是有時會引起不大不小的錯誤,這完全是由IE造成的。