为什么div的edge Rect会小于content Rect?display:table伪元素布局影响探究
问题解答
核心差异规则
四组代码的唯一差异为以下CSS规则:
.parent::after{ content: " "; display:table; }
核心前置原理
先明确几个CSS基础规则:
- 盒模型定义
- 内容矩形:对应元素的
border-box区域,是背景色覆盖的范围,默认高度由内部子元素渲染的最顶端到最底端位置决定。 - 边缘矩形:对应元素的
margin-box外边缘,是计算相邻元素布局间距的唯一参考,受margin合并规则影响。
- 内容矩形:对应元素的
- 垂直margin合并规则
同一个BFC下的块级元素,满足以下条件时会发生垂直margin合并:父子元素间没有border、padding、内联内容、独立BFC或占位元素隔开时,第一个子元素的顶部margin、最后一个子元素的底部margin会和父元素的对应margin合并,合并后的值直接作用在父元素的外边缘上,不会撑开父元素的内容高度。 display: table伪元素的作用
上述规则里的.parent::after是父元素的最后一个子元素,display: table会让它成为无高度的块级占位符,刚好隔开最后一个子元素(.child)的底部margin和父元素底部,阻止父子margin合并,子元素的margin会被包裹在父元素内部,直接撑开父元素的内容高度。
疑问1:为什么div的边缘矩形可以小于内容矩形?
当子元素设置负垂直margin,且和父元素发生margin合并时,合并后的负margin会把父元素的外边缘向内拉动,但父元素的内容矩形高度仍由子元素的content高度决定,就会出现边缘矩形小于内容矩形的情况。
比如无伪元素的负margin组中,.child设置了margin-bottom: -20px,和父元素合并后,父元素的底部外边缘被向上拉动20px,但父元素的背景还是覆盖到.child的content高度80px位置,就出现了内容矩形高度80px、边缘矩形高度仅60px的情况。
疑问2:为什么.other元素检测到的边缘矩形一致,但父元素内容矩形存在差异?
你观察到的现象刚好是margin合并被阻止/不被阻止的典型表现,我们分两组对照说明:
负margin对照(第一组/第二组)
- 第一组(有伪元素):伪元素阻止了margin合并,
.child的-20px margin作用在伪元素上,父元素内容高度被拉到60px位置,边缘矩形底部也在60px。 - 第二组(无伪元素):发生margin合并,
.child的-20px margin直接作用在父元素外边缘,父元素内容高度保持.child的content高度80px,边缘矩形底部被拉到60px。
→ 两组父元素的底部外边缘都在60px位置,所以.other的布局位置完全一致,但父元素内容高度分别为60px和80px,内容矩形存在差异。
正margin对照(第三组/第四组)
- 第三组(无伪元素):发生margin合并,
.child的20px margin溢出到父元素外,父元素内容高度为80px,边缘矩形底部被推到80+20=100px位置。 - 第四组(有伪元素):伪元素阻止了margin合并,
.child的20px margin被包裹在父元素内部,父元素内容高度被撑到100px,边缘矩形底部也在100px位置。
→ 两组父元素的底部外边缘都在100px位置,所以.other的布局位置完全一致,但父元素内容高度分别为80px和100px,内容矩形存在差异。
内容的提问来源于stack exchange,提问作者Wilkin Wendy
相关产品推荐
相关产品推荐

