什么是字号大小?字号大小就是字体的高度,例如设置字号为50px,那么它的高度以下图所示:css
什么是行距呢?以下图所示:html
其中半行距 = (lineHeight – fontSize) / 2。chrome
可是实际上,font-size常常不等于渲染的高度,以下图所示:浏览器
对于笔者用的ProximaNova这个字体,设置font-size为30px,实际上高度为42px。为何文字的高度不等于字号的高度?这得从字体设计提及。为此装了一个FontForge和RoboFont软件设计一款本身的字体。bash
打开RoboFont,以下图所示:(这个软件常常闪退,须要注意保存)dom
双击l和y两个字母,用钢笔工具勾勒形状,以下图所示:工具
从上图能够看到它有一些刻度和度量线,画一个示意图以下所示:字体
这些度量线的位置能够本身设置:ui
Units Per Em表示一个字的高度有1000个单位,baseline的坐标为0,其它线的坐标相对于baseline,以下图所示:url
而后把这个设计好的字体导出为my-font.ttf文件,在网页经过@font-face引入,以下代码所示:
@font-face {
font-family: 'my-font';
src:url('/Users/yincheng/Desktop/my-font.ttf');
font-weight: normal;
font-style: normal;
}复制代码
而后使用这个font-family,你会发现,这个字体的font-size和height几乎彻底一致,以下图所示,分别设置font-size为35px、45px、55px:
为何咱们设计的字体会如此“完美”,而其余人的字体高度老是要大一点呢?
为此咱们用FontForge打开ProximaNova.ttf,由于这个软件能够查看字体的更多信息,就是界面丑了点。以下图所示:
而后点击Element -> FontInfo,切到OS/2的Metric标签,以下图所示:
把鼠标放到相应的输入框,FontForge会提示你Windows系统是使用Win Descent和Ascent决定字体内容高度,而Mac是用的HHead Descent和Ascent。上面字体在Mac下的Ascent为1079,Ascent为-336,以下图所示:
同时它的units of em仍然是1000,以下图所示:
而它的内容区域content-area大小为1079 - (-336) = 1415是font-size 1000 unit的1415 / 1000 ~= 1.4倍,这就解释了一开始提出的问题:
设置font-size为30px,实际上显示42px,由于30 * 1.4 = 42px,为进一步验证,把咱们设计的字体my-font改一下它的Ascent,以下图所示:
这样它的内容区域高度就变成了1250unit,是字号大小的1.25倍,导出为一个新的字体,在网页上使用,以下图所示:
设置font-size为50px,它的content-area高度为50 * 1.25 = 62.5px。这就证实了上面的分析是对的。
那么为何设计师们要这样搞呢,为何不控制在1000个unit的范围内?首先由于经常使用的unit per em为有如下几个值:
若是你的unit选得越大,那么曲线的光滑粒度可控制得更细,以下图所示:
可是若是选1000的话,由于它是一个整千,比例什么的应该会比较好控制。
其次,大于1000可让可控制的区域更大,通常不会让字恰好撑到底线和顶线,以下图所示:
能够在RoboFont里面设置每一个字的宽度,例如y这个字母我要让它比z占的空间小一点,以下图所示:
y为400,z为500,也就是说y的宽度为高度的0.4,z的宽度为高度的0.5,由于高度是1000.
font-size为50px的时候,4个yz的宽度为180px,以下图所示:
由于:(50 * 0.4 + 50 * 0.5) * 4 = 180px。
再讨论一个经典的问题。
有如下html:
<div style="border:1px solid #ccc"><img src="/Users/yincheng/Desktop/2.png"></div>
在浏览器下面显示为:
复制代码
为何图片不是和div底部贴在一块儿,而会有一点空白呢?
先来看一下这个空白有多大,以下图所示,设置div的font-size为40px,line-height为60px:
div的高度为174,图片的高度为154,所以这里空白的高度为174 - 154 = 20px。
为了辅助说明,在img的后面跟上几个字母,以下代码所示:
<div class="img-container"><img src="/Users/yincheng/Desktop/2.png">lyz</div>
画上辅助线:
复制代码
复制代码
这段空白的距离就是基线baseline到div底边的距离。因为基线的坐标是0,底线的坐标为-250,因此基线到底线的距离为:
250 / 1000 * 40 = 10px
因为行高为60px,font-size为40px,因此底线到div的距离即半行距为:
(60 - 40)/ 2 = 10px
所以基线到div底边的距离就为:
10px + 10px = 20px
到这里就解释了为何会有空白,以及空白的大小怎么计算。
那怎么去掉这段空白呢,能够设置div的行高为0。而且须要注意的是在怪异模和有限怪异模式下,为了计算行内子元素的最小高度,一个块级元素的行高必须被忽略,因此即便不设置div的行高为0,图片也是和div贴在一块儿的。这个咱们在《从Chrome源码看浏览器如何构建DOM树》讨论过。
参考: