首页 > 技术文章 > 浮动和清除浮动

tisikcci 2016-09-12 17:10 原文

之前学习了一些网页布局和浮动方面的知识,并亲自实践了一些,但有些地方还是模模糊糊不太清楚,有必要做一个彻底的总结,避免有些知识一知半解。

——————————————————————————————————————————————————————————————————————————碎碎念。

1.div内多个块元素的浮动关系:

假设一个大的div bigBox 中有三个块级盒子 div1 div2 div3

    <div class="bigBox">
        <div class="div1">第一个盒子</div>
        <div class="div2">第二个盒子</div>
        <div class="div3">第三个盒子</div>
    </div>

它们的样式为:

        .bigBox{
            width:500px;
            border: 1px solid #000;
        }
        .div1{
            background-color: yellow;
            /*float: left;*/
            width: 100px;
            height: 100px;
        }        
        .div2{
            background-color: blue;
            width: 120px;
            height: 120px;
        }        
        .div3{
            background-color: red;
            width: 140px;
            height: 140px;
        }

由于块级元素会单独占用一行,并且父元素会自动被撑开,可以得到:

现在,先让div2 浮动起来:给div2 加一个浮动

        .div2{
            background-color: blue;
            width: 120px;
            height: 120px;
            float: left;
        }        

这时,可以看到:

div3 跑到了原来div2 所在的位置,同时div3中的文字会环绕div2,我们通过给div3多加几个字使这个效果更加明显:

<div class="div3">第三个盒子多加几个字</div>

这时:

总结:当div内存在多个块级元素,如果其中一个块级元素发生了浮动,相对于紧跟在它后面的块级元素,这个元素脱离了普通流。后面的元素会占用浮动元素的位置,就像这个浮动元素不存在一样;

   但后面紧跟的这个元素中的文本会环绕在浮动元素的右、下方。

如果让div1向左浮动, div2向右浮动,会是什么效果?

发现相对于浮动元素后面的元素,浮动元素脱离了普通流,后面的元素会占用脱离普通流的浮动元素的位置。

总结:多个元素浮动时,浮动元素会脱离普通流,后面的块级元素会补充它们的位置。

如果块级元素内的所有块级元素div1 div2 div3都发生了左浮动:

浮动元素都脱离了普通流,这时外部父元素以为内部没有元素,看起来就像是一条线段。

如果这时候,想让父元素看起来像正常包裹浮动元素那样,就需要使用清除浮动技术。

 

2.清除浮动的几种方法:

a. 最直接的方式就是给浮动元素的父元素指定高度。

在上例中,既然三个内部块级元素都发生了浮动,给父元素设置一个高度:

        .bigBox{
            width:500px;
            height:150px;
            border: 1px solid #000;
        }

 

 

 b.让浮动元素的父元素也跟着浮动

不考虑元素浮动对外部整体布局的影响,可以让浮动元素的父元素也发生浮动,来达到清除浮动的影响。

 

        .bigBox{
            width:500px;
            border: 1px solid #000;
            float: left;
        }

这种做法的原理可以理解为:浮动元素都已经脱离了普通流,但它们都又处于另一种相同的流中,它们之间的关系就表现为父级浮动元素还是包裹这子浮动元素。

c. 在所有浮动子元素的后面添加一个空的块级元素,并设置空的块级元素样式为clear:both;来清除浮动。

假设这个时候html文档结构是这样的 

    <div class="bigBox">
        <div class="div1">第一个盒子</div>
        <div class="div2">第二个盒子</div>
        <div class="div3">第三个盒子多加几个字</div>
        <div class="div4"><!-- 空盒子 --></div>
    </div>

样式如下:

        .bigBox{
            width:500px;
            border: 1px solid #000;
        }
        .div1{
            background-color: yellow;
            float: left;
            width: 100px;
            height: 100px;
        }        
        .div2{
            background-color: blue;
            width: 120px;
            height: 120px;
            float: left;
        }        
        .div3{
            background-color: red;
            width: 140px;
            height: 140px;
            float: left;
        }

再设置这个后加入的空的块级元素的样式为:

        .div4{
            clear:both;
        }

就能有效的清除浮动:

下面来让我看看clear:both清除浮动的原理。

首先来看一个栗子:

    <div class="bigBox">
        <div class="div1">第一个盒子</div>
        <div class="div2">第二个盒子</div>
        <div class="div3">第三个盒子多加几个字</div>
    </div>
        .bigBox{
            width:500px;
            border: 1px solid #000;
        }
        .div1{
            background-color: yellow;
            width: 100px;
            height: 100px;
        }        
        .div2{
            background-color: blue;
            width: 120px;
            height: 120px;
            float: right;
        }        
        .div3{
            background-color: red;
            width: 140px;
            height: 140px;
            clear:both
        }

其余的元素都不浮动,只让div2像右浮动,在div3上使用clear:both 清除浮动。

可以看到在第三个div上利用clear:both清除浮动后,应该是触发了一种机制:它会计算出当前浮动元素的位置,并当作浮动元素在现在的位置是普通流位置。

由上面的栗子,当所有块级子元素都在浮动时,在这些浮动元素的后面加一个空的div设置样式为clear:both;后会认为这些浮动元素现在待的位置是普通流位置,空div只能呆在这些元素后面。这样就会将父级块级元素撑开。起到清除浮动的效果。

 

d. 在父元素上设置overflow:hidden;来清除浮动

原理:overflow:hidden;本身的是用来隐藏溢出的,之所有能够起到清除浮动,是因为我们默认没有给浮动元素的父元素设置高度,这时父级块元素的默认高度为:height:auto;当我们给父元素添加overflow:hidden;后,首先要计算父元素的高度才能确定怎么隐藏溢出,但由于设置了overflow:hidden而触发了BFC,使得height:auto的值包含了内部浮动元素的height;这时隐藏溢出就不会将浮动元素隐藏掉,而是正好将其包裹在里面。从而起到清除浮动的作用。

        .bigBox{
            width:500px;
            border: 1px solid #000;
            overflow: hidden;
        }

 

e. 利用给父元素添加自定义的伪类,清除浮动

 这种方法本质上讲,于在子元素末尾添加空的块级元素并设置其clear:both;是一个道理。

        .bigBox{
            width:500px;
            border: 1px solid #000;
        }
        .bigBox:after {
            clear: both;
            display: block;
            visibility: hidden; 
            height: 0;
            line-height: 0;
            content: "";
        }

 

推荐阅读