前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入研究CSS字体度量及CSS 盒子

深入研究CSS字体度量及CSS 盒子

作者头像
用户1687375
发布2018-06-08 12:35:44
1.8K0
发布2018-06-08 12:35:44
举报
文章被收录于专栏:较真的前端

本文首发于[Godfery的博客]。

感谢Godfery为大家贡献的优秀文章,大家可以通过点击本文下方的阅读原文来访问Godfery的博客

这张图展示的是8种不同的字体,其中第一、第二个分别为 font-awesome图标、自定义的字体图标,其余字体依次为Avenir、Trebuchet MS、Arial、Helvetica、Hiragino Sans GB、STXihei。(源码地址:https://codepen.io/hiyangguo/pen/VXqQMB

这些字符的font-size:100px,但是占的高度却不一样。有的是 100px,有的大于 100px。另外可以看出,垂直方向并没有居中对齐。 这篇文章主要研究:

  • font 的工作原理及度量参数
  • CSS box models 的类型、定义

字体度量

要弄明白上面问题的答案,需要先从字体说起:

我们拿出其中Avenir、Helvetica、Hiragino Sans GB三种字体进行分析

由上图可知,在我们设置 font-size:100px 时,文字所占的高度分别为 137px、 115px 和 100px。

感觉有点懵啊。怎么 font-size:100px ,可是高度却由于字体不同,而不一样了呢? 在字体设计中一个字符所在的空间容器称为EM Square(也被称作“EM size”或者“UPM”)。

在传统的金属字模中,这个容器就是每个字符的实际金属块。每个字符的高度是统一的,这样每个字模可以整齐地放进行和块中(如下)。

字体的定义规则

  • 字母的高度被称为“em”,在数字化字体中 em 是空间的数字化定义总量。em的大小(以下均写为: EM size)通常是 1000 单位,在 TrueType 字体中,EM size 约定是2的幂,通常是1024或2048。
  • 根据其实际使用的单位,字体的度量可以根据一些设置来决定。注意,有些值是em-square之外的值。
  • 在浏览器中,相对单位是用于缩放用来适应所需的 font-size

字体的设置

这是一张详解字体设置的图例,图中各个属性的意义:

  • baseline (基线): 分隔 ascent 和 descent ,默认字符底端沿 baseline 排列,如图中的P,x,Ё(为俄文字符)
  • ascent (上升): 基线的上部分,字符最高处与 ascent 顶端可能有空白,由 font-family决定
  • descent (下降): 基线的下部分,字符最低处与 descent 底端可能有空白,由 font-family 决定
  • xHeight (X 字高): 小写字符 x 的高度,由 font-family 决定
  • capHeight (顶面高度): 大些字符 P 的高度,由 font-family 决定
  • lineSpacing (行间距): 在浏览器中一般 lineSpacing = ascent + descent
  • lineHeight (行高): 默认等于 lineSpacing,受 line-height 设置影响,如果设置 line-height,lineHeight 等于 line-height。
  • half-leading (半行距): 如果lineHeight > lineSpacing,则lineHeight 与 lineSpacing 之间会产生上下相等的空隙 (lineHeight - lineSpacing)/2 称为半行距(half-leading或 half lead strips)。

字符所占高度的计算

所以在了解了上面的概念以后,就可以解答为什么在 font-size:100px 的时候行高却不一样的问题。

首先,先下载一个专业的字体软件FontForge,这个软件运行在xquartz上,所以要两个都要装。

百度云通道( https://pan.baidu.com/s/1GqI-n39GkFQWsNZ8vWKMGg#list/path=%2F )

安装后我们以 Avenir 字体为例进行分析。

  • EM size 为 1000
  • ascent 为 1000 ,descent 为 366
  • capHeight 为 708
  • xHeight 为 468

注:浏览器使用HHead Ascent/Descent值(Mac)和Win Ascent/Descent值(Windows),并且这些值可能不同。

这意味着 Avenir 字体在 1000 单位的 EM size 中使用了 1000 + 366 个单位,也就是说 font-size:100px,其高度为 100px * (1000 + 366 ) ≈ 137px。 这个计算高度定义了 元素内容(Content area)高度 也就相当于 background 属性。

CSS box models

接下来我们深入的研究一下,CSS box models。你可能不知道什么CSS box models,不过说出来你可能不信,在实际工作当中恐怕你最常见的就是CSS box models。

Block Box/Containing Box (块盒子/包裹盒子)

比如有一段简单的文字,就有可能会有一些列的 box 。那么这个段落被称为 Containing Box ,之所以这么命名,可能是因为他包含了很多 box 吧。(呵…)当然你也可以称之为 Block Box,因为他就是一个块。简单来说Containing Box和Block Box其实是一个东西。

Inline Box (内联盒子)

在段落内部,有很多的 Inline Box。 这些 Box 不会像 Block Box 那样形成新的一⾏。

在上面的例子中, <em/> 标签包裹的 斜体元素 就是一个典型的 Inline Box。

Anonymous Inline Box (匿名内联盒子)

在段落内部,那些没有标记的Inline Box 则成为 Anonymous inline Box。

Line Box (行盒子)

所有Inline Box在Containing Box紧挨着排列,则会形成 Line Box。需要注意的是,Line Box是没办法直观看到的。

Content area

Content area 是围绕⽂文本的隐形框。 而且在字体度量这一小节我们也证明过了,它的高度由font-size决定。

更详细的定义及说明可以访问 CSS 规范2.1 中关于 视觉格式化模型(Visual formatting model)一节进行阅读。

地址:

视觉格式化模型

http://www.ayqy.net/doc/css2-1/visuren.html

9 Visual formatting model

https://www.w3.org/TR/CSS2/visuren.html

Inline Box 与 Line Box

Inline Box 如何影响 Line Box

Line box 的高度由 Line Box 中最⾼的 Inline Box(或Replaced Element)确定。 最⾼的 Inline Box 可以是⼀个 Anonymous Inline Box。

也可能是一个增加了line-height的 Inline Box。 由于增加了 line-height ,所以这个它会比其它的 box 更高。

可能是⼀个更⼤的 font-size 的 Inline Box,这使得这个 Inline Box ⽐其他 Inline Box更高。

由于浏览器器的不同,它也可能受到上标或下标的影响。 因为有些浏览器以影响Line box的方式渲染上标元素。

我们可以通过设置 <sup/>、<sub/> 的 line-height 为 0 来解决这个问题。

Inline Box 可能受到 Replaced Element(如:<img/>、<input/>、<svg/>) 的影响。

Inline Box 撑破 Line Box

正如我们所看到的, Line Box 将增加所有行内 Inline Box 的⾼度。

但是,有时候 Inline Box 的一部分会撑破 Line Box 的顶部或底部。例如一个拥有padding、margin、border 的 Inline Box 。由于 Inline Box 不能设定高度(设了也白设)。因此会在元素的上方和下方显示padding、margin、border,但并不会影响 Line Box。 注意:对于Replaced Element、inline-block行内元素padding、margin、border都会增加高度,所以Line Box 的高度也会受到影响。

浏览器将按照文档的先后顺序呈现 Line Box。 所以, 后续行上的 border 可能会覆盖上⼀行的 border和文本。

参考文章 行内元素垂直方向的layout 深入了解CSS字体度量,行高和vertical-align FontForge 与字体设计 - EM Square Deep dive line-height

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 较真的前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档