今天就来捋一捋简单低调却奢华的css,主要鲁三个点:
一.margin的折叠
二.margin折叠后的计算
三.margin折叠的解决之道
先来捋一捋margin的折叠:
主要分为父子折叠以及兄弟折叠,都是垂直方向上的折叠
父子折叠(不一定是父子,可以是多层级的包含,只要是空盒子嵌套)看例子:
<ul style="margin-top:2px>
<li style="margin:10px 0"></li>
<li style="margin:10px 0"></li>
<li style="margin:10px 0"></li>
<li style="margin:10px 0"></li>
<li style="margin:10px 0"></li>
</ul>
我们的目的是想让li和ul之间有个10px的间隔:但是现实是残酷的,发现不管是ul的顶部还是底部,都没有和li间隔开,反而是ul和上面的元素还有下面的元素间隔开了10px,
我X,什么鬼,居然连乾坤大挪移都用上了?客官别急,其实是因为ul和li的垂直margin折叠了,所以最后就编程只有ul有margin,而且是10px,为什么是10px?怎么解决?
别急,折叠计算和解决之道在后面会详细解答,客官只要记住,两个嵌套的盒子中间没有非空内容间隔,它们垂直的margin会合并。这就是嵌套盒子的margin折叠
我咋一看,不对啊,li之间应该是20px的间隔才是的,怎么只有10px呢?那是因为li发生了另一种margin折叠,兄弟折叠
出发条件,当两个普通流元素(非浮动非定位)的margin也会折叠,比如第一个li的margin-bottom和第二个的margin-top会折叠,所以最后就只会取其中一个,这就是兄弟margin折叠,到此,折叠产生就讲完了,立马进入第二个主题:
二.折叠的计算
2.1 参加折叠的margin都是正值:取其中 margin 较大的值为最终 margin 值。
2.2 参与折叠的 margin 都是负值:取的是其中绝对值较大的,然后,从 0 位置,负向位移。
2.3 参与折叠的 margin 中有正值,有负值:先取出负 margin 中绝对值中最大的,然后,和正 margin 值中最大的 margin 相加。
2.4 相邻的 margin 要一起参与计算,不得分步计算
<div style="margin:50px 0; background-color:green; width:50px;">
<div style="margin:-60px 0;">
<div style="margin:150px 0;">A</div>
</div>
</div>
<div style="margin:-100px 0; background-color:green; width:50px;">
<div style="margin:-120px 0;">
<div style="margin:200px 0;">B</div>
</div>
</div>
错误的计算方式:算 A 和 B 之间的 margin,分别算 A 和其父元素的折叠,然后与其父元素的父元素的折叠,这个值算出来之后,应该是 90px。依此法算出 B 的为 80px;然后,A和B折叠,margin 为 90px。
请注意,多个 margin 相邻折叠成一个 margin,所以计算的时候,应该取所有相关的值一起计算,而不能分开分步来算。
以上例子中,A 和 B 之间的 margin 折叠产生的 margin,是6个相邻 margin 折叠的结果。将其 margin 值分为两组:
正值:50px,150px,200px
负值:-60px,-100px,-120px
根据有正有负时的计算规则,正值的最大值为 200px,负值中绝对值最大的是 -120px,所以,最终折叠后的 margin 应该是 200 + (-120) = 80px。
margin折叠计算就讲完了,接下来讲讲解决之道:三.解决margin折叠
3.1嵌套margin折叠类型解决方法
1.在父层盒子添加:overflow:hidden (比较暴力,如果有悬浮窗可能导致无法看到)
2.不用margin-top,改用padding-top (如果子盒子有border,那这个方法就不适合了)
3.给父元素添加1px的padding或者添加一个style不为none的border,可以使用透明border(如果设计师不能容忍1px的差异,那这个就不适用了)
4.给父元素加上浮动(如果要占满一行那就要加上width:100%)
5.设置父元素dispaly:inline-block或者display:table-cell;(如果要占满一行那就要加上width:100%)
6.给父元素添加绝对定位(不推荐)
这几个方法都能解决嵌套导致的margin折叠问题,任君选择
3.2 兄弟之间的margin折叠解决方法
1.给最后面的兄弟加上浮动
2.给最后面的元素加上display:inline-block;
各位客官,今天就捋到这,下回再见