CSS中的BFC的理解

554 阅读3分钟

这是我参与更文挑战的第8天,活动详情查看: 更文挑战

在了解BFC之前呢?我们现了解一下常见的定位方案。

普通流:

  • 元素按照其在html中的先后位置自上而下的布局
  • 行内元素水平排列,直到当行被占满然后换行,块级元素则会呗渲染为完整的一个新行
  • 所有元素都默认是普通流

浮动

  • 元素按照普通流的形式出现,然后根据浮动的方向尽可能的向左或者向右偏移

绝对定位

  • 元素整体会脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响

而我们今天所了解的BFC是在普通流中的。BFC在MDN中给的定义是块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。 通俗的讲BFC我们可以看作是一个渲染区域,他有自己的渲染规则,也可以认为是bfc属于元素的一个属性,当元素拥有BFC这些属性的时候,我们就可以认为是一个隔离了的独立容器。容器里面的元素在布局上不会影响容器外面的元素。 那么如何给元素添加BFC这个属性呢?

  • 跟元素()
  • 浮动元素(元素的float属性不是none )
  • 绝对定位元素(position 为absolute或者fixed)
  • display 为inline-block、table-cell、table-caption、table、table-row、table-row-group、table-header-group、table-footer-group、inline-table、flex或者inline-flex、grid或者inline-grid、flow-root。
  • overflow值不为visible的块元素
  • contain值为layout,content或者paint的元素
  • 多列容器(元素的 column-count 或 column-width (en-US) 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中

BFC特性与作用

  • 解决css的外边距重叠
<div class="test"/>
<div class="test"/>

.test{
    width:100px;
    height:100px;
    margin:100px;
    background:blue;
}

1623227607537.jpg

我们可以看到两个盒子的margin-top与margin-bottom重合了。首先这不是一个bug。MDN的定义:块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则仅为其中一个),这种行为称为边距折叠。 最终的margin值计算方法如下: a、全部都为正值,取最大者; b、不全是正值,则都取绝对值,然后用正值减去最大值; c、没有正值,则都取绝对值,然后用0减去最大值。 注意:相邻的盒模型可能由DOM元素动态产生并没有相邻或继承关系

如何解决这种问题呢?我们可以将两个div放置于不同的BFC中,BFC的内容将不会互相干扰。

<div class='container'>
     <div class="test"/>
</div>
<div class='container'>
    <div class="test"/>
</div>
 .container{
 overflow:hidden;
 }
 .test{
     width:100px;
     height:100px;
     margin:100px;
     background:blue;
 }
 

1623228423237.jpg

  • 清除浮动

<div class='test-box'>
    <div class="test"/>
</div>
	
<style>
	.test-box{
		border: 1px solid red;
	}
	.test{
	width: 100px;
	height: 100px;
	background: blue;
	float: left;
	}
</style>

我们可以看到外层盒子只剩一个2px高度的内容,这是因为我们为test盒子设置了浮动使其脱离了文档流。

1623228721756.jpg

遇到这种情况我们可以使用overflow属性来触发父元素的bfc属性,那么父容器将会包裹着子容器,从而达到了清除浮动的作用

<div class='test-box'>
	     <div class="test"/>
</div>

<style>
	.test-box{
		border: 1px solid red;
		margin: 100px;
		overflow: hidden;
	}
	.test{
	width: 100px;
	height: 100px;
	background: blue;
	float: left;
	}
</style>

1623228745899.jpg

  • 组织元素被浮动元素覆盖 我们设置两个div,给第一个元素设置浮动,我们可以看到,浮动的元素会覆盖第二个div。
<div class='test-box'>
	</div>
	<div class="test"/>

<style>
	.test-box{
		width: 100px;
		height: 100px;
		background: red;
		float: left;
	}
	.test{
	width: 200px;
	height: 200px;
	background: blue;
	
	}
</style>

1623229381451.jpg

要解决上面的问题我们可以设置第二个元素的overflow属性,使其触发BFC特性从而达到组织元素被覆盖的问题。

<div class='test-box'>
	</div>
	<div class="test"/>

<style>
	.test-box{
		width: 100px;
		height: 100px;
		background: red;
		float: left;
	}
	.test{
	width: 200px;
	height: 200px;
	background: blue;
	overflow: hidden;
	}
</style>

1623229440067.jpg