五、深入理解清除浮动

一、浮动的本质

浮动的核心只有一句话:浮动元素会脱离标准文档流向左/向右浮动,直到碰到父元素或者另一个浮动元素。

二、浮动的特征

2.1浮动会脱离文档

也就是说浮动会脱离原来文档流所在的层级,进入更高的层级。它在更高的层级上会忽略标准文档流中的元素,向左向右直到碰到父元素或者另一个浮动元素。同时在标准文档流中,剩余的元素也会当做该浮动元素不存在。
示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            border: 5px solid red;
        }
        .box1 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            /*float: right;*/
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }

    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
    <!--<div style="clear: left"></div>-->
</div>
</body>
</html>

运行结果:


image.png

分析:在以上示例中,第一个和第二个元素向右浮动,第三个元素未设置浮动。这时候第一个元素碰到边框元素停下,第二个元素碰到第一个元素停下,第三个元素仍然在标准文档流中,并且认为第一个第二个元素的位置为空。

2.2浮动可以内联排列

示例代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            border: 5px solid red;
        }
        .box1 {
            float: right;
            width: 100px;
            height: 200px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }

    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
    <!--<div style="clear: left"></div>-->
</div>
</body>
</html>

运行结果如下:


image.png

image.png

image.png

分析:当放大或者缩小浏览器的框会有不同的显示效果。这是因为浮动会向左向右浮动,直到碰到另外一个浮动元素为止。这是浮动可以内联排列的特征。这个特征介于inline和block之间,类似于inline-block的效果。

2.3浮动会导致父元素坍塌

出现这个情况的原因是浮动元素会脱离标准文档流,并不占据标准文档流的位置,而标准文档流中的其他元素会占据浮动元素的位置,当没有其他元素的时候,父元素就不能被撑开,所以就没有了高度。
示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            border: 5px solid red;
        }
        .box1 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
    <!--<div style="clear: left"></div>-->
</div>
</body>
</html>

运行结果:


image.png

分析:从运行结果可以看出,父元素坍塌了。

三、深入理解clear属性

clear属性不允许被清除浮动的元素所在行的左边/右边有浮动元素(从浏览器界面上来看),底层原理是在被清除浮动的元素上边或者下边添加足够的清除空间。
同时,我们是在通过在别的元素上清除浮动来实现撑开高度的,而不是在浮动元素上。

3.1在浮动元素上加上清除浮动的属性

示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            border: 5px solid red;
        }
        .box1 {
            float: right;
            width: 100px;
            height: 200px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            float: right;
            width: 100px;
            height: 100px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3" style="clear: both">3</div>
    <!--<div style="clear: both"></div>-->
</div>
</body>
</html>

运行结果:


image.png

结果分析:首先,可以观察到父元素还是坍塌了;其次,在浏览器的显示界面上,左边明明还有很大的空间,但是3号元素并没有靠着2号元素去排列,而是排列在了下面。导致这样的结果出现的原因是:虽然在3号标签上加了清除浮动,但是3号元素同时设置了浮动属性,导致了这个清除浮动效果在浮动元素的那个层级生生效了,并没有在标准文档流里面生效。

3.2综合示例

示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            border: 5px solid red;
        }
        .box1 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <div class="box3">1</div>
    <div class="box1">2</div>
    <div class="box1">3</div>
    <div class="box2" style="clear: both">4</div>
    <div class="box3">5</div>
    <div class="box3" style="clear: both">6</div>

</div>
</body>
</html>

运行结果:


image.png

结果分析:1号框是正常的,没有浮动;2号框设置向右浮动,但是它并不跟1号框同行,相当于在2号框的上外边画一条横线,跟上面隔离开,然后在剩下的界面上开始浮动;3号框设置向右浮动,就是一个普通的浮动;4号框设置向右浮动和清除浮动,不跟2、3号同行,相当于在上面画一条线,从下面开始浮动;5号框是一个普通框,可以看到它补充了2、3、4号框的位置;6号框设置了清除浮动,可以看到它相当于在4号框下面画了一条线,然后补充进在标准文档流的位置。同时,可以观察到父元素的框并没有垮掉,这是因为有最后的1、5、6号元素。当把6号框注释掉的时候,父框的高度只到5号框那个地方。当注释掉5、6号框的时候,父框高度只到1号框那个地方,当这三个框都注释掉的时候,父元素坍塌了。
上面这个示例包含了四种情况:1、什么都不设置(1、5);2、只设置浮动(2、3);3、只设置清除浮动(6);4、同时设置浮动和清除浮动(4)。

四、解决父级边框塌陷的方法

  • 浮动元素后面加空div
  • 设置父元素的高度
  • 父级添加overflow属性
  • 父级添加伪类after

4.1在标准文档流中的剩余元素上清除浮动实现撑开高度

示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .father {
            border: 5px solid red;
        }
        /*.father:after {*/
            /*content: "";*/
            /*display: block;*/
            /*clear: both;*/
        /*}*/
        .box1 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="father">
    <!--<div class="box3">1</div>-->
    <div class="box1">2</div>
    <div class="box1">3</div>
    <div style="clear: both"></div>
    <!--<div class="box2" style="clear: both">4</div>-->
    <!--<div class="box3">5</div>-->
    <!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>

运行结果:


image.png

分析:在上面这个例子中,是通过给一个空元素加上清除浮动属性实现了高度撑开。
注:这种方法需要你在浮动元素后面加上一个空div,这样会造成元素的浪费;同时当结构是ul-li元素的时候,因为ul标签里面只能有li标签,你不可能在ul标签里面加入div空元素。

4.2设置父元素的高度

示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            height:50px;
            border: 5px solid red;
        }
        .box1 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <!--<div class="box3">1</div>-->
    <div class="box1">2</div>
    <div class="box1">3</div>
    <!--<div class="box2" style="clear: both">4</div>-->
    <!--<div class="box3">5</div>-->
    <!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>

运行结果:


image.png

分析:缺点从结果里面可以看得清清楚楚:就是不灵活。

4.3父级添加overflow属性

示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box-wrapper {
            border: 5px solid red;
            overflow: hidden;
        }
        .box1 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="box-wrapper">
    <!--<div class="box3">1</div>-->
    <div class="box1">2</div>
    <div class="box1">3</div>
    <!--<div class="box2" style="clear: both">4</div>-->
    <!--<div class="box3">5</div>-->
    <!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>

运行结果:


image.png

overflow属性详解

image.png

上面的示例就是设置的hidden,所以没有浮动元素里面的数字的下半部分被修剪了。当把overflow的值设置为scroll的时候,结果如下:
image.png

当把overflow的值设为auto的时候,结果如下:
image.png

两者对比可以发现,当为scroll的时候,右侧出现了滚动条,虽然下方没有出现,但是如果说你长度也超出了,是会出现滚动条的;但是值为auto的时候,下方没有滚动条。
同时,要特别注意,这种方法在下拉列表框的情况下不能使用。原因是overflow本来就是为了解决高度溢出的问题的,而你下拉列表出来的时候肯定是比你自身高度高的,会把下拉列表隐藏掉。

4.4父级加伪类after

示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .father {
            border: 5px solid red;
        }
        .father:after {
            content: "";
            display: block;
            clear: both;
        }
        .box1 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box2 {
            float: right;
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
        .box3 {
            width: 50px;
            height: 50px;
            margin: 20px;
            background-color: green;
            font-size: 80px;
        }
    </style>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body>
<div class="father">
    <!--<div class="box3">1</div>-->
    <div class="box1">2</div>
    <div class="box1">3</div>
    <!--<div style="clear: both"></div>-->
    <!--<div class="box2" style="clear: both">4</div>-->
    <!--<div class="box3">5</div>-->
    <!--<div class="box3" style="clear: both">6</div>-->
</div>
</body>
</html>

运行结果:


image.png

分析:这个方式其实跟第一个方式有点像,但是这个操作方式是一个类选择器,比第一个好使,所以推荐用这个去做。

4.5防止父级边框塌陷方法总结

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,816评论 1 92
  • 1. 前言 前端圈有个“梗”:在面试时,问个css的position属性能刷掉一半人,其中不乏工作四五年的同学。在...
    YjWorld阅读 4,559评论 5 15
  • 主要内容: 浮动的介绍、清除浮动、各种定位、BFC以及外边距合并的介绍。 浮动 什么是浮动元素 浮动元素是floa...
    苦瓜_6阅读 596评论 0 0
  • 一、文档流的概念指什么?有哪种方式可以让元素脱离文档流? 1、文档流指的是元素在排列布局中所占用的位置,具体的说是...
    鸿鹄飞天阅读 807评论 0 0
  • “我在这里欢笑,我在这里哭泣,我在这里活着,也在这死去”!一首《北京北京》唱出了多少人对生活的无奈。 虽然很多人都...
    泠泠柒阅读 310评论 5 1