[前端]浅析外边距折叠(Collapsing Margins)

蓝飞 蓝飞 | 时间:2013-01-26, Sat | 9,608 views
前沿信息 

我们在学习前端的过程中,有时候会出现一些奇怪的现象,Collapsing Margins便是其中之一,有时候我们想要某个元素离的第一个子元素能够下移一些,于是给它设置了margin-top,但奇怪的是这个margin-top属性却传递给了父元素,导致父元素的位置下移:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title></title>
	<style type="text/css">
		body {
			margin: 0;
		}
		.parent {
			height: 200px;
			background: #0099ff;
		}
		.child {
			width: 230px;
			margin-top: 50px;
		}
	</style>
</head>
<body>
	<div class="parent">
		<div class="child">Child</div>
	</div>
</body>
</html>

这是个BUG吗?为什么各种浏览器都会有这样的“BUG”呢?其实,W3C规范认为margin折叠会使页面布局更加合理,比如两个段落(<p>)之间,段前间距跟段后间距应该只保留最大的一个,而不应该两者相加而导致段落之间间隙过大。下面,我们就来探究一下这个奇怪的Collapsing Margins。

什么是外边距折叠(Collapsing margins)?

Collapsing margins,即外边距折叠,指的是毗邻的两个或多个垂直方向的外边距 (margin) 会合并成一个外边距。这里的毗邻包括相同级别的元素外边距,也包括父子元素的外边距。

什么情况下会发生折叠?

可以归结为以下两点:

  1. 这两个或多个外边距没有被非空内容、padding、border 或 clear 分隔开。
  2. 这些 margin 都处于普通流中(非浮动元素、非定位元素)。

折叠后margin的计算

  1. 当参与折叠的margin均为正值时,取最大的margin值作为最终margin。
  2. 当参与折叠的margin均为负值时,取绝对值最大的margin值作为最终margin。
  3. 当参与折叠的margin同时存在正负值时,取绝对值最大的负margin值与最大的正margin值相加作为最终margin。

如何防止外边距折叠?

在某些情况下,margin的折叠并不是我们需要的效果,甚至可能影响正常的布局,这时候怎么办呢?有以下这些解决办法,按需要任选其一即可:

  1. 使用高度为零的空元素将折叠的margin隔开(不建议)
  2. 使用边框将折叠的margin隔开:border:1px transparent solid; (大小大于零)
  3. 使用内边距将折叠的margin隔开:padding:1px; (大小大于零)
  4. 为父元素设置overflow:hidden;
  5. display:inline-block;(IE7以下不支持)
  6. position:absolute;
  7. float:left;

后记

很久之前便想写一篇关于margin折叠的文章了,可惜由于各种原因,再加上很长一段时间以来心比较急躁,难以静下来写写东西,无奈耽搁至今。。寒假里还有许多事要做,希望自己能够乐观积极,不怕麻烦,赶紧把这些事情通通搞定,然后恶补前端性能JavaScript,准备下学期的实习。

——于2013年1月26日 深夜1:46:48

如需转载请注明出处:蓝飞技术部落格

当前暂无评论 »