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

相关文章

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

Redis的持久化之RDB和AOF机制详解

《Redis的持久化之RDB和AOF机制详解》:本文主要介绍Redis的持久化之RDB和AOF机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述RDB(Redis Database)核心原理触发方式手动触发自动触发AOF(Append-Only File)核

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.