0

0

深入浅析CSS 布局和 BFC

青灯夜游

青灯夜游

发布时间:2020-10-12 17:49:19

|

2434人浏览过

|

来源于segmentfault

转载

深入浅析CSS 布局和 BFC

CSS布局中有一些概念,一旦你理解了它们,就能真正提高你的 CSS 布局能力。本文是关于块格式化上下文(BFC)的。你可能从未听说过这个术语,但是如果你曾经用CSS做过布局,你可能知道它是什么,理解什么是 BFC,怎么工作以及如何创建 BFC 非常有用,这些可以帮助你理解CSS中的布局是如何工作的。

(推荐教程:CSS教程

在本文中,通过熟悉的示例来解释什么是 BFC。然后说明 display 的一个新值,只有当你理解了什么是 BFC 以及为什么需要它时,它才有意义。

什么是 BFC

在一个Web页面的CSS渲染中,块级格式化上下文 (Block Fromatting Context)是按照块级盒子布局的。W3C对BFC的定义如下:

立即学习前端免费学习笔记(深入)”;

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

BFC是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个 BFC 中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

块格式化上下文(BFC)的行为通过一个简单的float示例很容易理解。在下面的示例中,我有一个框,其中包含向左浮动的图像和一些文本。如果我们有足够多的文本,它会环绕浮动的图像和边框,然后环绕整个区域。

// html
<p class="outer">
  <p class="float">I am a floated element.</p>
  I am text inside the outer box.
</p>

// css
.outer {
  border: 5px dotted rgb(214,129,137);
  border-radius: 5px;
  width: 450px;
  padding: 10px;
  margin-bottom: 40px;
}

.float {
  padding: 10px;
  border: 5px solid rgba(214,129,137,.4);
  border-radius: 5px;
  background-color: rgba(233,78,119,.4);
  color: #fff;
  float: left;  
  width: 200px;
  margin: 0 20px 0 0;
}

1.png

如果我删除了一些文本,那么就没有足够的内容来包围图像,而且由于浮动被从文档流中脱离,所以边框会上升,并在图像下方,直到文本的高度。

2.png

这是因为当我们浮动一个元素时,文本所在的框的宽度保持不变,为给浮动元素腾出空间而缩短的是文本的行框。这就是为什么背景和边框会出现在浮动后面的原因。

我们通常有两种方法来解决这个布局问题。一种方法是使用 clearfix hack,它的作用是在文本和图像下面插入一个元素,并将其设置为 clear:both。另一种方法是使用 overflow 属性,其值不是缺省值 visible

.outer {
  overflow: auto;
}

3.png

查看演示:https://codepen.io/anon/embed/XzYWZj?height=500&theme-id=0&slug-hash=XzYWZj&user=&default-tab=

overflow 以这种方式工作的原因是,使用 visible 的初值以外的任何值都会创建一个块格式化上下文,而 BFC 的一个特性是它包含浮动。

BFC 是布局中的一个迷你布局

你可以将 BFC 看作是页面内的一个迷你布局。一旦一个元素创建了一个 BFC,它就包含了所有的内容。正如我们所看到的,这包括浮动的元素,它们不再从盒子底部伸出来。BFC 还会导致一些其他有用的行为。

BFC 可以防止 margin 折叠

了解边距合并是另一个被低估的 CSS 技能。在下一个示例中,假设有一个背景颜色为灰色的 p

这个 p 包含两个标签 p。外部 p 元素的 margin-bottom 为 40 像素,标签 p 的顶部和底部 margin 都是 20 像素。

// html
<p class="outer">
  <p>I am paragraph one and I have a margin top and bottom of 20px;</p>
  <p>I am paragraph one and I have a margin top and bottom of 20px;</p>
</p>
  
// css
.outer {
   background-color: #ccc;
  margin: 0 0 40px 0;
}

p {
  padding: 0;
  margin: 20px 0 20px 0;
  background-color: rgb(233,78,119);
  color: #fff;
}

因为 p 元素的 margin 和外部 p 上的 margin 之间没有任何东西,所以两个会折叠,因此 p 最终与 p 的顶部和底部齐平。 我们在 p 的上方和下方看不到任何灰色。

4.png

在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。折叠的结果按照如下规则计算:

  1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  3. 两个外边距一正一负时,折叠结果是两者的相加的和。

产生折叠的必备条件:margin必须是邻接的!

如果我们把盒子设为 BFC,它现在包含了标签 p 和它们的边距,这样它们就不会折叠,我们可以看到边距后面容器的灰色背景。

.outer {
  background-color: #ccc;
  margin: 0 0 40px 0;
  overflow: auto;
}

5.png

查看演示:https://codepen.io/anon/embed/YEvzRv?height=500&theme-id=0&slug-hash=YEvzRv&user=&default-tab=

再一次,BFC 的工作是把东西装在盒子里,防止它们从盒子里跑出来。

BFC 可以阻止元素被浮动元素覆盖

你将熟悉 BFC 的这种行为,因为使用浮动的任何列类型布局都是这样工作的。如果一个项目创建了一个 BFC,那么该项目将不会包裹任何浮动元素。在下面的例子中,有如下 html 结构:

元典智库
元典智库

元典智库:智能开放的法律搜索引擎

下载
<p class="outer">
  <p class="float">I am a floated element.</p>
  <p class="text">I am text</p>
</p>

带有 float 类的项被向左浮动,因此 p 中的文本在它环绕 float 之后。

6.png

我可以通过将包裹文本的 p 设置为 BFC 来防止这种包裹行为。

.text {
  overflow: auto;
}

7.png

这实际上是我们创建具有多个列的浮动布局的方法。浮动项还为该项创建了一个 BFC,因此,如果右边的列比左边的列高,那么我们的列就不会相互环绕。

查看演示:https://codepen.io/anon/embed/qVKEpJ?height=500&theme-id=0&slug-hash=qVKEpJ&user=&default-tab=

在多列布局中使用 BFC

如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。

例如:

<p class="container">
    <p class="column">column 1</p>
    <p class="column">column 2</p>
    <p class="column">column 3</p>
</p>

对应的CSS:

.column {
    width: 31.33%;
    background-color: green;
    float: left;
    margin: 0 1%;
}
.column:last-child {
  float: none;
}

未创建 BFC 之前:

8.png

添加以下样式创建一个 BFC:

.column:last-child {
  float: none;
  overflow: hidden; 
}

9.png

现在尽管盒子的宽度稍有改变,但布局不会打破。当然,对多列布局来说这不一定是个好办法,但能避免最后一列下掉。这个问题上弹性盒或许是个更好的解决方案,但这个办法可以用来说明元素在这些环境下的行为。

还有什么能创建 BFC?

除了使用 overflow 创建 BFC 外,其他一些 CSS 属性还创建 BFC。正如我们所看到的,浮动元素创建了 BFC。你的浮动项将包含它里面的任何东西。

使用以下方式都能创建 BFC

  • float 的值不是 none。
  • position 的值不是 static 或者 relative。
  • display 的值是 inline-block、table-cell、flex、table-caption 或者inline-flex
  • overflow 的值不是 visible

创建 BFC 的新方式

使用overflow或其他的方法创建BFC时会有两个问题。首先,这些方法本身是有自身的设计目的,所以在使用它们创建BFC时可能会产生副作用。例如,使用overflow创建BFC后在某些情况下可能会看到出现一个滚动条或者元素内容被裁切。

这是由于overflow属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。

即使在没有任何不想要的副作用的情况下,使用 overflow 也可能会让其他开发人员感到困惑。为什么 overflow 设置为 autoscroll?最初的开发者的意图是什么?他们想要这个组件上的滚动条吗?

最安全的做法应该是创建一个 BFC 时并不会带来任何副作用,它内部的元素都安全的呆在这个迷你布局中,这种方法不会引起任何意想不到的问题,也可以理解开发者的意图。CSS 工作组也十分认同这种想法,所以他们定制了一个新的属性值:display:flow-root

flow-root 浏览器支持情况

你可以使用display:flow-root安全的创建BFC,来解决上文中提到的各种问题:包裹浮动元素、阻止外边距叠加和阻止围绕浮动元素。

10.png

浏览器对该属性的支持目前还是有限的,如果你觉得这个属性值很方便,请投票去让Edge也支持它。不过无论如何,你现在应该已经理解了什么是 BFC,以及如何使用 overflow 或其他方法来包裹浮动,以及知道了 BFC 可以阻止元素去环绕浮动元素,如果你想使用弹性或网格布局可以在一些不支持他们的浏览器中使用 BFC 的这些特性做降级处理。

理解浏览器如何布置网页是非常基础的。 虽然有时看起来无关紧要,但是这些小知识可以加快创建和调试 CSS 布局所需的时间。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
抖漫入口地址合集
抖漫入口地址合集

本专题整合了抖漫入口地址相关合集,阅读专题下面的文章了解更多详细地址。

12

2026.03.17

多环境下的 Nginx 安装、结构与运维实战
多环境下的 Nginx 安装、结构与运维实战

本专题聚焦多环境下Nginx实战,详解开发、测试及生产环境的差异化安装策略与目录结构规划。深入剖析配置模块化设计、灰度发布流程及跨环境同步机制。结合监控告警、故障排查与自动化运维工具,提供全链路管理方案,助力团队构建灵活、高可用的Nginx服务体系,从容应对复杂业务场景挑战。

1

2026.03.17

PS 批量添加图片
PS 批量添加图片

本专题整合了PS批量添加图片教程合集,阅读专题下面的文章了解更多详细操作。

2

2026.03.17

Nginx 基础架构:从安装配置到系统化管理
Nginx 基础架构:从安装配置到系统化管理

本专题深入解析Nginx基础架构,涵盖从源码编译与包管理安装,到核心配置文件优化及虚拟主机部署。进一步探讨日志轮转、性能调优、高可用集群构建及自动化运维策略,助力管理员实现从单一服务搭建到企业级系统化管理的全面升级,确保Web服务高效、稳定运行。

3

2026.03.17

mulerun骡子快跑入口地址汇总
mulerun骡子快跑入口地址汇总

本专题整合了mulerun入口地址合集,阅读专题下面的文章了解更多详细内容。

45

2026.03.17

源码编译安装Nginx详解:模块选择、依赖准备与常见错误排查
源码编译安装Nginx详解:模块选择、依赖准备与常见错误排查

本专题详解Nginx源码编译全流程:从GCC、OpenSSL等依赖准备,到按需定制HTTP/SSL/流媒体模块的configure参数策略。深入剖析“缺少库文件”、“配置选项冲突”及“权限错误”等常见报错,提供精准排查思路与解决方案。助您掌握灵活构建高性能、定制化Nginx的核心技能,满足复杂生产环境需求。

1

2026.03.17

Linux环境安装Nginx全流程:apt、yum与源码编译方式深度实操
Linux环境安装Nginx全流程:apt、yum与源码编译方式深度实操

本专题深度实操Linux下Nginx三大安装方式:apt/yum包管理器快速部署,适合新手与标准化运维;源码编译灵活定制模块,满足高性能与特殊需求场景。内容涵盖环境准备、依赖安装、配置优化及平滑升级策略,对比各方案优劣,助您根据业务场景选择最佳实践,构建稳定高效的Web服务基石。

5

2026.03.17

c++ 字符处理
c++ 字符处理

本专题整合了c++字符处理教程、字符串处理函数相关内容,阅读专题下面的文章了解更多详细内容。

7

2026.03.17

minimax视频生成教程汇总
minimax视频生成教程汇总

本专题整合了minimax生成视频相关教程,阅读下面的文章了解更多详细操作。

8

2026.03.17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 1.0万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.7万人学习

CSS教程
CSS教程

共754课时 | 44.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号