BFC(Block Formatting Context)基础分析

W3C官方对于BFC的描述只有3小段,强烈建议想理解BFC的朋友先去看看,链接见文末。

常见的文档流分为:定位流、浮动流、普通流3种。BFC是普通流中的一种。

本文提出3个问题并给出使用BFC来解决这些问题的方法,这3个问题是:

  1. 外边距折叠(Collapsing Margins)
  2. 让一个没有设置高度的容器包含浮动元素
  3. 阻止文字环绕

什么是BFC

根据W3C对BFC的描述,可以总结出:BFC是一个具有特殊CSS样式的HTML盒子,比如div
标签就经常用来当盒子用。
这些特殊样式如下,下面的样式只要满足一项,就说明这个盒子是BFC

  • float: left | right
  • position: fixed | absolute
  • display: inline-block | table-cell | table-caption | flex | inline-flex
  • overflow: hidden | scroll | auto

外边距折叠

外边距折叠有很多种情况,最简单的就是上下两个盒子,上面的设置了margin-bottom
下面的设置了margin-top,这时候总的外边距并不是两者相加,而是取最大的外边距作
为总的外边距。(假设外边距的设置为正值)
下面的代码发生了外边距折叠。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>外边距折叠</title>
	<style>
	.container { background-color: red; width: 200px; }
	p { background-color: lightgreen; margin: 10px 0; }
	</style>
</head>
<body>

<div class="container">
	<p>Sibling 1</p>
	<p>Sibling 2</p>
</div>

</body>
</html>

下面的代码通过使用overflow: hidden;新创建一个BFC,从而实现阻止外边距折叠。
overflow: hidden;本来的含义是:如果盒子的内容超出盒子,则这部分内容隐藏。)

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>使用BFC阻止外边距折叠</title>
	<style>
	.container { background-color: red; width: 200px; }
	p { background-color: lightgreen; margin: 10px 0;}
	.newBFC {overflow: hidden; /* 这条样式专门用来创建BFC */}
	</style>
</head>
<body>

<div class="container">
	<p>Sibling 1</p>
	<div class="newBFC">
		<p>Sibling 2</p>
	</div>
</div>

</body>
</html>

发生了外边距折叠(左),使用BFC阻止外边距折叠(右)。

容器无高度包含浮动元素

先看以下无BFC,容器无高度包含浮动元素会发生什么。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>无BFC容器无高度包含浮动元素</title>
	<style>
	.container { 
		width: 200px;
		background-color: green; 
		outline: 1px dashed red;
	}

	.container div {
		float: left; 
		background-color: lightgreen;
		margin: 10px;
	}
	</style>
</head>
<body>

<div class="container">
	<div>Sibling 1</div>
	<div>Sibling 2</div>
</div>

</body>
</html>

上述代码运行效果如下:

可以看到,由于浮动元素是脱离普通文档流的,所以.container盒子发生了塌陷,高度
变为0。如何阻止这种情况发生呢,请看下面的代码:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>有BFC容器无高度包含浮动元素</title>
	<style>
	.container { 
		width: 200px;
		background-color: blueviolet; 
		outline: 1px dashed red;
		overflow: hidden; /* 创建BFC */
	}

	.container div {
		float: left;
		background-color: lightgreen;
		margin: 10px;
	}
	</style>
</head>
<body>

<div class="container">
	<div>Sibling 1</div>
	<div>Sibling 2</div>
</div>

</body>
</html>

上面的代码给.container盒子添加了一条样式overflow: hidden;,解决了容器盒子
塌陷的问题。运行效果图如下:

阻止文字环绕

左图右文,文字环绕图片,代码实现如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>左图右文 - 文字环绕图片</title>
	<style>
	.container { 
		background-color: gainsboro; 
		width: 500px;
  		min-height: 400px;
		padding: 10px
	}

	.pic {
		float: left;
		margin-right: 10px;
	}
	</style>
</head>
<body>

<div class="container">
	<div class="pic">
		<img src="5.jpg" alt="小王子">
	</div>

	<div class="text">
		《小王子》是法国作家安托万·德·圣·埃克苏佩里于1942年写成的著名儿童文学短篇小说。
		本书的主人公是来自外星球的小王子。书中以一位飞行员作为故事叙述者,讲述了小王子
		从自己星球出发前往地球的过程中,所经历的各种历险。作者以小王子的孩子式的眼光,
		透视出成人的空虚、盲目,愚妄和死板教条,用浅显天真的语言写出了人类的孤独寂寞、
		没有根基随风流浪的命运。同时,也表达出作者对金钱关系的批判,对真善美的讴歌。
		《小王子》是法国作家安托万·德·圣·埃克苏佩里于1942年写成的著名儿童文学短篇小说。
		本书的主人公是来自外星球的小王子。书中以一位飞行员作为故事叙述者,讲述了小王子
		从自己星球出发前往地球的过程中,所经历的各种历险。作者以小王子的孩子式的眼光,
		透视出成人的空虚、盲目,愚妄和死板教条,用浅显天真的语言写出了人类的孤独寂寞、
		没有根基随风流浪的命运。同时,也表达出作者对金钱关系的批判,对真善美的讴歌。
	</div>
</div>

</body>
</html>

运行效果如下:

有时候我们不需要文字环绕,就想让文字老老实实待在右边。
左图右文,文字不环绕图片代码实现如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>左图右文 - 文字不环绕图片</title>
	<style>
	.container { 
		background-color: gainsboro; 
		width: 500px;
  		min-height: 400px;
		padding: 10px
	}

	.pic {
		float: left;
		margin-right: 10px;
	}

	.text {
		overflow: hidden;
	}
	</style>
</head>
<body>

<div class="container">
	<div class="pic">
		<img src="5.jpg" alt="小王子">
	</div>

	<div class="text">
		《小王子》是法国作家安托万·德·圣·埃克苏佩里于1942年写成的著名儿童文学短篇小说。
		本书的主人公是来自外星球的小王子。书中以一位飞行员作为故事叙述者,讲述了小王子
		从自己星球出发前往地球的过程中,所经历的各种历险。作者以小王子的孩子式的眼光,
		透视出成人的空虚、盲目,愚妄和死板教条,用浅显天真的语言写出了人类的孤独寂寞、
		没有根基随风流浪的命运。同时,也表达出作者对金钱关系的批判,对真善美的讴歌。
		《小王子》是法国作家安托万·德·圣·埃克苏佩里于1942年写成的著名儿童文学短篇小说。
		本书的主人公是来自外星球的小王子。书中以一位飞行员作为故事叙述者,讲述了小王子
	</div>
</div>

</body>
</html>

运行效果如下:

总结

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素是不会影响到外面的元素。
  • BFC的区域不会与其它float的元素区域重叠。
  • 计算BFC的高度时,浮动子元素也参与计算。

如果有帮助,亲,点个赞奥!不胜感激。

参考资料

https://www.w3.org/TR/CSS22/visuren.html#block-formatting

https://www.sitepoint.com/understanding-block-formatting-contexts-in-css/

http://www.cnblogs.com/xiaohuochai/p/5248536.html#undefined

posted @ 2017-08-03 20:40  阿胜4K  阅读(7124)  评论(6编辑  收藏  举报