细说CSS中margin属性的使用

2020-05-03 11:30:05易采站长站整理

元素 #a 下方的元素 #b 也设置了 margin-top 为 20px,如果不折叠,则他们之间就有 30px 的距离。如果折叠成了一个 20px 的距离,则对元素 #a 来说,它的 margin-bottom 要求至少要有 10px 的距离,是满足的,而对于元素 #b 来说,它的 margin-top 要求至少要有 20px 的距离,也是满足的。

而 margin 折叠的存在,其实是为了可以在视觉上显得更美观,也更贴近设计师的预期。

margin 折叠规则

并不是所有的 margin 都可以折叠,需要满足以下条件:

垂直相邻的 margin 才有可能折叠,水平 margin 永远不折叠
根元素(即 html 元素)的 margin 永远不折叠
如果一个元素,它的 top margin 和 bottom margin 是相邻的,并且有清除浮动后的空隙(clearance),这个元素的 margin 可以跟兄弟元素的 margin 折叠,但是折叠后的 margin 不能跟父元素的 bottom margin 折叠。

需要注意的是,margin 并不是只能折叠一次,多个满足要求的 margin 都可以进行折叠形成一个折叠后的 margin(collapsed margin)。
并且假如这个折叠后的 margin 是由 margin A 等折叠而来的,如果有 margin X 跟 margin A 是相邻的,则我们也认为 margin X 跟这个折叠后的 margin 相邻。

折叠后的 margin 大小

当两个或者两个以上的 margin 折叠后,margin 的值计算如下:

如果 margin 都是正数,则取他们当中的最大值
如果 margin 中有正有负,则取最大的正数加上最小的负数(如最大的 margin 是 20px,最小的 margin 是 -20px,则他们计算后的值是 0)
如果 margin 中都是负数,则取他们当中的最小值

几道思考题

浮动、定位元素的 margin 不会和其他任何元素的 margin 发生重叠,包括它的子元素。

这是因为浮动元素脱离了正常流,所以它和其他相邻元素就不处与同一个流中,自然不相邻;又因为浮动元素的内容盒会形成一个新的 BFC,所以浮动元素跟子元素不处与同一个 BFC 中,因此它们的 margin 也不能折叠。定位元素同理可得。

inline-block 的元素不会和其他元素的 margin 发生折叠,包括它的子元素。

因为 margin 折叠只会发生在块级元素上,因此 inline-block 元素的 margin 不会和兄弟元素折叠,又因为 inline-block 的内容盒会形成一个新的 BFC,所以 inline-block 元素本身也不会和子元素的 margin 发生折叠

margin 折叠的几个栗子

栗子1

如果两个 margin 满足以下三个条件,我们就说这两个 margin 是相邻(adjoining)的:

两个 margin 之间没有行盒(line box)、清除浮动后的空隙(clearance)、padding和边框

针对这个条件,我们通过增加 padding 的方式来阻止 margin 的折叠: