本文主要是介绍CSS中的BFC机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1 什么是BFC
块格式化上下文BFC(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。以上内容摘自MDN,其实通俗来讲BFC就是一个独立的布局环境,BFC中的元素布局不受外部元素的影响,也不会影响到外部元素。
2 如何触发BFC
其实在日常开发中经常会主动触发BFC:
- 给元素设置浮动(
float: left | right
) - 给元素设置脱离文档流的定位(
position: absolute | fixed
) - 给元素设置内容溢出(
overflow: hidden | scroll
) - 给元素设置弹性布局(
display: flex
) - …
以上列出的都是常见的几种,更多触发BFC的方式可查阅文档MDN-BFC。除了主动触发BFC,其实每个HTML文档中都会被动触发BFC,因为其根元素html
本身就会形成一个BFC,可以理解为页面中的所有元素都存在与某个BFC环境下。
3 BFC的特性
3.1 BFC内部依然遵循元素定位规则
在CSS中,元素定位规则分为以下三种:
- 普通文档流:元素按照从上至下,从左至右的顺序排列,但元素又分行内元素和块级元素,其排列方式有所不同:
- 行内元素:水平排列,直到水平方向占满一行后再另起一行排列。
- 块级元素:垂直排列,每一个块级元素都会独自占用一行。
- 浮动流:设置浮动的元素会向左或向右浮动,直到碰到父级元素或其他浮动的元素,需要注意的是,设置浮动的元素只是半脱离文档流。
- 脱离文档的定位流:当定位设置为
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
。
这就是发生了外边距合并。
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;}
效果如下:
不难发现两个li
标签的距离为20px
,这样就通过BFC机制解决了外边距合并问题。
3.4 BFC中元素的margin-box
的左边与子元素的border-box
左边相接
该特性的完整描述为“每个元素的margin-box
的左边会与包含块border-box
的左边相接触(对于从左到右的格式化,否则相反),即使存在浮动也会如此。”这句话晦涩难懂,先来解释一下什么叫margin-box
什么叫border-box
,这两个词都来源于盒模型:
本文中仅讨论W3C标准盒子模型,可以发现一个盒子由内至外分别为content
、padding
、border
、margin
四个部分组成,而每一个部分对应着content-box
、padding-box
、border-box
、margin-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; /* 添加左浮动 */
}
效果如下:
图中box1
、box2
只设置了width
、height
,未设置margin
、border
、padding
,此时参照的是父元素的最外层margin-box
,所以box2
与box1
直接相接。但当父元素拥有padding
或border
时,此时参照的是padding-box
或border-box
,如下图是设置了border
的效果:
如下图是给box1
设置了padding
的效果:
如下图是给box1
即设置了border
也设置了padding
的效果:
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
不设置margin
、border
、padding
的情况下如下所示,其结果与浮动的元素相同:
给box1
设置border
后效果如下所示,其结果也与浮动的元素相同:
给box1
设置padding
后的效果如下所示,此时效果就与浮动的元素不同了,定位的元素会直接“忽视”padding
的存在,直接box1
的左边缘相接:
给box1
即设置border
又设置padding
的效果如下,可以发现box1
的padding
依然被“忽视”了,直接与border-box
相接:
3.4.3 总结
- BFC内元素为浮动的情况下:参照的是
content-box
。 - BFC内元素为定位的情况下:参照的是
padding-box
。
3.5 BFC计算高度时包括浮动元素
该特性是用于清除浮动的方法之一,给父元素添加overflow: hidden
属性触发BFC机制即可,详细请阅读CSS浮动和清除浮动中的4.3节。
3.6 BFC的区域不会与浮动元素发生重叠
该特性常用于两栏自适应布局,即左边固定宽度,右边宽度自适应,如下图所示:
实现方式如下:
* {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机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!