不得不说前端是一个水很深的行业,虽然起点低,稍微一学就能入门;但是很多实操型的知识如各种兼容性、规范性问题不在实际操作中遇到是无法深刻的理解的,笔者就遇到了CSS外边距合并这一看似非主流却很主流的问题。
问题描述:
笔者想得到一个两个内套的盒子模型,并设置子盒子的上边距为50px;于是写了如下代码。
- <!DOCTYPE html>
- <html lang=“en”>
- <head>
- <meta charset=“UTF-8”>
- <title>padding-demo</title>
- <style type=“text/css”>
- * {padding:0;margin:0;border:0;}
- .wrap {
- width: 600px;
- margin: 0 auto;
- background: grey;
- height: 300px;
- }
- .wrap .box {
- font-size: 18px;
- color: #fff;
- width: 300px;
- height: 100px;
- line-height: 100px;
- margin: 0 auto;
- background-color: orange;
- margin-top: 50px;
- text-align: center;
- }
- </style>
- </head>
- <body>
- <div class=“wrap”>
- <div class=“box”>我是内容</div>
- </div>
- </body>
- </html>
但在浏览器中得到的确实下图的效果:
奇怪了,我明明是想让box在warp中有个上边距,为啥box紧贴了wrap,而wrap却有了个50px 的上边距,听说过子元素继承父元素的属性,还没见过父元素也会用子元素的属性。
赶紧学习了一下,是笔者才疏学浅了,原来这就是CSS外边距合并规范。引用w3schopl的定义是:当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
这就很好理解笔者遇到的问题,子元素的margin-top:50px,直接遇到了父元素的margin:0,然后合并到父元素上了。
解决办法:
那么既然知道CSS有此规范,那有什么解决办法么?答案是肯定的!
父元素的第一个子元素的上边距margin-top如果碰不到有效的border或者padding.就会不断一层一层的找自己 “领导”(父元素,祖先元素)的麻烦。只要给领导设置个有效的 border或者padding就可以有效的管制这个目无领导的margin防止它越级,假传圣旨,把自己的margin当领导的margin执行。 为父元素例子中的middle元素增加一个border-top或者padding-top即可解决这个问题。另外只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
解决方法:
- 修改父元素的高度,增加padding-top样式模拟(padding-top:1px;常用)
- 为父元素添加overflow:hidden;样式即可(完美)
- 为父元素或者子元素声明浮动(float:left;可用)
- 为父元素添加border(border:1px solid transparent可用)
- 为父元素或者子元素声明绝对定位
所以我只需要给wrap增加一个overflow:hidden;就完美解决了,得到如下效果。
注:令人哭笑不得的是该问题在IE7/IE8下是不会出现的,却在现代浏览器上绊了一脚,不过看了文尾的解释后,你就知道它其实也是有意义的一个规范。
CSS外边距合并实例
另外用几张图片来更生动形象的描述CSS外边距合并这一“bug”。
当一个元素出现在另一个元素上面时,第一个元素的下外边距与第二个元素的上外边距会发生合并。请看下图:
当一个元素包含在另一个元素中时(假设没有内边距或边框把外边距分隔开),它们的上和/或下外边距也会发生合并。请看下图:
尽管看上去有些奇怪,但是外边距甚至可以与自身发生合并。
假设有一个空元素,它有外边距,但是没有边框或填充。在这种情况下,上外边距与下外边距就碰到了一起,它们会发生合并:
如果这个外边距遇到另一个元素的外边距,它还会发生合并:
这就是一系列的段落元素占用空间非常小的原因,因为它们的所有外边距都合并到一起,形成了一个小的外边距。
外边距合并初看上去可能有点奇怪,但是实际上,它是有意义的。以由几个段落组成的典型文本页面为例。第一个段落上面的空间等于段落的上外边距。如果没有外边距合并,后续所有段落之间的外边距都将是相邻上外边距和下外边距的和。这意味着段落之间的空间是页面顶部的两倍。如果发生外边距合并,段落之间的上外边距和下外边距就合并在一起,这样各处的距离就一致了。