詳解CSS float屬性
CSS中的float屬性是一個頻繁用到的屬性,對於初學者來說,如果沒有理解好浮動的意義和表現出來的特性,在使用的使用很容易陷入困惑,雲裡霧裡,搞不清楚狀態。本文將從最基本的知識開始說起,談談關於浮動的應用,出現的問題和解決方案。
基礎知識
float,顧名思義就是浮動,設定了float屬性的元素會根據屬性值向左或向右浮動,我們稱設定了float屬性的元素為浮動元素。
浮動元素會從普通文件流中脫離,但浮動元素影響的不僅是自己,它會影響周圍的元素對齊進行環繞。舉例說明如下:
Html程式碼:
1 2 3 4 5 6 |
<div class="box"> <span class |
CSS程式碼:
1 2 |
.box { background: #00ff90; padding: 10px; width: 500px; } .float-ele { float: left; margin: 10px; padding: 10px; background: #ff6a00; width: 100px |
由效果圖可以看出,span元素周圍的文字會圍繞著span元素,而設定了float屬性的span元素變成了一個塊級元素的感覺,可以設定width和height屬性。這是設定了float屬性後的效果,關於float的詳細細節,我們接下來詳細講解。
float的詳細細節
在說明float帶來的詳細細節之前,我們首先要了解一個概念。
包含塊:浮動元素的包含塊就是離浮動元素最近的塊級祖先元素,前面敘述的例子中,div.box就是span元素的包含塊。
瞭解完包含塊的概念之後,首先要說明的浮動元素的第一個特性:不管一個元素是行內元素還是塊級元素,如果被設定了浮動,那浮動元素會生成一個塊級框,可以設定它的width和height,因此float常常用於製作橫向配列的選單,可以設定大小並且橫向排列。
浮動元素的展示在不同情況下會有不同的規則,下面我們來一一說明這些規則。
1.浮動元素在浮動的時候,其margin不會超過包含塊的padding
這一點很簡單,浮動元素的浮動位置不能超過包含塊的內邊界
HTML程式碼
1 2 3 4 5 |
<div class="box"> <span class="rule1"> 浮動元素 </span> </div> |
CSS程式碼
1 2 |
.box { background: #00ff90; padding: 10px; width: 500px; height: 400px; } .rule1 { float: left; margin: 10px; padding: 10px; background: #ff6a00; width: 100px; text-align: center; } |
這個例子中,box的padding是10px,浮動元素的margin是10px,合起來為20px,即浮動元素不會超過包含塊的padding。
PS:如果想要元素超出,可以設定margin屬性
2.如果有多個浮動元素,後面的浮動元素的margin不會超過前面浮動元素的margin
簡單說就是如果有多個浮動元素,浮動元素會按順序排下來而不會發生重疊的現象。
修改前面例子中的HTML程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 |
<div class="box"> <span class="rule1"> 浮動元素1 </span> <span class="rule1"> 浮動元素2 </span> <span class="rule1"> 浮動元素3 </span> </div> |
如圖所示,浮動元素會一個一個排序下來而不會發生重疊現象。
3.如果兩個元素一個向左浮動,一個向右浮動,左浮動元素的marginRight不會和右浮動元素的marginLeft相鄰。
什麼意思呢,我們要分兩種情況來看。
(1)包含塊的寬度大於兩個浮動元素的寬度總和,舉例如下:
HTML程式碼:
1 2 3 4 5 6 7 8 |
<div class="box"> <span class="rule1"> 浮動元素1 </span> <span class="rule2"> 浮動元素2 </span> </div> |
CSS程式碼
1 2 3 |
.box { background: #00ff90; padding: 10px; width: 500px; height: 400px; } .rule1 { float: left; margin: 10px; padding: 10px; background: #ff6a00; width: 100px; text-align: center; } .rule2 { float: right; margin: 10px; padding: 10px; background: #ff6a00; width: 100px; text-align: center; } |
這種情況很簡單:包含塊元素的寬度足夠大,兩個元素一個向左浮動,一個向右浮動,井水不犯河水。
(2)包含塊的寬度小於兩個浮動元素的寬度總和
修改浮動元素的寬度為300px,CSS程式碼如下:
1 2 |
.rule1 { float: left; margin: 10px; padding: 10px; background: #ff6a00; width: 300px; text-align: center; } .rule2 { float: right; margin: 10px; padding: 10px; background: #ff6a00; width: 300px; text-align: center; } |
如果所示,如果包含塊寬度不夠高,後面的浮動元素將會向下浮動,其頂端是前面浮動元素的底端。
4.浮動元素頂端不會超過包含塊的內邊界底端,如果有多個浮動元素,下一個浮動元素的頂端不會超過上一個浮動元素的底端
這條規則簡單說就是如果有多個浮動元素,後面的元素高度不會超過前面的元素,並且不會超過包含塊。舉例如下:
HTML程式碼:
1 2 3 4 5 6 7 8 9 10 |
<div class="box"> <p>在浮動元素之前在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,</p> <p class="rule1"> 浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1浮動元素1 </p> <p>在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後</p> <p class="rule1"> 浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2浮動元素2 </p> </div> |
CSS程式碼
1 2 3 |
.box { background: #00ff90; padding: 10px; width: 500px; height: 400px; } .rule1 { float: left; margin: 10px; padding: 10px; background: #ff6a00; width: 250px; text-align: center; } p { margin-top: 20px; margin-bottom: 20px; } |
如圖所示,兩個浮動元素,後面的浮動元素不會超過前面的浮動元素
5.如果有非浮動元素和浮動元素同時存在,並且非浮動元素在前,則浮動元素不會不會高於非浮動元素
這條規則也是顯而易見的,在第4條規則中的例子,浮動元素有一個非浮動元素p,而浮動元素沒有超過它。
6.浮動元素會盡可能地向頂端對齊、向左或向右對齊
在滿足其他規則下,浮動元素會盡量向頂端對齊、向左或向右對齊,在第4條規則中的例子,浮動元素會盡可能靠近不浮動的p元素,左側對齊
float特殊情況
前面討論了float需要遵守的一些規則,這些規則都是在比較常見的場景下展示的結果。下面我們來討論一些不常見的情況。
浮動元素的延伸性
在說浮動元素的延伸性之前,我們首先來考慮一個比較特殊的例子。
我們將span元素放在p元素內,並將其高度設定成高於p元素並且左浮動,這個例子的關鍵在浮動元素高度高於父元素。
HTML程式碼
1 2 3 4 5 6 7 |
<p> 在浮動元素之前在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前, <span class="high-float"> 浮動元素比父級元素高 </span> </p> <p>在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後在浮動元素之後</p> |
CSS程式碼
1 2 |
p { margin-top: 20px; margin-bottom: 20px; background-color: #00ff21; width: 500px; } .high-float { float: left; height: 80px; line-height: 80px; background-color: orangered; } |
在這個例子中,浮動元素高度高於父元素,可以看到浮動元素超出了父元素的底端。
這種情況要怎麼解決呢,只要將父元素也設定成浮動即可,我們將第一個p元素設定成左浮動,效果如下
將父元素p設定成float:left後,浮動元素就會被包含到父元素裡面,我們將這個特性成為浮動元素的延伸性。
浮動元素的延伸性是什麼呢,我們可以將其理解為元素被設定成浮動後,該元素會進行延伸進而包含其所有浮動的子元素
浮動元素超出父級元素的padding
在前面提到的第一條規則:浮動元素的外邊界不會超過父級元素的內邊界。大部分情況下,我們見到的場景都是符合的。但是有一些特殊情況。
(1)負margin
我們將浮動元素的margin-left設定成負數。
HTML程式碼:
1 2 3 4 5 6 |
<p> 在浮動元素之前在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前, <span class="minus-margin"> 負margin-left </span> </p> |
CSS程式碼:
1 2 |
p { margin-top: 20px; margin-bottom: 20px; margin-left: 50px; background-color: #00ff21; width: 500px; } .minus-margin { float: left; height: 80px; line-height: 80px; background-color: orangered; margin-left: -20px; } |
將margin-left設定成負數之後,浮動的子元素明顯超出了父元素的內邊界,這難道不是違反了第一條規則嗎?
但仔細想想,這其實是合理的,因為預設情況下marign-left就是0,所以不會超出父元素的內邊界,但是將其設定成負數之後,就相當於浮動元素覆蓋了自己的內邊界一樣。
我們在從數學的角度來看看這個問題,這個例子中:
父元素的margin-left:50px,padding和border預設為0,即內邊界所在距離瀏覽器左側的位置為50px。
浮動的子元素預設情況下距離瀏覽器左側的畫素應該為50px,但是將其設定成margin-left:20px後,瀏覽器會進行計算:
50px+(-20px)margin+0border+0padding=30px。距離瀏覽器左側更近,所以超出了父元素。
(2)浮動元素寬度大於父級元素寬度
如果我們將浮動元素的寬度設定大於父級元素,效果會如何呢?
元素左浮動,width大於父級元素
HTML程式碼
1 2 3 4 5 6 |
<p> 在浮動元素之前在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前, <span class="big-width"> width大於父級元素 </span> </p> |
CSS程式碼
1 2 |
p { margin-top: 20px; margin-bottom: 20px; margin-left: 50px; background-color: #00ff21; width: 250px; } .big-width { float: left; height: 80px; line-height: 80px; background-color: orangered; width: 300px; } |
將浮動元素左浮動,並且寬度超出父級元素時,由於浮動元素寬度較大,它會超過父級元素的右內邊界
如果將其設定成右浮動,情況又會怎麼樣呢?
可以看到,設定成右浮動後,會超出父級元素的左內邊界。
重疊問題
重疊問題是指兩個元素再同一個位置,會出現上下重疊的問題。浮動元素如果和普通文件流發生重疊會怎麼樣呢?
首先浮動元素要怎麼樣才會發生重疊呢,設定其margin-top為負數即可。我們看看例子:
HTML程式碼:
1 2 3 4 5 6 7 8 |
<p> <span> 在浮動元素之前在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前,在浮動元素之前。 </span> <span class="overlay"> 浮動元素重疊 </span> </p> |
CSS程式碼
1 2 |
p { margin-top: 20px; margin-bottom: 20px; margin-left: 50px; background-color: #00ff21; width: 250px; } .overlay { float: left; height: 80px; line-height: 80px; background-color: orangered; width: 300px; margin-top: -30px; } |
如果浮動元素不設定負margin時,是這樣的
浮動元素的重疊問題
在這個例子中,可以看到p中正常流元素span的內容會顯示在浮動元素上面。
我們給設定span設定背景圖片試試,效果如下:
元素設定背景後,重疊的部分還是會顯示背景
如果是span標籤換成div標籤會怎麼樣呢?
HTML程式碼:
|