數(shù)年前,當(dāng)開發(fā)者首次開始不使用table 來布局網(wǎng)頁時(shí),CSS中的一個(gè)property突然間顯得格外重要,該屬性就是float。float屬性變得如此常用的原因在于:默認(rèn)情況下,在一個(gè)以列布局的方式中 block-level元素之間不會對齊。因?yàn)?code>column在實(shí)際的CSS布局中 是常用且必需的,所以float屬性逐漸地被極多地采用(甚至濫用)。
CSS float 屬性是什么?
CSS的float 屬性允許開發(fā)者 在不使用table的前提下 在網(wǎng)頁的布局中 融入類似表格的 column。如果不是因?yàn)镃SS的float屬性,不使用絕對和相對定位,CSS的布局是不可能實(shí)現(xiàn)的。采用 相對定位和絕對定位 實(shí)現(xiàn)的布局 會非常凌亂 并且 這樣的布局是不可維護(hù)的。
在這篇文章中,我們將會具體討論:float屬性是什么;float屬性 在具體的上下文中 是如何影響元素的。我們也會看看float屬性在大多數(shù)常用的瀏覽器中 會有哪些差異。最終,我們會展示:CSSfloat屬性的一些實(shí)際的使用。這將會提供一個(gè)對float屬性 全面地且透徹地討論。
定義與語法 - Definition and Syntax
CSSfloat屬性的目的 在于:把一個(gè)block-level元素推到左邊或者右邊,使該block-level元素 相對于其它的元素 脫離文檔流。這使得 自然流動(dòng)的內(nèi)容 會包裹浮起來的元素。這個(gè)概念類似于:你每天在印刷媒體上所看到的內(nèi)容(圖片或其它圖像元素 對齊于左邊或者右邊,其它的內(nèi)容 通常是一些文本 會環(huán)繞在 左對齊或右對齊的 圖片元素 周圍)。如下圖所示:

上圖展示了:3個(gè)圖片 在它們各自的列中 都是左對齊的,并且都被文字環(huán)繞著。這是CSS布局中 float屬性的基本觀念,并且展示了float在table-less design中的 一個(gè)使用方式。

語法
CSS的float屬性 可以接收4個(gè)值:left, right, none, inherit。float的使用方式如下:
#sidebar {
float: left;
}
最常用的值是:left和right。none是所有元素的默認(rèn)值(或者說是初始值)。inherit可以用于幾乎所有的CSS屬性,但是在IE 7及以下 inherit不起作用。
float屬性不需要其它任何的屬性 共同作用于 同一個(gè)元素,就能正常運(yùn)作;然而,float在特定環(huán)境下會更有效地運(yùn)作??偟膩碚f,一個(gè)浮起來的元素 應(yīng)該又一個(gè)明確的寬度(除非該元素是replaced element,比如一個(gè)圖片)。這保證了:浮動(dòng)的行為和預(yù)料中的一致,有助于 在某些瀏覽器中 避免問題的出現(xiàn)。
#sidebar {
float: left; width: 350px;
}
浮動(dòng)元素的細(xì)節(jié) - SPECIFICS ON FLOATED ELEMENTS
下列是浮動(dòng)元素具體行為的列表:
- 一個(gè)左浮動(dòng)起來的盒子 會左移到:盒子的外邊距的左最外沿(如果沒有外邊距,就是邊框的左邊沿) 接觸到 包含該盒子的父元素的邊沿 或者 另一個(gè)浮動(dòng)元素的邊沿。
- 如果浮動(dòng)元素的尺寸超過了 可利用的水平空間,浮動(dòng)元素會移動(dòng)到下一行。
non-positionednon-floated的塊元素 默認(rèn) 浮動(dòng)元素不占據(jù)空間,因?yàn)楦?dòng)元素 相對于其它塊元素 是脫離文檔流的。- 浮動(dòng)元素的外邊距 不會和相鄰元素的外邊距 合并。
- 根元素(<html>)不能浮起來。
- 一個(gè)浮動(dòng)起來的
inline元素 會被轉(zhuǎn)化為 塊元素。
float的實(shí)際使用 - Float in Practice
float屬性最常用的用途之一是:使圖片浮動(dòng)起來,并且使文本環(huán)繞包裹 浮動(dòng)圖片。如下圖所示:

上圖中用于圖片的CSS代碼如下:
img {
float: left;
margin: 0 15px 5px 0;
border: solid 1px #bbb;
}
為了達(dá)到上圖效果 所需要的唯一的屬性 是:float。上面代碼中出現(xiàn)的其它的屬性(margin, border) 是出于審美的原因。上圖中的其它元素(含有文本的p元素) 不需要任何樣式作用于它們。
像上文中提到的那樣,浮起來的元素 相對于其它塊元素 是脫離文檔流的,并且其它塊元素仍然在文檔流中,其它塊元素的行為 看起來 好像浮動(dòng)元素并不在那兒一樣。這可以用下圖展示:

在上面例子中,p元素是塊元素,所以p元素會 忽略 浮動(dòng)元素,跨越整個(gè)父容器的寬度(減去padding)。所有沒有浮起來的塊元素都有類似的行為。
p元素內(nèi)的文本是inline元素,所以文本會圍繞浮動(dòng)元素。浮動(dòng)元素之所以有外邊距,是想讓它偏離p元素:使得p元素忽略浮動(dòng)元素在視覺上更清晰。
清除浮動(dòng) - Clearing Floats
使用浮動(dòng)所帶來的布局問題 可以通過 使用CSS的clear屬性 來解決,這可以讓你清除某個(gè)元素 左側(cè)的或者右側(cè)的 浮動(dòng)元素。
讓我們來看一個(gè)經(jīng)常會出現(xiàn)的例子 - footer圍繞在 一個(gè)2列布局 的右側(cè):

如果你在IE6 IE7中查看的話:左側(cè)列和右側(cè)列都在對的位置,footer也被塞到下方。但是如果在Firefox,Opera,Safari,Chrome中,你會看到footer會跳到左側(cè)列的旁邊。之所以會這樣,是因?yàn)樽髠?cè)列的浮動(dòng)。這是正確的行為,即使左側(cè)列的浮動(dòng)會造成困擾。為了解決這個(gè)問題,我們使用上述的clear屬性,并應(yīng)用于 footer:
#footer {
clear: both;
}
結(jié)果如下所示:

clear屬性會清除浮起來的元素,所以應(yīng)用clear: both到2列 不會讓footer下移,因?yàn)?code>footer不是浮起來的元素。
所以對非浮動(dòng)元素 使用clear,去強(qiáng)制浮動(dòng)元素占據(jù)它們本來的空間。
解決父元素的坍塌 - Fixing the Collapsed Parent
過度使用float的布局 最常見的癥狀之一 是:父元素坍塌。如下所示:

注意:浮起來的圖片的底部出現(xiàn)在了它的父元素的外邊。父元素沒有擴(kuò)展到完全包含浮動(dòng)圖片。之所以會這樣是由于:浮起來的元素 相對于其它塊元素 脫離了文檔流,所以所有的塊元素在被渲染時(shí),是假設(shè)浮動(dòng)元素不在它原本的位置上的。這不是CSS的bug;這是和CSS說明一致的。所有的瀏覽器在這個(gè)示例中的渲染結(jié)果都是一樣的。應(yīng)該指出的是:在這個(gè)例子中,對父容器添加一個(gè)寬度 會阻止 IE瀏覽器發(fā)生父元素坍塌;所以這是在Firefox,Opera,Safari,Chrome中你不得不解決的問題。
解決方案1:使父元素浮起來 - SOLUTION 1: FLOAT THE CONTAINER
解決這個(gè)問題的最簡便的方法是:使 包含它的父元素 浮起來:

現(xiàn)在父容器擴(kuò)展到 包含所有的子元素。但是不幸的是,這個(gè)方法只會在有限的幾個(gè)環(huán)境下起作用,因?yàn)楦?dòng)父元素可能對你的布局產(chǎn)生難以預(yù)料的效果。
解決方案2:添加額外的標(biāo)記 - SOLUTION 2: ADDING EXTRA MARKUP
這是個(gè)過期的方法,但是好在簡單。只需要在父容器的下面添加一個(gè)額外的元素,并清除它。下面是 使用該方法后 html的樣子:
<div id="container">

<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper.</p>
<div class="clearfix"></div>
</div>
應(yīng)用于新添加元素的CSS:
.clearfix {
clear: both;
}
你也可以通過使用
標(biāo)簽達(dá)到同樣的效果。在任何情況下,這個(gè)方法都會讓你得到想要的結(jié)果:父容器會擴(kuò)展到 包圍它所有的子元素。但是這個(gè)方法并不推薦,因?yàn)樗砑恿藳]有語義的代碼 給你的標(biāo)記語言。
解決方案3:after偽元素 - SOLUTION 3: THE :AFTER PSEUDO-ELEMENT
:after偽元素給HTML頁面添加了一個(gè)元素。這個(gè)方法經(jīng)常被用來解決清除浮動(dòng)的問題。CSS代碼如下:
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
如果包含浮動(dòng)元素的父容器 沒有擴(kuò)展到 包圍所有的子元素,這時(shí)就可以使用clearfix。但是這個(gè)方法不適用于IE7 及以下,所以需要 使用下面規(guī)則 來設(shè)置 一個(gè)額外的IE樣式 :
.clearfix {
display: inline-block;
}
.clearfix {
zoom: 1;
}
根據(jù)你要處理的問題的類型,上述2中解決方式中一個(gè) 會解決 IE中的問題。需要指出的是:zoom屬性是一個(gè)不標(biāo)準(zhǔn)的微軟專有的屬性,并且會導(dǎo)致你的CSS無效。
因?yàn)?code>:after偽元素的解決方式在IE6 IE7中無效,并且需要額外的無效的IE樣式,所以在代碼方面顯得有點(diǎn)臃腫。雖然這個(gè)方法不是最佳方法,但是可能是目前最好的方法。
解決方案4:overflow屬性 - SOLUTION 4: THE OVERFLOW PROPERTY
截止到現(xiàn)在,最好的最容易的解決父元素坍塌問題的方法是:為父元素 添加overflow: hidden或者overflow: auto。這個(gè)方法很簡潔,易于維護(hù),在幾乎所有的瀏覽器中都起作用,而且不會添加額外的標(biāo)記。
你會注意到:我所說的,幾乎所有的瀏覽器。這是因?yàn)樗皇怯糜贗E6。但是在很多情況下,父容器都會有一個(gè)設(shè)置好的寬度,這恰好解決了IE6中的問題。如果父容器沒有寬度,你可以使用下面代碼 添加一個(gè)IE6的樣式:
// This fix is for IE6 only
.clearfix {
height: 1%;
overflow: visible;
}
在IE6中,height會被錯(cuò)誤地認(rèn)為是min-height,所以 這會強(qiáng)制父容器包圍它的子元素。overflow接著被設(shè)置回visible,確保了內(nèi)容沒有被隱藏或卷起來。
在任何瀏覽器中 使用overflow方法的唯一缺點(diǎn)是:父元素會有滾動(dòng)條 或者 隱藏的內(nèi)容。如果父元素中的任意的子元素 使用了負(fù)的外邊距 或者 絕對定位,并且它們超過了父元素的邊框,它們會被遮擋。所以,這個(gè)方法應(yīng)該被謹(jǐn)慎使用。應(yīng)該指出的是:如果父元素不得不設(shè)置一個(gè)具體的height或min-height,那么你絕對不要使用overflow方法。
所以,實(shí)際上沒有簡單的,兼容所有瀏覽器的 解決父元素坍塌問題的 方法。但是幾乎任何的浮動(dòng)清除問題 通過上述方法中某一個(gè) 都可以被解決。
IE中float相關(guān)的bug - Float-Related Bugs in Internet Explorer
這些年來,有許多關(guān)于CSSfloat的bugs討論的文章被發(fā)布到網(wǎng)上。所有這些文章 無疑都是 處理IE特定的問題的。下面,你會發(fā)現(xiàn)一些文章的鏈接列表,這些文章深入討論了float相關(guān)的問題:
使用JavaScript更改float屬性 - Changing the Float Property with JavaScript
在JavaScript中更改一個(gè)CSS值,你需要訪問style對象。使用對象時(shí)需要做個(gè)轉(zhuǎn)換:把想要的CSS屬性轉(zhuǎn)換為駝峰的樣子。例如,CSS屬性magin-left在JavaScript中變?yōu)榱?code>marginLeft; background-color屬性在JS中變?yōu)榱?code>backgroundColor等等。但是使用float屬性時(shí),有點(diǎn)不同,因?yàn)閒loat已經(jīng)是JavaScript中保留的關(guān)鍵字了。所以,接下來的代碼是不正確的:
myDiv.style.float = "left";
作為代替,你應(yīng)該使用下面中的一種:
// For Internet Explorer
myDiv.style.styleFloat = "left";
// For all other browsers
myDiv.style.cssFloat = "left";
float的實(shí)際應(yīng)用 - Practical Uses for Float
float可以被用來解決在CSS布局中的許多設(shè)計(jì)挑戰(zhàn)。一些例子在這兒被討論了。
2列,固定寬度的布局
這兒 列出了 創(chuàng)建一個(gè)簡單的,兼容多瀏覽器的 2列水平居中布局 的8步指導(dǎo)。float屬性對于該布局的融洽是必需的。
布局包括了一個(gè)header,一個(gè)水平導(dǎo)航條,一個(gè)主內(nèi)容列,一個(gè)側(cè)邊欄,以及一個(gè)footer。布局在瀏覽器窗口中是水平居中的。這是一個(gè)相當(dāng)基本的布局,只要你知道如何處理不可避免的IE bugs,使用CSS創(chuàng)建該布局一點(diǎn)都不困難。

3列,等高布局
pixy.cz 展示了兼容多瀏覽器的3列布局,同樣使用的是float:
沒有
table,沒有絕對定位(沒有任何定位),沒有hacks,所有列都保持同樣的高度。左側(cè)欄和右側(cè)欄有個(gè)固定寬度(150px),中間欄自適應(yīng)寬度。

帶標(biāo)題的浮動(dòng)圖片
類似于 我們之前在'Float in Practice'章節(jié) 所討論的內(nèi)容,Max Design 描述了怎樣使 帶標(biāo)題的圖片浮起來,并允許圖片周圍的文本自然地圍繞著它。
Floating an Image and Caption

使用無序列表創(chuàng)建水平導(dǎo)航
float屬性 在編碼基于sprite圖的水平導(dǎo)航條時(shí) 是一個(gè)關(guān)鍵因素。Line25描述了 怎樣創(chuàng)建一個(gè)很棒的menu,這里的li元素包含了導(dǎo)航按鈕,并且li元素是左浮動(dòng)的:
How to Create a CSS Menu Using Image Sprites

為了展示在這個(gè)例子中
float屬性的重要性,這兒有一個(gè) 在使用firebug移除float: left后 的截屏:
基于柵格的圖片陳列室
對float屬性的一個(gè)簡單使用 是:左浮動(dòng) 包含在無序列表中一系列圖片,這會得到 和‘基于table的布局’相同的 布局。

上圖中的這些圖片 是以無序列表的形式被展示的,該無序列表的所有l(wèi)i元素的float屬性都被設(shè)置為float: left。比起基于table的柵格布局,這種方式的布局更好,因?yàn)殛惲惺抑械膱D片數(shù)量改變時(shí),布局不會受到影響。

上圖中的iStockphoto’s search results page 是個(gè)類似結(jié)構(gòu)的圖片柵格,但是這次的所有圖片都被包含在左浮動(dòng)的<div>元素中,而不是li元素中。
把<input> field和button對齊
各種瀏覽器中form元素的默認(rèn)樣式處理起來很頭疼。很多時(shí)候,在 單field的form中(比如一個(gè)搜索form) 把input元素放在提交按鈕的旁邊是必需的。
在所有的瀏覽器中,結(jié)果都是相同的:提交按鈕看起來比input field要高。更改margin和padding不會更改顯示結(jié)果。最簡單的方式是:使input field左浮動(dòng),并添加一個(gè)微小的右外邊距。
總結(jié) - Conclusion
就像在一開始提到的那樣,不使用CSS的float屬性時(shí),table-less的布局 在最壞的情況下 會變得不可能,在最好的情況下 會變得不可維護(hù)。float在CSS布局中仍然是重要的,即使當(dāng)CSS3開始獲得重要位置 - 即便 已經(jīng)有一些關(guān)于‘不使用float進(jìn)行布局’的討論。希望這里的討論已經(jīng)簡化了 一些有關(guān)float的奧秘,并對開發(fā)者所面臨的許多問題 提供了一些實(shí)際的解決方法。
本文翻譯自: https://www.smashingmagazine.com/2009/10/the-mystery-of-css-float-property/
轉(zhuǎn)載請注明出處