> For the complete documentation index, see [llms.txt](https://yangsx95.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yangsx95.gitbook.io/notes/front-end/css/css-fu-dong-float-xiang-jie-san-qing-chu-fu-dong-fang-an.md).

# 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>
```

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

![](/files/Q0nhISyXYGMtumAnhPCb)

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

### 原因：

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

![](/files/9wuGVUjImdlQeEWuIR22)

因为父元素都没有高度，所以两个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>
```

![](/files/5nQU9cbDlF4gGi4z9kLV)

这样，第二个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的位置，直到左边没有浮动的元素**。

![](/files/3mwcWZVRbg4gat6yE4Tv)

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

隔墙法和内墙法，都是使用 `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>
```

![](/files/x0fy9pJ5XXQFtaouptWf)

这样就成功的设置了两个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的高度包裹了子元素，达到了目的：

![](/files/cBKQCa0Q0m9D2EmNqSdr)

**为什么呢？**

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

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

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

![](/files/6Tq5RreAjDnmAo7sHcRR)

他有一个副作用：

```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>
```

![](/files/U7IoNDoqz4Hq5Yc4remf)

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

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

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