CSS中的BFC机制

2024-03-06 19:18
文章标签 css 机制 frontend bfc

本文主要是介绍CSS中的BFC机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 什么是BFC

块格式化上下文BFC(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。以上内容摘自MDN,其实通俗来讲BFC就是一个独立的布局环境,BFC中的元素布局不受外部元素的影响,也不会影响到外部元素。

2 如何触发BFC

其实在日常开发中经常会主动触发BFC:

  1. 给元素设置浮动(float: left | right
  2. 给元素设置脱离文档流的定位(position: absolute | fixed
  3. 给元素设置内容溢出(overflow: hidden | scroll
  4. 给元素设置弹性布局(display: flex

以上列出的都是常见的几种,更多触发BFC的方式可查阅文档MDN-BFC。除了主动触发BFC,其实每个HTML文档中都会被动触发BFC,因为其根元素html本身就会形成一个BFC,可以理解为页面中的所有元素都存在与某个BFC环境下。

3 BFC的特性

3.1 BFC内部依然遵循元素定位规则

在CSS中,元素定位规则分为以下三种:

  1. 普通文档流:元素按照从上至下,从左至右的顺序排列,但元素又分行内元素和块级元素,其排列方式有所不同:
    1. 行内元素:水平排列,直到水平方向占满一行后再另起一行排列。
    2. 块级元素:垂直排列,每一个块级元素都会独自占用一行。
  2. 浮动流:设置浮动的元素会向左或向右浮动,直到碰到父级元素或其他浮动的元素,需要注意的是,设置浮动的元素只是半脱离文档流。
  3. 脱离文档的定位流:当定位设置为absolute绝对定位或fixed固定定位时,元素会完全脱离文档流,元素的位置就是定位时设置的位置,其布局不会受其他元素的影响,也不会影响到其他元素。

BFC内部依然遵循元素定位规则这句话很好理解,前面提到根元素html本身会形成一个BFC,所以其内部自然遵循元素定位规则。

3.2 BFC内部相邻元素垂直外边距合并

属于同一个BFC的内部两个相邻的元素的垂直外边距会发生合并,这个特性在li标签下格外明显,举个例子:

<ul><li>JavaScript</li><li>Python</li><li>C++</li><li>Java</li><li>Golang</li>
</ul>
ul {width: 200px;
}li {list-style: none;border: 3px solid pink;border-radius: 3px;margin: 10px 0px; /* 关键代码:为li标签设置了10px的上下外边距 */text-align: center;
}

在CSS中为li标签设置了上下10px的外边距,理论上每个li标签在垂直距离上应该相距20px,但结果却是每个li标签在垂直距离上只相距10px
image.pngimage.pngimage.png
这就是发生了外边距合并。

3.3 不同BFC的相邻元素不会外边距合并

要解决3.2节中的外边距合并问题,可以将每个被合并的元素都放在一个单独的BFC环境下,这样就不会发生外边距合并,修改代码如下,将每个li标签用一个div标签包裹:

  <ul><div><li>JavaScript</li></div><div><li>Python</li></div><div><li>C++</li></div><div><li>Java</li></div><div><li>Golang</li></div></ul>

再让每个div标签触发BFC机制,这里选用最为常用的overflow: hidden;方式:

    ul div {overflow: hidden;}

效果如下:
image.pngimage.png
不难发现两个li标签的距离为20px,这样就通过BFC机制解决了外边距合并问题。

3.4 BFC中元素的margin-box的左边与子元素的border-box左边相接

该特性的完整描述为“每个元素的margin-box的左边会与包含块border-box的左边相接触(对于从左到右的格式化,否则相反),即使存在浮动也会如此。”这句话晦涩难懂,先来解释一下什么叫margin-box什么叫border-box,这两个词都来源于盒模型:
image.png
本文中仅讨论W3C标准盒子模型,可以发现一个盒子由内至外分别为contentpaddingbordermargin四个部分组成,而每一个部分对应着content-boxpadding-boxborder-boxmargin-box

3.4.1 浮动的元素

举个例子:

<div class="box1"><div class="box2"></div>
</div>
.box1 {width: 500px;height: 500px;background-color: red;overflow: hidden; /* 触发BFC */
}
.box2 {width: 300px;height: 300px;background-color: blue;float: left; /* 添加左浮动 */
}

效果如下:
image.png
图中box1box2只设置了widthheight,未设置marginborderpadding,此时参照的是父元素的最外层margin-box,所以box2box1直接相接。但当父元素拥有paddingborder时,此时参照的是padding-boxborder-box,如下图是设置了border的效果:
image.png
如下图是给box1设置了padding的效果:
image.png
如下图是给box1即设置了border也设置了padding的效果:
image.png

3.4.2 定位的元素

依然采用3.4.1节中的例子,将box2从左浮动改为绝对定位position: absolute;并设置left: 0;top: 0;

.box1 {width: 500px;height: 500px;background-color: red;overflow: hidden; /* 触发BFC */border: 30px solid pink;padding: 30px;position: relative;
}
.box2 {width: 300px;height: 300px;background-color: blue;position: absolute;left: 0;top: 0;
}

box1不设置marginborderpadding的情况下如下所示,其结果与浮动的元素相同:
image.png
box1设置border后效果如下所示,其结果也与浮动的元素相同:
image.png
box1设置padding后的效果如下所示,此时效果就与浮动的元素不同了,定位的元素会直接“忽视”padding的存在,直接box1的左边缘相接:
image.png
box1即设置border又设置padding的效果如下,可以发现box1padding依然被“忽视”了,直接与border-box相接:
image.png

3.4.3 总结

  • BFC内元素为浮动的情况下:参照的是content-box
  • BFC内元素为定位的情况下:参照的是padding-box

3.5 BFC计算高度时包括浮动元素

该特性是用于清除浮动的方法之一,给父元素添加overflow: hidden属性触发BFC机制即可,详细请阅读CSS浮动和清除浮动中的4.3节。

3.6 BFC的区域不会与浮动元素发生重叠

该特性常用于两栏自适应布局,即左边固定宽度,右边宽度自适应,如下图所示:
image.png
实现方式如下:

* {margin: 0;padding: 0;
}html,
body {width: 100%;height: 100%;
}.left {width: 200px;height: 100%;background: red;float: left;
}.right {height: 100%;background: blue;overflow: hidden;
}
<div class="left"></div>
<div class="right"></div>

4 BFC的应用场景

4.1 清除浮动

见3.5节

4.2 两栏自适应布局

见3.6节

4.3 消除边距合并

见3.3节

这篇关于CSS中的BFC机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/781052

相关文章

vite搭建vue3项目的搭建步骤

《vite搭建vue3项目的搭建步骤》本文主要介绍了vite搭建vue3项目的搭建步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1.确保Nodejs环境2.使用vite-cli工具3.进入项目安装依赖1.确保Nodejs环境

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni