几个概念
line box:包裹 inline box 的一个 盒子 ,一个或多个 line box 堆叠 撑起一个 HT ML 元素。 inline(-level) box:可以是一个由 行内元素 包裹的盒子,也可以是一个纯文字的匿名盒子。 content area:对于非替换元素来说,content area 的范围由 font -s ize 以及字体本身决定;对于替换元素来说,由元素自有 宽 高决定。 baseline:一个元素基线的位置由该元素内字母 x 底部所在的位置决定,当然字体不同基线所在的位置也就不同。通过一段代码可以理解一下:
div { background-color: # ccc; font- Size: 20px; color: #fff; } span { color: red ; } <div>文字1<span>文字2</span>文字3</div>
白色 的文字就是一个匿名 inline box, 红色 的文字是一个由 span 包裹的 inline box。这三个 inline box 组成一个 line box,可以理解为灰色的区域,因为在这个例子里就是由一个 line box 撑开了 div 。如果有多行的文字,那就有多个 line box。
关于 content area,W3C 有一段这样的解释:
CSS 2.1 does not define w hat the content area of an inline box is (see 10.6.1 above) and thus different UAs may draw the backgrounds and borders in different places.这篇文章 对非替换元素 content area 的定义就是自有宽高加上 m arg in,padding 以及 border。我认为 应该 将 content area 理解为 content box。
line box 高度
浏览器会计算 line box 中每一个 inline box 的高度,对于不同的 inline box 计算方式有所不同:
如果是一个替换元素(比如 img , input ),inline-* 元素 或者 是 flexbox 中的子元素,高度由其 mar gin box 决定;
inline-block 元素:
div { background-color: #ccc; color: #fff; } span { dis play : inline-block; h ei ght: 30px; margin: 10px; background: #fff; color: red; } <div>xxx<span>xxx</span>xxx</div>
这里 span inline box 的高度就是 height + margin 2 。如果 height 的值是 auto,高度就是等于 line-height + margin 2。
如果是一个非替换元素,高度由它的 line-height 决定,而不是 content area,虽然有时候看起来像 content area 撑开了 line box 的高度。
div { background-color: #ccc; font-size: 20px; color: #fff; font-f ami ly: Sana; } span { background: #fff; color: red; } <div>xxx<span>xxx</span>xxx</div>
这张图片可以明显地看出撑开 line box 的是 line-height,而不是 content area。
这篇文章 用了 virtual-area height 来表示 line-height 撑开的高度,而我的理解其实就是 inline box 的高度。
line box 中所有 inline box 的最高点以及最低点决定了它的高度(该计算包括了 strut 的高度,后文会提到 strut)。
非替换元素的的 margin,padding 以及 border 并不会影响 line box 高度的计算。当一个 inline-level box 的 line-height 小于 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>
leading:
content area 的高度与 inline box 的高度差就是 leading,这个 leading 会等分被添加到 content area 的顶部与底部,所以说 content area 永远 位于 inline box 的中间(垂直居中)。
strut:
浏览器认为每一个 line box 的起始位置都存在一个宽度为 0,没有任何字符的 匿名 inline box,称为 strut,这个 strut 是会从父元素继承 line-height 的,因此它的高度会影响整个 line box 高度的计算。
一个例子
div { background: #eee; border: 1px solid #000; box-sizing: border-box; } <div><img src="./image.png" alt=""></div>
在图片中可以看到 img 与外层的 div 存在一个间隙,这就是上文提到的 strut 造成的。
在这个例子中,默认情况下 img 的底边与父元素的基线对齐( img { vert ical -align: baseline } ),而这个基线实际上就是 strut 基线所在的位置。如下图所示:
strut 其实就相当于一个不可见的字母 x,上文已经提到 strut 本身是具有 line-height 的,所以就导致图片底部多了一段间隙。
总结一下存在间隙 原因 :
strut 存在 line-height vertical-align 默认值为 baseline对应的解决 方案 :
修改 strut 的 line-height,因为 strut 的 line-height 不是能够直接设置的,所以需要设置父元素的 line-height,然后让 strut 继承,或者修改 font-size 将 vertical-align 设置为其他值line-heightW3C 中对于 line-height 的解释是这样的:
On a block cont ai ner element whose content is composed of inline-level elements, 'line-height' s PE cifies the minimal height of line boxes w IT hin the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height PR operties. We call that imaginary box a "strut."我的 简单 理解是,对于由行内元素组成的块级元素而言,line-height 决定了 line box 的最小高度,浏览器会假定每一个 line box 以一个宽度为 0 的 inline box (strut) 开始 ,而这个 strut 从父元素继承到 font 以及 line-height。
normal 是 line-height 的默认值,W3C 对它并没有一个 明确 的定义。normal 会将 content area 作为一个计算 因素 。 line-height 并不是两条 baseline 之间的 距离 。 line-height 的值推荐使用数值,而不是使用 em 单位,因为 em 单位会根据从父元素继承到的 font-size 来计算行高。vertical-align
W3C 对 baseline 以及 middle 的定义如下:
baseline: Align the baseline of the box with the baseline of the parent box. If the box does not have a baseline, align the bottom margin Edge with the parent's baseline.元素基线与父元素基线对齐,如果元素没有基线,比如 img ,则使用 margin 底边与父元素基线对齐。
middle: Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.元素的垂直中点位置与父元素的基线加上一 半 x-height 的位置对齐。
参考
Deep dive CSS: font metrics, line-height and vertical-align
https://meyerweb测试数据/eric/css/inline-format.html
https://HdhCmsTestzhangxinxu测试数据/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/
https://HdhCmsTestw3.org/TR/CSS2/visudet.html#inline-box-height
总结
以上是 为你收集整理的 深入理解 line-height 和 vertical-align 全部内容,希望文章能够帮你解决 深入理解 line-height 和 vertical-align 所遇到的问题。
如果觉得 网站内容还不错, 推荐好友。
查看更多关于深入理解 line-height 和 vertical-align的详细内容...