接下来将深入介绍 font-family
、font-size
、line-height
、vertical-align
等。
文字
文字是通过文字制作软件做出来的,如 fontforge。
制作文字时,有几根参考线。不同字体的参考线不同。
一般一共这 5 根参考线,不同的文字类型,这些参考线的距离会有所变化。
字体大小 font-size
设置的是文字的相对大小。
如活字印刷术:
字是刻在也正方型金属框内的,当金属框变大,字也应变大。
文字相对大小:1000、2048、1024等,无单位,表示相对大小(相当于金属框的大小)。
比如 Consolas 字体的相对大小是 2048(fontforge 软件):
当相对大小为2048时,顶线(Ascent)距离基线的距离是 1884,底线距基线的距离是514,所以顶线距底线的距离是 1884 + 514 = 2398 。
所以 Consolas 字体大小可记为 2398/2048 。
font-size
所以当给字体设置大小 font-size
为 200px 时,字体的实际大小是 200 * 2398/2048 ≈ 234px 。
<span>
M
</span>
span{
font-family: consolas;
font-size: 200px;
}
文字顶线到底线的距离,是文字的实际大小(content-area,内容区)。行盒的背景,就覆盖这个 content-area。
span{
background-color: aqua;
}
line-height
顶线向上延伸的空间,和底线向下延伸的空间,两个空间是相等的,该空间叫做 line gap,这个 gap 的大小默认是字体设计者决定的。
top 到 bottom 的距离,叫做 virtual-area,这个区域高度是可调的,即行高 line-height
。
line-height: normal
使用文字默认的 gap,
如 consolas 字体的默认 gap 是 0:
<p>
<span>
M
</span>
</p>
p{
background: red;
}
span{
font-family: consolas;
font-size: 200px;
background-color: aqua;
}
而 Arial 字体的默认 gap 就不是 0:
span{
font-family: Arial;
}
可以看到 <span>
的上下有一点红边,这个距离就是默认的 gap 了:
所以当把字体大小 font-size
和行高 line-height
同时设置为 200px 时(line-height
设置为 1 也一样),会出现这样的情况:
p{
background: red;
}
span{
background-color: aqua;
font-family: consolas;
font-size: 200px;
line-height: 200px;
}
原因正如之前介绍的,font-size
设置的是相对大小,实际的字体大小是 234px,而行高 line-height
设置多少就是多少,也间接导致 gap 转化为了负数。
因而 line-height
设置为 1 (或者和字体大小相同)是一种不好的做法。
另外,视觉上大多文字是出现在行盒中间的,可实际上文字处于哪个位置是由文字设计者决定的。
比如小写字母 p,就处于行盒的下部分位置:
正确的说法是:content-area
出现在 virtual-area
的正中间。因为上下的 line gap
是一定相等的。
所以想实现所有字体的行高合适,使字与字上下之间 0 空隙贴合,是不可能的(除非你对于每一种字体的每一个大小都设置对应的行高)。
最合适的行高就是默认行高 line-height: normal
了。
vertical-align
通过上文,我们知道,参考线取决于 font-family
、font-size
、line-height
。
来回顾一下参考线的布局:
对于一个元素,如果其子元素出现行盒,该元素内部也会产生参考线。
如
<p>
M
<span class="test">
M
</span>
<span style="background: gold;">
M
</span>
</p>
<span>
元素参考线确定后,<p>
元素也会产生参考线,这两组参考线默认情况下是基线对齐的(vertical-align: baseline
):
p{
font-size: 100px;
background: red;
}
.test{
background-color: aqua;
font-size: 150px;
vertical-align: baseline;
}
可以清晰地看出,字母 M 的底部就是基线。
这种对齐的方式就是通过 vertical-align
来设置。
如
.test{
vertical-align: super;
}
表示 <span>
元素的 基线 与其父元素 <p>
的 上基线(super)对齐:
可以看到,这样一来,导致父元素 <p>
的基线位置变化,旁边那个黄色背景的 <span>
的位置也跟着变化了。
vertical-align: sub;
表示<span>
元素的 基线 与其父元素 <p>
的 下基线(sub)对齐:
vertical-align: text-top;
表示 <span>
元素的 virtual-area 的顶边(top)与其父元素 <p>
的 顶线(text-top)对齐:
virtual-area 的顶边是受行高 line-height
影响的。
vertical-align: text-bottom;
表示 <span>
元素的 virtual-area 的底边(bottom)与其父元素 <p>
的 底线(text-bottom)对齐:
行盒组合起来可以形成很多行,每一行的区域就叫做 line-box(区分于行盒 inline-box),line-box 的顶边是该行内所有行盒中的最高顶边,底边是所有行盒中最低的底边。
line-box
是承载文字内容的必要条件,以下情况不生成 line-box:
- 元素内部没有任何行盒
- 元素内部字体大小为 0
vertical-align: top;
表示 <span>
元素的 virtual-area 的顶边(top)与 line-box 顶边 对齐;
vertical-align: bottom;
表示 <span>
元素的 virtual-area 的底边(top)与 line-box 底边 对齐;
vertical-align
取值为 数值 时表示相对于父元素基线的偏移量,可正可负。
vertical-align
取值为 百分值 时是相对于自身的 virtual-area 高度百分比,对于父元素基线的偏移量,也可正可负。
vertical-align: middle;
表示 <span>
元素的 基线(top)与 X 字母高度的一半位置 对齐;
可替换元素盒行块盒的基线
可替换元素,如图片 <img>
,它的基线位于图片的下外边距。
所以这就解释了之前提到的图片底部白边的问题,是因为图片的基线与其父元素基线对齐导致的。
表单元素,基线位置在内容的底边位置。
行块盒:
- 有文字时,最后一行有 line-box,用最后一行的基线作为整个行块盒的基线
- 没有文字时,基线位置在下外边距