# CSS浮动float详解（三）：清除浮动方案

阅读前请看 [\[CSS\]CSS浮动float详解（二）：使用float](http://blog.csdn.net/xf616510229/article/details/53679353)

float虽然带来了很多好处，但是也带来了一些问题。

### 问题：

```
<!DOCTYPE html>
<html>
<head>
    <title>测试</title>
    <meta charset="utf-8">
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        li{
            float: left;
            list-style: none;
            height: 40px;
            width: 80px;
            background-color: orange;
            border: solid 1px #000;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="div1">
        <ul>
            <li>首页</li>
            <li>性感美女</li>
            <li>清纯妹子</li>
            <li>丝袜美眉</li>
            <li>非主流妹妹</li>
        </ul>
    </div>
    <div class="div2">
        <ul>
            <li>关于本站</li>
            <li>联系我们</li>
            <li>法律声明</li>
        </ul>
    </div>
</body>
</html>
```

我们像使用这段代码绘制两个导航条，但是结果却不尽人意。

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-996d0a676482993eac82669c0cb2efae5664074a%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTYzMDI0ODQw.png?alt=media)

我们发现，第二个div浮动到了第一个div后面。那么造成这个的原因是什么呢？

### 原因：

原因其实非常简单，上一篇我们讲到了使用float脱离文档流的几种表现，其中—— **脱离文档流表现四：子元素不会再撑出父容器的高** 和 **脱离文档流表现五：脱离文档流的元素，仍然是在父元素中浮动** 和是造成这种现象的主要原因。我们给两个div分别加边框，然后发现：

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-3633aa8460742b84db2873d716dd606a15635dfe%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTYzNjA5OTUx.png?alt=media)

因为父元素都没有高度，所以两个div处在了同一个位置，且又占用一行。第一组li先开始浮动，浮动到了左上角，第二组li也要在顶部浮动，由于前面有了第一组li，所以就依靠着第一组li浮动了。由此造成了这样的效果。

### 解决办法

知道了为什么造成这样的错误，解决起来就比较容易了。

#### 解决办法一，增加高度

原因是因为两个div处于同一个高度，影响了浮动的效果。所以，让第二组li在第一组li下面浮动，是最直接的方法，根据 **脱离文档流表现五：脱离文档流的元素，仍然是在父元素中浮动**，我们可以通过改变第一个div的高度来改变第二个div的位置，让元素浮动在第一组li的下方：

```html
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .div1{
            border: solid 5px #000;
            /*加个高度*/
            height: 50px;
        }
        .div2{
            border: solid 5px red;
        }
        li{
            float: left;
            list-style: none;
            height: 40px;
            width: 80px;
            background-color: orange;
            border: solid 1px #000;
            text-align: center;
        }
    </style>
```

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-6ad74f8d4afea5f8d9d99345e516e257229f7132%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTY0ODU5MDk5.png?alt=media)

这样，第二个div的位置就在第一组li的下方了，两组li就不会相互依靠了。

#### 解决办法二： `clear:both`

CSS提供了一个属性 `clear:both` 如下。

* none : 　允许两边都可以有浮动对象
* both : 　不允许有浮动对象
* left : 　不允许左边有浮动对象
* right : 　不允许右边有浮动对象

所以clear属性并不是清楚元素的浮动，而是用来指出不允许有浮动对象的边情况。

```html
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .div1{
            border: solid 5px #000;
        }
        .div2{
            border: solid 5px red;
            /*this........*/
            clear: both;
        }
        li{
            float: left;
            list-style: none;
            height: 40px;
            width: 80px;
            background-color: orange;
            border: solid 1px #000;
            text-align: center;
        }
    </style>
```

当我们给第二个div指定了 `clear:both` 属性后，我们发现，问题解决了。 **这是因为div2说，我的左边不可以有浮动的元素，浏览器就调整div2的位置，直到左边没有浮动的元素**。

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-87b33c6c3fa86dae11680ae658923cb515fffd95%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTcwODAzOTM1.png?alt=media)

#### 解决办法三：隔墙法和内墙法

隔墙法和内墙法，都是使用 `clear：both` 实现的，二者也有相似性。

**隔墙法**

为什么会出现隔墙法呢？狮子和猿猿们在使用 `clear:both` 时，发现一个很致命的问题，那就是因为这两个div都没有高，所以，要想给这个两个div设置间隔（margin），简直痴人说梦！！！还好，这点小挫折难不到狮子和猿猿们，隔墙法由此诞生。

既然无法设置margin，那么就在这两个div之间加入一个有高度的透明的div，这样就实现了margin的效果：

```html
<!DOCTYPE html>
<html>
<head>
    <title>测试</title>
    <meta charset="utf-8">
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .div0{
            border: solid 5px #000;
        }
        .div1{
            border: solid 5px red;
        }
        li{
            float: left;
            list-style: none;
            height: 40px;
            width: 80px;
            background-color: orange;
            border: solid 1px #000;
            text-align: center;
        }
        .spacing{
            height: 20px;
            border: solid 2px #000;
            clear: both;
        }
    </style>
</head>
<body>
    <div class="div0">
        <ul>
            <li>首页</li>
            <li>性感美女</li>
            <li>清纯妹子</li>
            <li>丝袜美眉</li>
            <li>非主流妹妹</li>
        </ul>
    </div>
    <div class="spacing">
        <!-- 我就是墙，用来当作边距 -->
    </div>
    <div class="div1">
        <ul>
            <li class="first">关于本站</li>
            <li>联系我们</li>
            <li>法律声明</li>
        </ul>
    </div>
</body>
</html>
```

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-efaa0ea89e194fe4095721f1c70616b7e5d8296f%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTcyNTE4MDIx.png?alt=media)

这样就成功的设置了两个div之间的边距。

**内墙法**

隔墙法用了一段时间以后，猿猿和狮子们又发现有问题了，这次问题比较棘手，那就是想要给两个div设置背景，但是两个div都没有高度，每次设置高度太麻烦了，如果能让div的高度再次包裹子元素就好了。

没有什么可以难得到狮子们和猿猿们的，经过长时间的编码，猿猿们发现了一条很有趣的现象，刚好可以解决这个问题。那就是内墙法，将隔墙法中的墙放入到div的内部，让我们来看一看代码：

```html
<!DOCTYPE html>
<html>
<head>
    <title>测试</title>
    <meta charset="utf-8">
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .div0{
            border: solid 5px #000;
        }
        .div1{
            border: solid 5px red;
        }
        li{
            float: left;
            list-style: none;
            height: 40px;
            width: 80px;
            background-color: orange;
            border: solid 1px #000;
            text-align: center;
        }
        .spacing{
            clear: both;
        }
    </style>
</head>
<body>
    <div class="div0">
        <ul>
            <li>首页</li>
            <li>性感美女</li>
            <li>清纯妹子</li>
            <li>丝袜美眉</li>
            <li>非主流妹妹</li>
        </ul>
        <div class="spacing">
            <!-- 墙在内部 -->
        </div>
    </div>
    <div class="div1">
        <ul>
            <li class="first">关于本站</li>
            <li>联系我们</li>
            <li>法律声明</li>
        </ul>
    </div>
</body>
</html>
```

注意边框，我们可以看到插入墙的div1的高度包裹了子元素，达到了目的：

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-faf6a77d51b3c26de80a0c322b5365a15d23aada%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTczMzA1MjU5.png?alt=media)

**为什么呢？**

还记得刚刚所说的那句话吗？ **这是因为diiv.spacing说，我的左边不可以有浮动的元素，浏览器就调整div2的位置，直到左边没有浮动的元素**，这样div.spacing就移动了第一组li的下方， **中间其实空出了li高度的空白**，这些空白只不过是被浮动的li遮挡住了而已，并不是被脱离文档流的li撑出的高。

#### 解决办法四： `overflow:hidden`

`overflow:hidden` 是溢出隐藏的作用，示例如下：

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-d9bef7d027f7b894cc34742fed92246e8ee255c7%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTc0ODIzMDMx.png?alt=media)

他有一个副作用：

```html
<!DOCTYPE html>
<html>
<head>
    <title>测试</title>
    <meta charset="utf-8">
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .div1{
            border: solid 5px #000;
            overflow: hidden;
        }
        .div2{
            border: solid 5px red;
            overflow: hidden;
        }
        li{
            float: left;
            list-style: none;
            height: 40px;
            width: 80px;
            background-color: orange;
            border: solid 1px #000;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="div1">
        <ul>
            <li>首页</li>
            <li>性感美女</li>
            <li>清纯妹子</li>
            <li>丝袜美眉</li>
            <li>非主流妹妹</li>
        </ul>
    </div>
    <div class="div2">
        <ul>
            <li>关于本站</li>
            <li>联系我们</li>
            <li>法律声明</li>
        </ul>
    </div>
</body>
</html>
```

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-8499645ca62d7c0015564bbdbae85c34b5941703%2FaHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE2MTgwMTM3OTQz.png?alt=media)

**给div1和div2加上 `overflow:hidden` 后，我们发现，div1和div2有高了！！！**

这样又很方便的设置背景了。

> 注意： IE6 不支持使用 `overflow:hidden` 清除浮动


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yangsx95.gitbook.io/notes/front-end/css/css-fu-dong-float-xiang-jie-san-qing-chu-fu-dong-fang-an.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
