下午在看《css禅意花园》,书中提到了外边距重叠,于是去网上搜索了一下资料。
写了一个小例子做测试。发现网上的有些总结与我的测试不符,索性就自己总结了╮(╯▽╰)╭
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>无标题文档</title> 6 <style type="text/css"> 7 body,div,h1{ 8 margin: 0;padding: 0; 9 } 10 11 div{ 12 13 width: 480px; 14 height: 560px; 15 background-color: #efe; 16 /*这里都用于解决父与子的层叠*/ 17 18 /*第一种:当然这种需要修正父元素的高和宽*/ 19 /*padding: 1px 0;*/ 20 21 /*第二种:*/ 22 /*position: absolute;*/ 23 24 /*第三种:*/ 25 /*float:left;*/ 26 27 /*第四种:*/ 28 /*overflow: hidden;*/ 29 30 /*第五种:*/ 31 /*display:inline-block;*/ 32 33 /*第六种:*/ 34 /*只适用于ie6 7 */ 35 /*zoom:1;*/ 36 37 /*第七种:*/ 38 /*IE6下边框无法透明*/ 39 /*border:1px solid transparent;*/ 40 } 41 42 h1{ 43 width: 400px; 44 height: 200px; 45 margin: 40px; 46 47 /*第一种:同时解决了父子 兄弟这2种层叠问题,但是在IE6下会有新的问题兼容产生:双倍左右边距*/ 48 /*float:left; */ 49 /*解决IE6双倍左右边距的问题*/ 50 /*_margin-left: 20px; 51 _margin-right:20px;*/ 52 53 54 55 /*第二种:同时解决了父子 兄弟这2种层叠问题 兼容问题已通过zoom解决*/ 56 /*display:inline-block; 57 *display:inline; 58 *zoom:1; 59 */ 60 } 61 .c1{ 62 background-color: #ccc; 63 64 } 65 .c2{ 66 67 background-color: #ff3; 68 } 69 </style> 70 </head> 71 <body> 72 <div> 73 <h1 class='c1'>div1</h1> 74 <h1 class='c2'>div2</h1> 75 </div> 76 </body> 77 </html>
另外发现知乎上的一个回答,来自丁小倪。
链接:http://www.zhihu.com/question/19823139
一、首先你要知道什么情况下会触发:两个或多个毗邻的普通流中的块元素垂直方向上的 margin 会折叠
1.两个或多个
说明其数量必须是大于一个,又说明,折叠是元素与元素间相互的行为,不存在 A 和 B 折叠,B 没有和 A 折叠的现象。2.毗邻
是指没有被非空内容、padding、border 或 clear 分隔开,说明其位置关系。
注意一点,在没有被分隔开的情况下,一个元素的 margin-top 会和它普通流中的第一个子元素(非浮动元素等)的 margin-top 相邻; 只有在一个元素的 height 是 "auto" 的情况下,它的 margin-bottom 才会和它普通流中的最后一个子元素(非浮动元素等)的 margin-bottom 相邻。3.垂直方向
是指具体的方位,只有垂直方向的 margin 才会折叠,也就是说,水平方向的 margin 不会发生折叠的现象。二、那么如何使元素上下margin不折叠呢?
1.浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠(注意这里指的是上下相邻的元素)
2.创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠(注意这里指的是创建了BFC的元素和它的子元素不会发生折叠)
我们都知道触发BFC的因素是float(除了none)、overflow(除了visible)、display(table-cell/table-caption/inline-block)、position(除了static/relative)
很明显大家可以看出来相邻元素不发生折叠的因素是触发BFC因素的子集,也就是说如果我为上下相邻的元素设置了overflow:hidden,虽然触发了BFC,但是上下元素的上下margin还是会发生折叠
这个问题其实和BFC并没有太大的关系,希望大家不要滥用BFC,要知道BFC不是全能,创建BFC的初衷只是为了让元素本身(包括它的子元素)能够正确的计算自己的宽高。http://www.yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts不发生折叠的触发因素是浮动元素、inline-block 元素、绝对定位元素,这个只是创建BFC因素的子集,但并不能说明创建了BFC的元素就不会发生折叠,因为BFC还可以用overflow:hidden来创建。相反如果父元素触发了BFC,那么他的块级子元素反而会发生折叠。
这里我写了一个DEMO来说明这个问题:http://whycss.com/demo/collspan_demo.html 创建BFC的三种情况都提到了,结果是子元素的上下margin都会发生折叠 。
克军提到的最后一个zoom,这是IE浏览器最初支持的缩放属性,到现在只有最新的webkit核心的浏览器也支持。但只是在IE8以下的浏览器下才可成功触发hasLayout,对于非IE浏览器也是没有效果的,所以还是需要同样的去创建BFC。关于hasLayout与BFC的介绍可参见本人博客的文章http://www.smallni.com/?p=174
关于最终如何解决这样的问题,我的建议是在写的时候尽量用同一方向的margin,比如都设置为top或者bottom,因为你在实践的时候有时不需要为每个元素设置浮动、inline-block或者absolute 。