深入理解CSS浮动、清除浮动:解锁你不知道的BFC

引言

当我们涉足网页布局的世界时,我们了解到一种叫做文字环绕布局的布局方式,浮动最开始的出现就是为了实现文字环绕布局。但我们在实际的运用过程中,我们常常会发现自己陷入了CSS浮动和清除浮动的陷阱,或者听到BFC(块级格式化上下文)的术语,但不太明白它们的含义,CSS布局是前端开发的核心,但也是令人困惑的部分之一。

你可能曾经遇到以下问题:

  • 为什么一些元素默认占据整行,而另一些可以并排显示?
  • 如何让文本环绕图片或其他元素?
  • 为什么有时候设置元素的宽高有效,有时候却不起作用?
  • 当使用浮动时,为什么元素位置错乱,或者父容器的高度无法正确计算?
  • 如何有效地清除浮动,避免不必要的问题?
  • BFC是什么,它与布局有何关系?

让我们一起来解开CSS布局的谜团,深入探讨浮动、清除浮动和BFC的概念吧~ 我将帮助你们来理解它们的工作原理,以及如何使用它们来实现各种网页布局~

第一章:块级、行内块和行内

在开始聊浮动之前,我们需要先简单一下探讨HTML和CSS中的三种基本元素类型:块级元素、行内块元素和行内元素。这些元素在网页布局中扮演着重要的角色,了解它们的特点和默认行为将有助于更好地掌握CSS布局,这也是我们接下来浮动布局内容中需要了解的基础内容,当然你如果知道的话就请跳过吧~

1.1 块级元素

块级元素是HTML文档中的主要构建块。它们的特点包括:

  1. 默认情况下,块级元素会占据一整行,每个块级元素都会从新的一行开始,相邻的块级元素会各自占据一行。
  2. 可以设置宽度(width)和高度(height),这使得它们非常适合用于构建页面的主要结构,如标题、段落、列表、div等。

块级元素的经典示例包括<div><p><h1><h6><ul><ol><li>等。

1.2 行内块元素

行内块元素融合了块级元素和行内元素的特点,具有以下特点:

  1. 可以在同一行上显示多个行内块元素,而不会自动换行。
  2. 与块级元素不同,行内块元素可以设置宽度和高度,允许更灵活的布局。

常见的行内块元素包括<img><span><a>等。

1.3 行内元素

行内元素是最基本的元素类型,其特点包括:

  1. 默认情况下,行内元素不会自动换行,它们会在同一行上显示。
  2. 不允许设置宽度和高度,宽度和高度通常由内容决定。

一些常见的行内元素包括<strong><em><a><span>等。

第二章:浮动和清除浮动

浮动是CSS布局中的重要概念,它允许元素脱离文档流,但也可能引发一些布局上的问题,让我们从浅到深来慢慢了解它吧~

2.1 什么是浮动?

浮动是CSS中的一种属性,即floaat,它通常用于将元素移动到其正常位置之外。元素可以浮动到左侧或右侧,并尝试将其放置在相邻元素的旁边。浮动通常用于实现以下效果:

  1. 文字环绕:将图像或其他元素浮动,使文本围绕在其周围。
  2. 元素同行显示:使块级元素在同一行上显示,而不是各自占据一整行。
  3. 允许元素设置宽度和高度:浮动的元素可以设置具体的宽度和高度,而不受默认的块级元素宽度自动占满父容器的限制。

2.2 如何使用浮动?

要使用浮动,只需为元素添加float属性并指定浮动方向(leftright)。例如:

css 复制代码
cssCopy code
.img-float {
  float: left;
}

上面的示例将元素img-float浮动到左侧,使文本围绕在其右侧。

2.2 清除浮动

在元素进行浮动后,会出现父元素没有高度的情况,下面的内容会直接弹到上面的div盒子下面,这是因为元素浮动后脱离了标准流,父盒子无法检测到子元素,于是高度变成了0,这是浮动经常出现的问题:

而浮动带来的问题还远不止这一个,除去这个常见的问题之外,我们来简单汇总一下:

  • 浮动的元素脱离了标准文档流,即脱标

  • 浮动的元素互相贴靠

  • 浮动的元素会产生字围效果

  • 浮动元素有收缩效果

    • 当浮动元素没有设置尺寸,会适应浮动元素内的子元素尺寸
  • 浮动的元素不占尺寸,标准流元素可以撑起父级块的尺寸,浮动元素不可以

  • 浮动元素设置margin_top不会发生塌陷现象

    • 给标准流元素设置margin-top时会发生margin塌陷

这就是为什么我们需要在使用浮动之后清除浮动带来的影响。

如何清除浮动

清除浮动本质

首先我们需要知道清除浮动的本质是清除浮动元素造成的影响:浮动的子标签无法撑开父盒子的高度

注意:

  • 如果父盒子本身有高度,则不需要清除浮动
  • 清除浮动之后,父级就会根据浮动的子盒子自动检测高度。
  • 父级有了高度,就不会影响下面的标准流了

清除浮动的六种方法

方法1:固定宽高

给浮动的元素添加父级div盒子,再给父级盒子设置高度

  • 缺点:高度固定死了,无法做到自适应,不宜维护,不灵活
  • 如果页面发生大小变化浮动元素挤到下一行,那么依然会出现塌陷
  • 应用:万年不变导航栏,固定栏;
方法2:一起浮动

子元素摆烂脱离文档流,父元素表示我也摆烂了,也添加一个浮动,这样父元素也脱离了文档流

  • 虽然实现了父元素出现高度,但是治标不治本
  • 缺点:这是一种将错就错的办法,后面的DIV盒子依然会塌陷到浮动元素下面没有解决问题

示例:

像这样为ul添加了浮动效果之后,ul确实计算了其中li的高度,从而使父容器拥有了高度,看似解决了问题,但是我们发现黑色的div被ul盖在了下面,说明这种方法并没有解决塌陷问题,所以是治标不治本。

方法3:额外标签法
ini 复制代码
在浮动的元素最后添加一个空div标签,里面设置style='clear:both',清除浮动效果;
  • 优点: 通俗易懂,书写方便
  • 缺点: 添加了无意义的标签,结构化较差
    注意: 要求这个新的空标签必须是块级元素。
css 复制代码
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <div class="clear"></div>
</ul>

示例:

然后我们就可以发现,ul的浮动被清除了!而且div也正常的出现在了ul下方,成功实现了清除浮动

方法4:父级添加双伪元素

那么针对于添加额外标签会导致多写一行无用标签,我们有没有其它方法能够解决这一问题呢?当然是有的,还记得伪元素吗?它来了: :after 方式是额外标签法的升级版。我们给父元素添加伪元素:

  • 优点:没有增加标签,却相当于添加了标签,结构更加简单
  • 缺点:需要照顾低版本浏览器,如果考虑兼容性的话,我们需要多写一行兼容性代码
  • 这也是我们使用频率第二高的清除浮动方式
css 复制代码
.clearfix:after{
        content: "";
        display: block;
        height: 0px;
        clear: both;
        visibility: hidden;
    }
/*IE6\7 兼容*/
.clearfix{
    *zoom: 1;
}

具体效果和添加一个div类似,只是变成了after,我就不贴重复的图片了。

方法5.父盒子添加overflow: hidden;触发BFC

方法简单,常用,没错这就是使用率第一高的清除浮动方法,但是你发现出现了一个你不认识的东西:BFC,而且BFC还有很多种方法可以创建,那就让我们展开来认识认识它吧~

第三章:BFC(块级格式化上下文)

BFC Block fomatting context(块级格式化上下文),是一个独立的渲染区域,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。

简单来说:bfc是创建了一个单独的区域,容器外的元素绝对无法影响到bfc内部的元素

3.1 创建BFC

我们先来学习一下如何才能够创建BFC(块级格式化上下文)。了解如何触发元素的BFC属性是非常重要的,因为它将影响到布局的实现。以下是一些常用的属性和方法,可以用来创建BFC:

  1. float: leftfloat: right:使用浮动属性可以触发元素的BFC,这在创建多列布局或文字环绕效果时非常有用。
css 复制代码
.element {
  float: left; /* 创建BFC */
}
  1. position: absoluteposition: fixed:绝对定位的元素会触发BFC,这对于创建一些特定布局效果非常有帮助。
css 复制代码
.element {
  position: absolute; /* 创建BFC */
}
  1. display: inline-block:行内块元素也可以创建BFC,这在一些垂直对齐和布局方面非常有用。
css 复制代码
.element {
  display: inline-block; /* 创建BFC */
}
  1. display: table-cell...:表格单元格元素也会触发BFC,display中大部分table开头的都可以创建BFC,这对于我们创建表格布局非常有用。
css 复制代码
.element {
  display: table-cell; /* 创建BFC */
}
  1. overflow: hiddenoverflow: autooverflow: overlayoverflow: scroll:设置元素的溢出属性为这些值之一可以创建BFC,这对于解决外边距合并等问题非常有用。
css 复制代码
.element {
  overflow: hidden; /* 创建BFC */
}
  1. 弹性盒子(Flexbox):使用Flexbox布局模型的元素会自动创建BFC,这对于构建灵活的布局非常有帮助。
css 复制代码
.container {
  display: flex; /* 创建BFC */
}

通过应用这些属性和方法,我们就可以在需要的地方触发BFC,以更好地控制页面布局和解决布局问题。

3.2 BFC的特点

BFC(块级格式化上下文)具有一些独特的特点,这些特点使其在布局和解决CSS问题时非常有用。下面是BFC的主要特点:

  1. BFC容器在计算高度时,会将浮动元素的高度也计算在内。这意味着当一个元素包含浮动元素时,它的高度会自动适应浮动元素的高度,从而防止父容器出现塌陷或高度塌陷问题。这一特性对于创建多列布局等情况非常重要。

  2. BFC可以解决外边距重叠问题,确保外边距按预期工作。外边距重叠是指元素的外边距合并在一起的情况。当两个元素在一起且外边距重叠时,BFC可以阻止它们的外边距合并。如果不是BFC的话外边距是会重叠的。例如下面这两个

css 复制代码
.wrap{
      width: 100%;
      height: 600px;
      background: red;
      margin-top: 100px;
      /* overflow: auto; */
    }
.box{
      width: 100%;
      height: 300px;
      background: blue;
      margin-top: 50px;
    }

就像图中的效果一样,如果.wrap.box像这样设置margin-top你会发现他们的外边距重合了,而不是我们希望的.box应该在更下方一些,它们的外边距将合并为一个100px的外边距。但如果.swap是一个BFC容器,那么就会达到我们想要的结果,它们的外边距将按照各自的值出现:

  1. BFC元素的边界不会与浮动元素重叠,从而实现更精确的控制。在BFC中,元素的边界会清除浮动元素,确保它们不会重叠。这对于创建复杂的布局效果和避免不必要的干扰非常有用。
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <style>
        .container {
            width: 300px;
            border: 1px solid #000;
            overflow: hidden; 
        }

        .float-box {
            width: 100px;
            height: 100px;
            float: left;
            background-color: lightblue;
            margin-right: 20px;
        }

        .content {
            width: 100px;
            height: 100px;
            background-color: lightgreen;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="float-box"></div>
        <div class="content">This is some content.</div>
    </div>
</body>
</html>

如果我们.container中没有overflow: hidden属性的话我们会出现这种情况:

因为浮动的文字环绕效果,.content虽然被float-box重叠盖住了,但是它的文字被挤了出来,但是我们把.container设置为了BFC容器之后我们会发现:

这个小问题被解决了~

第四章:BFC的实际应用

我们刚刚全面讲解了一下BFC(块级格式化上下文)的创建以及它的一些特性,而BFC不仅仅是一个理论概念,它在前端开发中具有强大的实际作用。我我来向你分享几种有关BFC的实际应用实现。

解决外边距合并问题

外边距合并(margin collapsing)是一个常见的布局问题,我们在讲BFC特性的时候已经介绍了一遍,所以现在你可以自己尝试一遍,这个示例几乎是一样的,你来想一想它会是什么样子的吧:

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      width: 200px;
      border: 1px solid #000;
      overflow: auto; /* 创建BFC */
    }
    .box {
      margin: 20px;
      background-color: #f0f0f0;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box">Box 1</div>
    <div class="box">Box 2</div>
  </div>
</body>
</html>

实现多列布局

BFC还可以帮助我们实现多列布局,使文本和元素像报纸或杂志一样排列在多列中。这是一个示例,大家可以进行实验:

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      column-count: 3;
    }
  </style>
</head>
<body>
  <div class="container">
    <p>Column 1</p>
    <p>Column 2</p>
    <p>Column 3</p>
    <!-- 这里可以添加更多内容 -->
  </div>
</body>
</html>

通过将column-count属性应用于BFC容器,我们可以轻松地创建多列布局,而不必手动分割内容或使用复杂的CSS。

创建分隔元素

有时我们需要在页面中创建分隔元素,例如在导航和内容之间添加分隔线。BFC可以帮助我们轻松实现这个效果:

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      border: 1px solid #000;
    }
    .separator {
      clear: both; /* 创建BFC */
      border-top: 1px solid #000;
    }
  </style>
</head>
<body>
  <div class="container">
    <p>Content goes here</p>
    <div class="separator"></div>
    <p>More content here</p>
  </div>
</body>
</html>

通过在分隔元素上创建BFC,我们可以确保分隔线不会重叠到内容中,而是清晰地将导航和内容分开。

实现复杂的浮动效果

最后,BFC还可以帮助我们实现复杂的浮动效果,例如文字环绕和图片排列。这个示例,大家也可以进行实验:

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      width: 300px;
      border: 1px solid #000;
    }
    .float-left {
      float: left;
      width: 100px;
      height: 100px;
      background-color: #f0f0f0;
    }
    .text {
      /* 创建BFC,防止文字环绕 */
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="float-left"></div>
    <p class="text">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit
    </p> 
   </div> 
</body>
</html>

总结

浮动是CSS布局中的一个重要概念,虽然在开发中很常见但是我们也常常会发现自己陷入了CSS浮动和清除浮动的陷阱,所以我们在写浮动的时候一定要注意清除浮动。而BFC也是CSS布局中的一个重要概念,它可以解决各种布局问题,包括我们写浮动时出现的问题和外边距重叠等等。通过创建和使用BFC,我们可以更好地控制和优化页面布局,确保页面的外观和行为符合我们的设计意图。

如果你想了解更多这类文章,点赞关注作者更新更多后续~

相关推荐
五点六六六4 分钟前
cli中的@/components/utils是怎么被替换的成对应的alias的?
前端·前端框架·node.js
欧阳天羲22 分钟前
Angular 框架下 AI 驱动的企业级大前端应用开
前端·人工智能·angular.js
啃火龙果的兔子25 分钟前
React 手动实现页面锚点导航
前端·javascript·react.js
香蕉可乐荷包蛋35 分钟前
Vue 2 和 Vue 3 中,组件的封装、二次开发和优化
前端·javascript·vue.js
开开心心就好1 小时前
电脑桌面整理工具,一键自动分类
运维·服务器·前端·智能手机·pdf·bash·symfony
江城开朗的豌豆1 小时前
局域网时间同步终极方案(无需互联网)
前端
你这-坏孩子2 小时前
更改elementui 图标 css content
前端·css·elementui
周尛先森2 小时前
Next.js 应用变慢的 8 个原因及解决办法
前端
扶光与望舒呀2 小时前
HTML 标题标签
前端·css·html
恋猫de小郭3 小时前
Flutter Web 的发展历程:Dart、Flutter 与 WasmGC
android·前端·flutter