在图片中可以看到 img 与外层的 div 存在一个间隙这是因为浏览器认为每一个 line box 的起始位置都存在一个宽度为 0 的,没有任何字符的 匿名 inline box(下文会提到的 strut),也就是说这个 匿名 inline box 的高度会影响整个 line box 高度的计算。
上文所说的 strut 其实就相当于一个不可见的字母 x,父元素的基线就是 strut 的基线所在的位置。而 strut 本身是具有 line-height 的,所以就导致图片底部多了一段间隙。
总结一下存在间隙原因:
strut 存在 line-height
vertical-align 默认值为 baseline
对应的解决方案:
修改 strut 的 line-height,因为 strut 的 line-height 不是能够直接设置的,所以需要设置父元素的 line-height,然后让 strut 继承,或者修改 font-size
将 vertical-align 设置为其他值
<div>我是一个匿名 inline box <em>我是一个 inline box</em> 我是另一个匿名 inline box</div>
IFC 中有两种盒子:inline-level box 和 line box。多个 inline-level box 组成了一个 line box。
line box 高度计算
浏览器会计算 line box 中每一个 inline-level box 的高度,对于不同的 inline-level box 计算方式有所不同。如果是一个替换元素,高度由其 margin box 决定,如果是一个非替换元素,高度由它的 line-height 决定。
line box 中所有 inline-level box 的最高点以及最低点决定了它的高度(该计算包括了 strut 的高度,后文 line-height 中提到 strut)。
img 所在的 line box 最高点是图片的顶部,最低点是 strut 的底部。img作为一个 inline-level box,它的高度就是图片的高度,而 strut 其实就是个普通的文字,再加上 vertical-align: baseline 的作用,最终撑开了整个 line box。多个 line box 堆叠起来就撑开了父元素的高度,在这里只有一个 line box,撑开了 div>的高度。
非替换元素的的 margin,padding 以及 border 并不会影响 line box 高度的计算。当一个 inline-level box 的 line-height 小于 content area 的时候,line box 的高度就会小于 content area(line box 的高度与 content area 是没有关系的),此时元素的 background 以及 padding 等就会溢出到 line box 之外。
div {
background: #eee;
border: 1px solid #000;
box-sizing: border-box;
font-size: 50px;
line-height: 10px;
}
span {
background: red;
margin: 10px;
padding: 10px;
}
<div><span>xxx</span></div>
我的简单理解是,对于由行内元素组成的块级元素而言,line-height 决定了 line box 的最小高度,浏览器会假定每一个 line box 以一个宽度为 0 的 inline box (strut)开始,而这个 strut 从父元素继承到 font 以及 line-height。(issue 开头的例子就是 strut 造成的)
baseline:元素基线与父元素基线对齐,如果元素没有基线,比如 ,则使用 margin 底边与父元素基线对齐。
middlee:元素的垂直中点位置与父元素的基线加上一半 x-height 的位置对齐。
借鉴于https://www.jianshu.com/p/1d9bd8959711