怪异的margin-top百分比

引子

在我们日常前端开发中,特别一些新入门的前端,往往对margin/padding的百分比有错误的认知。最近面试时有遇到过这个问题,由于对这些小知识点的忽略而凭借自己的直观印象而回答错误,所以做下梳理与记录。

面试官问:假设一个div,宽400px,高200px,他有个子div的margin:10%,你来算下他的margin 的 top, right, bottom, left 是多少?

当时觉得事不单纯,但是没有其他的印象,所以就直接就回答了:20px 40px 20px 40px。直到后来回去自己做了下测试,才知道自己的错误。下面上DEMO,从DEMO中可以很直观的看到margin值都一样的长度,这里为40px 40px 40px 40px,也许这个结果令你吃惊,你对margin的百分比或许有了自己的想法。

结论

CSS2.1 Box model

The percentage is calculated with respect to the width of the generated box’s containing block. Note that this is true for ‘margin-top’ and ‘margin-bottom’ as well.

margin:百分比的计算基于生成框的包含块(父元素)的width(margin-top/bottom也是如此)。
padding同理

对于margin-left和margin-right很好理解,但是为什么margin-top和margin-bootom也是相对于父元素width而不是height呢

WHY

对于margin/padding-top/bottom 的百分比之所以按照 width 计算,目前主要有这么几种解释

相对于height计算会引起无限循环

正常流中的大多数元素都会足够高以包含其后代元素(包括外边距),如果一个元素的上下外边距是父元素的height的百分数,就可能导致一个无限循环,父元素的height会增加,以适应后代元素上下外边距的增加,而相应的,上下外边距因为父元素height的增加也会增加,如此循环。

基于排版的需求

之所以按照同一个width来计算,是为了要横向和纵向2个方向都创建相同的margin/padding,如果它们的参照物不一致,那用百分比就无法得到垂直和水平一致的留白。

至于为什么是width而不是height?这是因为CSS的基础需求是排版,因此水平和垂直方向其实并不是同等权重的,更精确的说,因为我们常见的书写方向是横排文字,我们排版的水平宽度是一致的,而垂直方向上是可以向下无限延展的。对于竖排文字则相关, margin/padding-* 都按照 height计算。

对于受书写模式或者说排版方向影响还有一些其他的特性,比如说传统横排时,两个块状盒子margin在垂直方向上的 collapse(合并),段落间的空白进行 collapse 是常见和方便的。此时对于竖排,则是margin在水平方向上的collapse(合并)。

参考

CSS中margin-top/bottom(padding-top/bottom)百分比为何以最近的块级祖先元素的宽度而不是高度作计算?

如果文章有用,请随意打赏