css浮动拾遗:清除浮动到BFC

684 阅读5分钟

1.引言

css浮动是网页中重要的布局方式,使得界面美观化,其中最常用到浮动的就是图文排列的效果。如下图; e70537639bbb8356f482449cd1a5f14.png 想要实现所示布局,应该如何设置呢?

首先需知道文档流的概念:文档流就是是HTML页面中元素排列的默认方式(从左到右,从上到下),HTML标签分为块级元素,行内元素和行内块元素(关乎文档流)。

  1. 块级元素:独占一行,可以设置其宽高,常见的块级元素有<div><p><h><ul><ol><li>
  2. 行内元素:占不了一行,不可以设置它的宽高,宽高为其内容的宽高,常见的行内元素包括<span><a><img><strong><em> 等。
  3. 行内块元素:可以在同一行显示,而且可以设置其宽高,融合了块级和行内元素的特点。

2.浮动

浮动是css中的一种属性,即float,就是将元素移动到其正常位置之外,可以往左或往右浮动,最常用到的就是文字环绕效果,使得块级元素在同一行显示。如下; 171487e1e9ca8c3e6c25a0a108ca7bb.png 由于p标签是块级元素,所以正常的排列应该是如上图所示。 35811775671d90c6ffaa5615395ec88.png 如图,如果给img标签添加float并且指定方向(leftright)即可将该元素浮动,达到如图文字环绕效果。

3.清除浮动

浮动虽然好用,但是也有一些负面影响,如下 image.png 想要将1,2,3并排在一列,则紫色方块全部显示在其下面。容易想到将1,2,3并排在一列只需在li元素上添加浮动属性float:left即可。 image.png image.png image.png 但是如图,给li元素添加完浮动后,紫色方块明明有60px高,但是却只显示了一点点,通过浏览器检查发现紫色方块部分被挡住,而且发现ul容器高度变成了0,这是因为浮动元素的高度不计算在父容器的高度之内,导致父容器的后续容器布局和该浮动元素重叠。也就是浮动的元素会脱离其文档流(也称脱标)。注意:文字不会被盖住,也就是文字环绕效果。

但是如果就是想要紫色方块显示出来呢?那就需要清除浮动

清除浮动的本质:就是浮动的元素会脱离文档流,就无法撑开其父容器的高度(父容器未设置高度情况下下),而后面的元素就会挤上去造成重叠。所以清除浮动就是要让其父容器有高度。

如何清除浮动呢?

  1. 直接设置父容器的高度,给父容器设置一个高度,这样它就有了它的空间,后面的元素就挤不上来了。 image.png 但是父级容器不一定每次都知道宽高,还得计算高度,不推荐使用。

  2. 在浮动元素最末尾添加子容器,在子容器上添加clear:both用来清除浮动。 image.png 这个看上去比上一个稍微优雅一点。但是这个html里面每次都要多了一个空的div

  3. 给后面被影响的元素清除浮动同样可以。但是不建议,哪个标签的效果应该哪个设置,更符合语义化。 image.png

  4. 伪元素

xxx::after {
      content: "";
      clear: both;
      display: block;
    }

这个就不需要添加空的div,结构更加简单,也就相当于在父容器最后使用清除浮动。这个就比较优雅了,使用率也较高,如图所示。 image.png

  1. 给父盒子添加overflow: auto,触发 BFC 来清除浮动,方法简单,非常优雅,最为常用。 image.png

4.BFC

BFC,翻译成 Block Formatting Context(块级格式化上下文),一个拥有隔离空间的容器,是一个独立的渲染区域,可以用来用来解决父子容器 margin 重叠的问题以及解决浮动带来的影响。

4.1 创建BFC的方法

给父容器添加以下属性:

  1. overflow: hidden || auto || overlay || scroll
  2. 定位:position: absolute || fixed
  3. display: inline-xxx || flex || grid
  4. display: table || table-xxx
  5. 浮动: float: left || right

4.2 BFC的特征

观察以下代码,想象其结果;

<style>
    * {
      margin: 0;
      padding: 0;
    }

    .parent {
      width: 100vw;
      height: 400px;
      background-color: red;
      margin-top: 100px;
    }

    .child {
      width: 100vw;
      height: 200px;
      background-color: green;
      margin-top: 50px;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child"></div>
  </div>
</body>

正常思维下显示应该为: image.png 而实际显示: image.png 也就是说红色方框的margin-top:100px把绿色方框的margin-top:100px覆盖了,在CSS中,相邻元素间的垂直外边距(margin-top 和 margin-bottom)会发生合并,而水平外边距(margin-left 和 margin-right)则不会。同样,父子元素之间的垂直外边距也会合并,但水平外边距不会。

为了解决以上问题,使得更加符合正常情况,就可以将该容器设置成BFC容器,在父容器中添加overflow:auto 等可以触发BFC的属性,即可达到效果。 image.png BFC特征可以概括为:

  1. bfc 容器是让处于 bfc 内部的元素与外部的元素相互隔离,使外部元素的定位不会相互影响
  2. 解决外边距重叠问题
  3. bfc 容器在计算高度时,会将浮动元素的高度也计算在内

五. 小结

  • 浮动(Float):
  1. 浮动是一种使元素脱离正常文档流的布局方式,可以左右浮动。
  2. 浮动元素会被移出正常的文档流,但不会影响文字的排列,文字会环绕浮动元素。
  3. 浮动常用于实现图文混排等布局效果。
  • 清除浮动:
  1. 浮动元素会导致父容器高度塌陷,影响后续布局。
  2. 清除浮动的目的是为了让父容器能够包含浮动元素,避免高度塌陷。
  3. 清除浮动的方法有:设置父容器高度、添加空子元素并清除浮动、伪元素清除浮动(clear:both)、触发BFC (overflow:auto等)。
  • BFC(块级格式化上下文):
  1. BFC是一个独立的布局单元,内部的元素不会影响外部元素。
  2. 创建BFC的方法有:设置overflow属性、定位、显示类型等。
  3. BFC的特征包括:隔离内部元素与外部元素、解决外边距重叠问题、计算高度时包含浮动元素等。