CSS入門12-浮動與清除浮動

weixin_34107955發表於2018-01-25

(注1:如果有問題歡迎留言探討,一起學習!轉載請註明出處,喜歡可以點個贊哦!)
(注2:更多內容請檢視我的目錄。)

1.浮動的定義

浮動的框可以向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止。

由於浮動框不在文件的普通流中,所以文件的普通流中的塊框表現得就像浮動框不存在一樣。

2. 浮動的特徵

2.1 脫標性

浮動元素會脫離標準文件流,根據屬性向左或右浮動,使周圍元素重新排列。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.1-1</title>
    <style>
        .div1 {
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 50px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
    </style>
</head>
<body>
<div class="div1">div1</div>
<div class="div2">div2</div>
<div class="div3">div3</div>
</body>
</html>
4761597-bbad146abcfa224a.png
2.1-1

標準文件流如上圖所示,塊級元素從上往下排列。我們試著為其加上浮動屬性。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.1-2</title>
    <style>
        .div1 {
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 50px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
    </style>
</head>
<body>
<div class="div1 fl">div1</div>
<div class="div2 fl">div2</div>
<div class="div3 fl">div3</div>
</body>
</html>
4761597-1a10f169546b7c4a.png
2.1-2

可以看到,元素向左漂浮,寬高可以指定,若不指定,預設包裹其元素內容。再來看下,浮動元素對標準文件流元素的影響。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.1-3</title>
    <style>
        .div1 {
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 50px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
    </style>
</head>
<body>
<div>
    <div class="div1">div1</div>
    <div class="div2 fl">div2</div>
    <div class="div3">div3</div>
</div>

</body>
</html>
4761597-267ae4ef229755db.png
2.1-3

可以看到,div3不是紅色,而且檢查div3的元素時發現其真實位置竟然在被div2覆蓋的地方。那麼如果將div2向右浮動呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.1-4</title>
    <style>
        .div1 {
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 50px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fr {
            float: right;
        }
    </style>
</head>
<body>
<div>
    <div class="div1">div1</div>
    <div class="div2 fr">div2</div>
    <div class="div3">div3</div>
</div>

</body>
</html>
4761597-912981f5f49554b1.png
2.1-4

可以看得更明顯,div2其實是脫離標準文件流以後覆蓋了div3。

2.2 寬高對浮動的影響

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.2-1</title>
    <style>
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .div4{
            width: 90px;
            height: 100px;
            background-color: blue;
        }
        .fl {
            float: left;
        }
    </style>
</head>
<body>
<div>
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
    <div class="div3 fl">div3</div>
    <div class="div4 fl">div4</div>
</div>

</body>
</html>
4761597-870b41121b3221e9.png
2.2-1

4761597-d65ce0c5958f0b17.png
2.2-2

4761597-553a4be92cb88763.png
2.2-3

4761597-644cec3979f69e7b.png
2.2-4

4761597-fe84076161d43103.png
2.2-5

4761597-fc968539a011e35e.png
2.2-6

我們逐步將視窗寬度變小,可以發現,向左浮動時,當寬度不夠時,最右邊的盒子會向下挪到挨著左邊最突出的元素或者直到父元素邊框。

2.3 文字環繞

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>2.3</title>
<style>
div {
background-color: green;
}
.fl {
float: left;
}
.text {
word-break: break-all;
}
</style>
</head>
<body>
<div>
<img src="2.3.png" alt="" class="fl">
<div class="text">111111111111111111111111111111111111111111111111111111111111111111111111111111111</div>
</div>
</body>
</html>


4761597-e72b73feeeddea6d.png
2.3

2.4 高度坍塌

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.4</title>
    <style>
        .outer {
            border: 3px solid black;
        }
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
    <div class="div3 fl">div3</div>
</div>
</body>
</html>

4761597-019a55daf9c12801.png
2.4

如圖所示,浮動的元素並不會撐起其父元素的高度。這是怎麼回事呢?我們會在BFC中進行解釋。

3. 清除浮動

清除浮動,總體上來說,有兩種思路:

  1. 利用clear屬性
  2. 利用BFC特性

下面來看一下兩種思路各有哪些具體實現方案。

3.1 利用clear屬性

3.1.1 直接使用clear屬性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.1.1</title>
    <style>
        .outer {
            border: 3px solid black;
        }
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
        .clear {
            clear: left;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
    <div class="div3">div3</div>
</div>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
    <div class="div3 clear">div3</div>
</div>
</body>
</html>
4761597-be58f89190ca6d77.png
3.1.1

可以看到,如果需要清除浮動的元素與浮動元素同級,可以直接在需要清除浮動的元素上新增clear屬性。

3.1.2 額外標籤清除浮動

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.1.1</title>
    <style>
        .outer {
            border: 3px solid black;
        }
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
        .clear {
            clear: left;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3 clear">div3</div>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
    <div class="clear"></div>
</div>
<div class="div3">div3</div>
</body>
</html>
4761597-658ba0cf9ec7a365.png
3.1.2

可以看到,不同級的外部元素想要清除浮動影響,如果使用直接新增clear的方法,無法解決浮動元素的高度坍塌問題。可以在需要清楚浮動的末尾新增一個空標籤,用來清除浮動。

3.1.3 :before,:after偽類清除浮動

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.1.3</title>
    <style>
        .outer {
            border: 3px solid black;
        }
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
        .clearfix {
            zoom: 1;
        }
        .clearfix:after{
            content: '';
            display: block;
            clear: both;
            visibility: hidden;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="outer clearfix">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
</body>
</html>
4761597-df100be4185bfb3d.png
3.1.3

其實原理上和新增空標籤類似。有幾點需要注意:

  1. zoom:1是為了相容性,因為ie6/7不能使用偽類。
  2. content:' . ';display:block; 對於FF/Chrome/opera/IE8不能缺少,其中content()取值也可以為空。
  3. visibility:hidden;的作用是允許瀏覽器渲染它,但是不顯示出來,這樣才能實現清除浮動。

這種方法是相容性最好,後續影響也是最小的。下面提供CSS中的浮動和清除浮動,梳理一下!一文歸納的該方法:

// 現代瀏覽器clearfix方案,不支援IE6/7
.clearfix:after {
    display: table;
    content: " ";
    clear: both;
}

// 全瀏覽器通用的clearfix方案
// 引入了zoom以支援IE6/7
.clearfix:after {
    display: table;
    content: " ";
    clear: both;
}
.clearfix{
    *zoom: 1;
}

// 全瀏覽器通用的clearfix方案【推薦】
// 引入了zoom以支援IE6/7
// 同時加入:before以解決現代瀏覽器上邊距摺疊的問題
.clearfix:before,
.clearfix:after {
    display: table;
    content: " ";
}
.clearfix:after {
    clear: both;
}
.clearfix{
    *zoom: 1;
}

3.2 利用BFC特性

為父元素新增以下屬性來觸發BFC:

  • float 為 left | right
  • overflow 為 hidden | auto | scorll
  • display 為 table-cell | table-caption | inline-block | flex | inline-flex
  • position 為 absolute | fixed

可以給父元素設定overflow:auto來簡單地實現BFC清除浮動,但是為了相容IE最好用overflow:hidden。不過這樣元素陰影或下拉選單會被截斷,比較侷限。下面選取前兩種方法來看一下效果。

3.2.1 使父元素浮動

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1</title>
    <style>
        .outer {
            border: 3px solid black;
        }
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="outer fl">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
</body>
</html>
4761597-69c2c10cd6b3a8b7.png
3.2.1

這種方法,以暴制暴,父元素變成浮動以後同樣需要考慮其影響和清除。

3.2.2 父元素新增屬性overflow:hidden

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.2</title>
    <style>
        .outer {
            border: 3px solid black;
        }
        .div1 {
            width: 70px;
            height: 50px;
            background-color: green;
        }
        .div2 {
            width: 90px;
            height: 80px;
            background-color: yellow;
        }
        .div3 {
            width: 60px;
            height: 30px;
            background-color: red;
        }
        .fl {
            float: left;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="outer" style="overflow: hidden">
    <div class="div1 fl">div1</div>
    <div class="div2 fl">div2</div>
</div>
<div class="div3">div3</div>
</body>
</html>
4761597-36ae57712f59b92c.png
3.2.2

4. 浮動的應用場景

  1. 文字環繞
    這是浮動設計的初衷。
  2. 多列布局
    常用的多列布局,更推薦使用inline-block,當然要注意列之間的空隙。但浮動也經常用於左邊有一塊固定寬度,右邊根據父元素寬度自適應的情況。
  3. 選單欄
    同樣可以使用浮動或者inline-block實現。

參考

W3cSchool
CSS浮動float詳解
CSS清浮動處理(Clear與BFC)
CSS中的浮動和清除浮動,梳理一下!
CSS篇之2. 清除浮動,什麼時候需要清除浮動,清除浮動都有哪些方法
CSS複習筆記二:浮動和清除浮動
徹底理解浮動float CSS浮動詳解 清除浮動的方法
經驗分享:CSS浮動(float,clear)通俗講解
清除浮動float (:after方法)
偽類:after清除浮動的原理和方法

相關文章