过去很长一段时间我都觉得 margin 似乎有问题[1],因为他有些看起来怪异的特性。但直到最近才知道这并不能算是「怪异」
重叠的特性
123<div style="margin-bottom: 20px;">20px bottom margin</div><div style="margin-top: 40px;">40px top margin</div>
最终这两个 div 之间的距离会是 40px,而不是 padding 那样的 60px,第二个 div 的 margin 有 20px 都跟第一个 div 重叠了。
消除重叠
其实也挺简单的,若是列表项,则只设置 margin-top/margin-bottom 其中一个就行,然后第一个/最后一个将 margin-top/margin-bottom 设置为 0 即可。或者干脆换成 padding 也可以。
或者将元素设置为 inline
也能达成消除重叠的效果
为什么有重叠
因为 margin 表示的是元素隔开的距离。当两个不同 margin 的元素放在一起,会选择 margin 值最大的。另外如果没有这种重叠效果,跟 padding 还挺像的[2]……
作为第一个或最后一个子元素的 margin 问题
这个是比较诡异的地方了。
123456789101112<style>* { color: white;}</style><div style="background: rgb(48, 103, 133)">before</div><div style="background: rgb(214, 3, 17);"> <div style="margin-top: 1em;">inner-first</div> <div style="margin-bottom: 1em;">inner-last</div></div><div style="background: rgb(48, 103, 133)">after</div>
可以看到,父元素的高度并没有被子元素的两个 margin 撑开[3],而是跑到外面去了,他们看起来变成了父元素的 margin。如果给父元素加上 margin-top: 1.2em;
会发现它们之间也有重叠的特性。
更有趣的是,若父元素设置了 border
或者 padding
,它的高度就会被撑开了。