今天在知道上看见一网友问的问题,大概是他网页中有两个父子关系的 div,父级 div 没有任何外边距,而子级 div 顶部有有外 10px 边距,结果这 10px 的顶部外边距没按他的期望出现在父、子两个 div 之间,而是跑到父级 div 的顶部去了。
该网友想知道产生这个结果的原理,知道原文: http://zhidao.baidu.com/question/332708289.html (知道回答的时候我没试 Opear,以为只有 IE6 出这个问题)
这个问题我曾经遇到过多次,出现问题的情况: ·IE6、Opear 下出现、其他版本 IE 没装,Firefox 和 Chrome 没装,不确定是否有相同问题,以前遇着这个问题有否试过其他浏览器也记不清楚了,不过看样子都会有,有兴趣的朋友自己测试。 ·只是有时候出现这个问题,说明需要一定的条件才会出现,我只测试到当父级元素没有宽度时这个问题问发生: ------------------------------------------- <!Doctype html> <head> <body> <div> BBB您应该对使用搜索引擎的结果自行承担风险。百度不做任何形式的保证:不保证搜索结果满足您的要求,不保证搜索服务不中断,不保证搜索结果的安全性、正确性、及时性、合法性。因网络状况、通讯线路、第三方网站等任何原因而导致您不能正常使用百度,百度不承担任何法律责任。 </body> </html> ------------------------------------------- 由于提问的网友父级 div 赋予了 950px 的宽度,说明还有其他不明诱因情况下也会出现,这个有志气的朋友探索研究后还望告知。
导致这个错误的原因: 此错误是由 margin 外边距垂直合并引起的,如下面 html 在 css 中给 p 定义上下各 10px 外边距: -----html----- <div> <p>AAA</p> <p>BBB</p> </div> -----css----- p{margin:10px 0;}
理论上正确的结果是 AAA 的顶部离父级 div 有 10px 外边距,BBB 的底部离父级 div 也有 10px 距离,AAA、BBB 之间有 20px 距离 (AAA 底部 10px + BBB 顶部 10px = 20px);
但按这个方式处理出现了一个问题,AAA、BBB 之间 20px 的外边距影响了排版上的美观,于是浏览器解析过程中就自动将 AAA 的 10px 底边距和 BBB 的 10px 顶边距强制叠加到一起,使其只有 10px 距离;
margin外边距强制合并发生的条件: 1. 水平 margin 不会合并。 2. 两个上下渲染相邻(不一定是兄弟节点)的块状元素在正常页面流情况下会发生 margin 合并。 3. 浮动元素不会和任何元素(包括子孙节点)发生 margin 合并。 4. overflow = visible 的元素不和任何元素发生 margin 合并。 5. 绝对定位的元素不和任何元素发生 margin 合并。 6. inline-block 的元素不和任何元素发生 margin 合并。 7. 设置 clear 属性的元素不和任何元素发生 margin 合并。 8. 根元素不和任何元素发生 margin 合并。 9. 父节点和第一个子节点发生 margin-top 合并。 10. 如果最后一个子节点没有 border 以及 padding ,则和其父节点发生 margin-bottom 合并。
提问题那个网友显然是中了上面第 9 条的招: 由于他的父级 div 没有外边距,而子 div 有外边距,所以浏览器强制合并外边距后,距离依然为 10px (0+10px=10px);但是 bug 出现了,本该出现在父子之间的 10px 距离跑到了父级 div 的外面,而父子之间反而没有距离了。
由此我们可以推断出: 浏览器在处理这两个 div 合并他们垂直外边距时的顺序是:从后面的子级开始去合并到父级的,即:BBB 顶部外边距去叠加重合到 AAA 底部的外边距上,这时父级 AAA 底部外边距为 0,BBB 往 AAA 的边界外面挤了,产生了这个问题。
此 bug 的解决办法: 父元素加上垂直方向的 padding 内边距,有内边距就会隔开里面那个 div 的垂直方向外边距,强制其无法产生垂直外边距自动合并。 加 border 也可以解决,只要满足上面 1-10 的条件或者其他办法都能避免这个问题。
文字啰嗦,不明白的看图: |
|
来自: Dead n Gone > 《网页设计》