博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字号与行高
阅读量:4117 次
发布时间:2019-05-25

本文共 2895 字,大约阅读时间需要 9 分钟。

640?wx_fmt=jpeg

作者 | 李银城

原文 | https://zhuanlan.zhihu.com/p/27381252

1. 什么是字号与行高

什么是字号大小?字号大小就是字体的高度,例如设置字号为50px,那么它的高度如下图所示:

640?wx_fmt=png

什么是行距呢?如下图所示:

640?wx_fmt=png

其中半行距 = (lineHeight – fontSize) / 2。

但是实际上,font-size经常不等于渲染的高度,如下图所示:

640?wx_fmt=png

对于笔者用的ProximaNova这个字体,设置font-size为30px,实际上高度为42px。为什么文字的高度不等于字号的高度?这得从字体设计说起。为此装了一个FontForge和RoboFont软件设计一款自己的字体。

2. 设计字体

打开RoboFont,如下图所示:(这个软件经常闪退,需要注意保存)

640?wx_fmt=png

双击l和y两个字母,用钢笔工具勾勒形状,如下图所示:

640?wx_fmt=png

从上图可以看到它有一些刻度和度量线,画一个示意图如下所示:

640?wx_fmt=png

这些度量线的位置可以自己设置:

640?wx_fmt=png

Units Per Em表示一个字的高度有1000个单位,baseline的坐标为0,其它线的坐标相对于baseline,如下图所示:

640?wx_fmt=png

然后把这个设计好的字体导出为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:

640?wx_fmt=png

为什么我们设计的字体会如此“完美”,而其他人的字体高度总是要大一点呢?

3. 为什么字体高度大于字体大小

为此我们用FontForge打开ProximaNova.ttf,因为这个软件可以查看字体的更多信息,就是界面丑了点。如下图所示:

640?wx_fmt=png

然后点击Element -> FontInfo,切到OS/2的Metric标签,如下图所示:

640?wx_fmt=png

把鼠标放到相应的输入框,FontForge会提示你Windows系统是使用Win Descent和Ascent决定字体内容高度,而Mac是用的HHead Descent和Ascent。上面字体在Mac下的Ascent为1079,Ascent为-336,如下图所示:

640?wx_fmt=png

同时它的units of em仍然是1000,如下图所示:

640?wx_fmt=png

而它的内容区域content-area大小为1079 - (-336) = 1415是font-size 1000 unit的1415 / 1000 ~= 1.4倍,这就解释了一开始提出的问题:

640?wx_fmt=png

设置font-size为30px,实际上显示42px,因为30 * 1.4 = 42px,为进一步验证,把我们设计的字体my-font改一下它的Ascent,如下图所示:

640?wx_fmt=png

这样它的内容区域高度就变成了1250unit,是字号大小的1.25倍,导出为一个新的字体,在网页上使用,如下图所示:

640?wx_fmt=png

设置font-size为50px,它的content-area高度为50 * 1.25 = 62.5px。这就证明了上面的分析是对的。

那么为什么设计师们要这样搞呢,为什么不控制在1000个unit的范围内?首先因为常用的unit per em为有以下几个值:

640?wx_fmt=png

如果你的unit选得越大,那么曲线的光滑粒度可控制得更细,如下图所示:

640?wx_fmt=png

但是如果选1000的话,因为它是一个整千,比例什么的应该会比较好控制。

其次,大于1000可以让可控制的区域更大,一般不会让字刚好撑到底线和顶线,如下图所示:

640?wx_fmt=png

4. 字体的宽度

可以在RoboFont里面设置每个字的宽度,例如y这个字母我要让它比z占的空间小一点,如下图所示:

640?wx_fmt=png

y为400,z为500,也就是说y的宽度为高度的0.4,z的宽度为高度的0.5,因为高度是1000.

font-size为50px的时候,4个yz的宽度为180px,如下图所示:

640?wx_fmt=png

因为:(50 * 0.4 + 50 * 0.5) * 4 = 180px。

再讨论一个经典的问题。

5. 图片底部的空白

有以下html:

 

<div style="border:1px solid #ccc"><img src="/Users/yincheng/Desktop/2.png"></div>

在浏览器下面显示为:

640?wx_fmt=png

为什么图片不是和div底部贴在一起,而会有一点空白呢?

先来看一下这个空白有多大,如下图所示,设置div的font-size为40px,line-height为60px:

640?wx_fmt=png

div的高度为174,图片的高度为154,因此这里空白的高度为174 - 154 = 20px。

为了辅助说明,在img的后面跟上几个字母,如下代码所示:

 

<div class="img-container"><img src="/Users/yincheng/Desktop/2.png">lyz</div>

画上辅助线:

640?wx_fmt=png

这段空白的距离就是基线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贴在一起的。

完~

推荐图书

读书才是最好的学习。

我们都处在一个信息大爆炸的时代,每天围绕我们的信息就像洪水一般,但我一直认为,不管学习任何一门技术或者学科,获取知识最好的途径,就是静下心来去认真读一读与此相关的图书。

但我们要做到开卷有益的话,我们必须要读一些好书,不然就是浪费时间,与此同时还无法获取到自己想要的知识。

今天我为大家推荐的三本图书,是之前在100本前端图书推荐的系列文章里,均分享过,有PDF电子版,想看电子版图书的读者朋友们,可以自己去下载获取,里面分享的电子版图书,仅供学习使用,谢谢合作。

具体的可以到相关文章里去看看,文章如下:




图解CSS3:核心技术与案例实战

作者:大漠

当当
广告
购买

CSS权威指南(第三版)

作者:(美)迈耶 著,尹志忠,侯妍 译

当当
广告
购买

HTML 5与CSS 3权威指南(第2版 上册)

作者:陆凌牛

当当
广告
购买
推荐一本李银城作者写的图书:

高效前端:Web高效编程与优化实践

作者:李银城

当当
广告
购买

640?wx_fmt=jpeg

转载地址:http://ozdpi.baihongyu.com/

你可能感兴趣的文章
maven多工程构建与打包
查看>>
springmvc传值
查看>>
Java 集合学习一 HashSet
查看>>
在Eclipse中查看Android源码
查看>>
Android-Socket登录实例
查看>>
Android使用webservice客户端实例
查看>>
层在页面中的定位
查看>>
[转]C语言printf
查看>>
C 语言 学习---获取文本框内容及字符串拼接
查看>>
C 语言学习 --设置文本框内容及进制转换
查看>>
C 语言 学习---判断文本框取得的数是否是整数
查看>>
C 语言 学习---ComboBox相关、简单计算器
查看>>
C 语言 学习---ComboBox相关、简易“假”管理系统
查看>>
C 语言 学习---回调、时间定时更新程序
查看>>
C 语言 学习---复选框及列表框的使用
查看>>
第四章 - 程序计数器
查看>>
第七章 - 本地方法栈
查看>>
第十一章 - 直接内存
查看>>
JDBC核心技术 - 上篇
查看>>
JDBC核心技术 - 下篇
查看>>