CSS浮动及其清除浮动的5种方法

CSS定位机制

在理解浮动之前,我们先来看看css定位的机制。

在不设置浮动及定位的情况下,html文案是按照标准流的形式对页面进行排版。

标准流是根据元素所属类型(块级或行内级)进行从左往右,从上往下的排列。

块级元素:

  • 独占一行
  • 可以设置宽、高
  • 如果不设置宽度,宽度默认为容器的100%
  • 例如:div、h1~h6、ul、ol等

行内元素:

  • 与其他行内元素同行显示
  • 不可以设置宽高
  • 它的宽高就是其内容的宽高
  • 例如:span、a、b、i、u、em等d

所示效果如图:


Float(浮动)的基础知识

  • 会使元素向左或向右移动,只能左右,不能上下
  • 浮动元素碰到包含块或另一个浮动框,浮动停止
  • 浮动元素之后的元素讲围绕它,之前的元素不受影响
  • 浮动元素会脱离标准流
  • 设置:float:none / left / right

---

图文环绕

在这个例子中,有3个元素(p、img、p),我想要实现图文环绕的效果,于是对中间的img元素加了一个浮动样式。

img{
  float:left;
}

在设置了左浮动之后,可以看到img之前的p元素(蓝色框)并没有任何改变,img之后的p元素(红色框)挤压上来,将img元素包裹住了,形成了图文环绕的效果。

这也是就刚才基础知识所提到的浮动不会影响之前的元素,对之后元素有影响。

图文环绕的例子中, 在图片设置了浮动之后,它已经脱离了文档的标准流。在脱离标准流之后,下面的p元素随后挤压上来,占据了img本身的位置。

那么,为什么不是图片压着文字的样式,而是形成了图文环绕的效果呢?

这是因为文字有特殊的解析机制,它会找一个不挡住它的地方来显示。所以不给p元素设置浮动它也不会和img元素重叠。

对于文字的特效情况我们记着就好。

下面来看一个非图文环绕的例子。


盒子的浮动

这里我依然给出3个如下的盒子:

我们先来按照刚才设置图文环绕的方法,给中间的盒子2设置一个左浮动:

.box2{
  float:left
}

然后我们会发现盒子3居然不见了!但是这是依然在盒子3的文字依然在下方:

按照我们刚才设置图文环绕的效果,盒子3应该会挨着盒子2并排放置啊,怎么会出现文字依然在下方盒子却不见的情况?其实这里就是刚才提到的文字的特殊解析情况。

实际浮动中,上面的盒子设置了浮动后,它自身就脱离了标准流,下面的盒子就会顶上来,占据它之前的位置。所以就会呈现出一种盒子不见了情况。

在这个例子中,实际上盒子3并不是不见了,而是被盒子2给挡住了,现在我给盒子2设置一个右浮动,把下面的盒子3给显示出来。

.box2{
  float:righ;
}

在为盒子2设置了右浮动后,盒子3重新出现在我们的视野中。

那么要如何做到2个盒子(块级)并排显示呢?

其实很简单,我们只需要给2个盒子都同时设置一个浮动就好:

.box2,.box3{
    float:left;
}

在为2个盒子同时设置了左浮动之后,我们可以发现,现在盒子2并没有压住盒子3,两个盒子成一个并排排列的样子。

浮动固然好用,但是在网页开发中,使用了浮动还会导致一个高度塌陷的问题。


高度塌陷

什么是高度塌陷呢?

在实际的开发中,我们一般不会设置height来设置高度,一般使高度随者内容来改变。

所以高度塌陷父级盒子没有内容来填充时(设置浮动后盒子不占据位置),出现的一种高度缺失的情况。

举个例子来看,现在依然是刚才的3个盒子,我给他们设置了一个背景色为青色的父级盒子,为了效果展示,我还在父级盒子下创建了一个高度为100px的绿色盒子来演示高度塌陷问题。

<!--这是html代码-->
<body>
    <div class="parent">
        <div class="box1">我是盒子1</div>
        <div class="box2">我是盒子2</div>
        <div class="box3">我是盒子3</div>
    </div>
    <div class="demo"></div>
</body>
/*这是css代码*/
.parent {
            background-color: powderblue
        }
.demo   {
                      height:100px;
                      background-color:green;
                }

下面我先让盒子2与盒子3浮动起来:

.box2,.box3{
  float:left;
}

现在盒子2和盒子3的高度已经没有了,下面的绿色盒子挤压上来,父级盒子的高度由盒子1来撑开。

我再让盒子1左浮动:

.box1{
  float:left;
}

现在父级盒子的高度已经完全没有了,绿色盒子挤压上来。

父级盒子的高度塌陷是因为它内部的3个盒子都设置了浮动,脱离了标准流,它没有内容撑开当然就会丢失高度。

假设与父级盒子处于相邻关系的绿色盒子他本身有内容,在父级盒子高度丢失后,它挤压上去了。那么它自身的内容就会被父元素内部的3个盒子挡住。

为了解决这个问题,我们必须清除浮动,使得3个盒子既排列显示,父级元素又有高度。


清除浮动的5种方法

第一种:添加空元素

我现在给父级元素的后面新加一个空的div,并且设立一个类名clear。

<!--这是html代码-->
<body>
    <div class="parent">
        <div class="box1">我是盒子1</div>
        <div class="box2">我是盒子2</div>
        <div class="box3">我是盒子3</div>
    </div>
  <!--这是新增的代码-->
      <div class="clear"></div>
    <div class="demo"></div>
</body>

在刷新页面后,发现并没有什么变化,父级盒子的高度依然不在。

我们现在再给clear做一些样式设置。

.clear{
  clear:both;
}

现在我们的绿色盒子回到了3个盒子之下,但是原来的父盒子的背景颜色怎么不见了?

打开谷歌的审查元素来看看:

在审查元素中我们可以看到,实际上现在父盒子和我们用来清除浮动的clear都没有高度,那么是怎么做到让绿色盒子掉下来回到原来的位置呢?

其实就是这个clear:both在起作用。

clear有4个属性:

  • clear:none(不清除浮动)
  • clear:right(清除右侧的浮动)
  • clear:left(清除左侧的浮动)
  • clear:both(清除左右2侧的浮动)

简单的说来,为元素清除浮动就是不允许改元素的左侧或右侧有浮动元素的存在。

第二种:为父级元素设置overflow:hidden;

现在我把第一种方法注释了,绿色的盒子又挤压上去:

我要使用overflow:hidden把绿色盒子给放置回3个盒子的下方,使得他自身的内容不被浮动元素遮挡:

.parent{
        overflow:hidden;
}

在设置了hidden之后,我们的绿色盒子不但回归到3个盒子的下方,而且父级元素又重新回来了,打开审查元素来看,父级元素的高度就是内部盒子的高度。

为什么overflow:hidden就可以清除浮动,让父元素回归呢?

这个涉及到BFC的原理,这里不展开讨论。<s>因为我自己还没摸清楚</s>

简单的来说,就是我这个元素里面的子孙元素,不会影响到外部元素布局。

第三种:使用css3的伪类元素:after

我依然先把第二种方法注释掉,让绿色盒子又挤压上去

我给父级盒子添加一个类名clear

<!--这里是html代码-->
<body>
    <div class="parent clear">
        <div class="box1">我是盒子1</div>
        <div class="box2">我是盒子2</div>
        <div class="box3">我是盒子3</div>
    </div>
    <!-- <div class="clear"></div> -->
    <div class="demo"></div>
</body>

刷新网页后,并没有任何变化,我又来设置css代码

/*这里是css代码*/
  .clear:after {
            content: ".";
            height: 0;
            display: block;
            visibility: hidden;
            clear: both;
        }

再次刷新网页后,绿色盒子在3个盒子下方了,父级盒子也同时回来了

这个方法虽然好用,但是在低版本的IE上有兼容问题,所以我没还需要设置:

  .clear {
          zoom:1;
        }

第四种方法:给父元素设置高度

我注释了第三种方法,使绿色盒子挤压上来。然后我为父级元素设置了固定的高度:

   .parent {
            background-color: powderblue;
            height: 100px;
        } 

现在又达到了我们的目的,但是这个方法只有在涉及高度固定的时候才能使用。

第五种:父级元素一起浮动

我注释了第四种方法,使绿色盒子挤压上来,为父级元素设置css代码,然后刷新页面:

       .parent {
            background-color: powderblue;
            float: left;
        }

是不是没有任何变化呢?我们打开审查元素来看看

现在的父元素的宽和高都有了,是他内部3个盒子的宽和高。

这种方式会导致新的浮动问题,不建议使用

本文链接:

https://bahargul.xyz/index.php/archives/4/
1 + 3 =
快来做第一个评论的人吧~