Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

详解 line-height 属性 —— HTML中一行文字是如何排布的?什么是内容区、行内框、行框? #3

Open
JuniorTour opened this issue Apr 22, 2020 · 7 comments
Labels

Comments

@JuniorTour
Copy link
Owner

JuniorTour commented Apr 22, 2020

一位前端工程师,写过的最多的代码一定是<div>, <span>等填满了文字内容的HTML标签,那么各位有没有想过在这些标签内的文字是如何排布的?

本文将详细介绍line-height、font-size等属性的来龙去脉,以及em框、内容区、行内框和行框等概念,深入剖析这一行文字在毫厘之中的奥秘。

1. font-size:生成 em框 与 内容区

首先,一个字符受字体内置配置以及 font-size 属性影响,会在其周围产生一个不可见的em框(em square)(如下图),font-size属性并不决定实际显示的字符尺寸,只是指定 em框 的高度(宽度则会因字符、字体不同,而不尽相同)。

em框与其中字符的具体大小、相对位置关系由字体内置值决定。

也就是说对于不同的字体,即使是同样 font-size 的同一个字符也会产生不同尺寸的em框,并与em框有不同的相对位置。

一个元素中多个字符的 em 框组合在一起,就形成了内容区,即下图粉色外边框所圈起来的部分。
内容区的高度就是 font-size 的值,而宽度则视内容(如一行中文字的个数)而定。

em-box-and-content-area

em 框的概念来自传统印刷行业,以下图为例,为了用活字字模组成一块整齐的印刷板,每个字模的高度必须保持一致,这个高度称为em,即大写字母M对应字模的高度。

MetalTypeZoomIn

参考资料:Design with FontForge: EM square

2. line-height和基线

line-height 属性的值规定的是两行文字基线之间的最小距离。

基线也是印刷行业中的术语,维基百科这样描述它:“A baseline is a line that is a base for measurement or for construction.”(基线是一条用于测量和构造的线)。

基线相当于一把尺子,水平地串在 em 框里,一个个字符就以基线为参照,整齐地“站”在基线上(如下图)。

baseline-line-height

基线的位置因字体而异,由字体内置值决定位于 em 框中特定的位置,如下图:

where-is-baseline

因为基线无法在浏览器中看到,所以我们以上图中每行文字的 underline 为参照来看基线,上述三行分别为不同的字体,但有相同的 font-size 。

这三行中相同的字,如落、孤,可以明显地看到与基线有着不同的位置关系,第一行字底部与基线有一点重合,而其余两行则和基线几乎没有重合。

因为这三种字体的基线在 em 框之中的位置是不同的。

声明line-height 属性后,两行文字的基线便按照这个值上下分开,行与行也相应的上下分开。

当行高大于字体高度,即line-height的值减去font-size的值大于0时,基线相隔的距离大于该行的行框高度时,两行文字便被分开。

l-h-big-than-f-s

当行高小于字体高度,即 line-height 的值减去 font-size 的值小于0时,基线相隔的距离小于该行的行框高度时,两行文字便会重合在一起。

line-height-small-than-font-size

3. 行间距、行内框与行框是什么

内容区的上下还会有行间距(leading),具体值为行高减去字符大小的一半,( line-height 减 font-size 除 2 )。
行间距可能是负值(行高小于字符尺寸),这时就会产生上图所呈现的行与行相互重合的现象。

行内框内容区行间距,其高度的计算公式是:font-size + (line-height - font-size),去掉括号即 line-height,也就是说行内框的高度就等于 line-height 的值。

同一行中可以有不同高度的行内框(如下图)。

行框的上边界由最高的行内框决定,下边界由最低的行内框决定。

line-box-1

4. 行与行之间最终的相对位置

一个行框包含着一整行的内容,各个行框之间上下紧密贴合排列,形成了最终呈现在页面上行与行之间的位置关系。

总结:

  • font-size的值决定一个字符的 em 框的高度,字符的大小由字体内置值决定、又受 em框 高度影响;
  • 一个行内元素(包括匿名元素)之中的所有 em框 组合形成内容区,内容区加内边距即行内元素背景颜色所应用的范围;
  • 内容区加上行间距line-height - font-size ),形成行内框
  • 最高的和最低的行内框决定了一个行框的高度;
  • 最终,各个行框上下紧密贴合形成了行与行之间的位置关系。

参考资料:
  1. 《CSS 权威指南(第三版)》,第六章、文本属性和第七章、视觉格式化

  2. W3C规范-9 Visual formatting model(可视化模型)/ 中文版

  3. 另一篇同样主题的博文:深入理解CSS中的行高,相互对照,加深理解。

  4. 慕课网上张鑫旭老师的两节课:line-height与内联元素的高度机制

@JuniorTour JuniorTour added the CSS label Apr 22, 2020
@Aze-ziv
Copy link

Aze-ziv commented Jan 6, 2021

应该是不同字体也产生一样的em框,只是不同字体在同样em框里的位置和大小等定义不一样吧

@JuniorTour
Copy link
Owner Author

应该是不同字体也产生一样的em框,只是不同字体在同样em框里的位置和大小等定义不一样吧

@Aze-ziv 你好,就我查到的一些资料来看,em框的尺寸是由字体自定义的,不同的字体应该会产生不同尺寸的em框。

参考资料:

Em-box vs the content-area of a non-replaced element:The em-box is the theoretical box (or square) around a font character of a given 'size' as designed by the font designer.

《CSS 权威指南 4th》中文翻译:Most fonts, as it turns out, don’t have em boxes whose heights match the character glyphs.

@Aze-ziv
Copy link

Aze-ziv commented Jan 15, 2021

感谢;那我们的font-size设置的就不是em框的大小了吧,有些奇怪

@Aze-ziv
Copy link

Aze-ziv commented Jan 15, 2021

Most fonts, as it turns out, don’t have em boxes whose heights match the character glyphs.:意指同个字的不同字体的字形(可视文字)与em框没有一个确定的关系;但是这个em框应该是和我们的font-size大小一样,不然怎么理解我们font-size如果设置为16px的em框大小呢

@Aze-ziv
Copy link

Aze-ziv commented Jan 15, 2021

1
如图设置字体line-height:1em;height:1em;font-size:200px;
与另一背景为200px高的方框同高,可理解为:em = font-size;则不同字体em框应该是一同大的

@JuniorTour
Copy link
Owner Author

1
如图设置字体line-height:1em;height:1em;font-size:200px;
与另一背景为200px高的方框同高,可理解为:em = font-size;则不同字体em框应该是一同大的

你好,我的理解是 font-size属性的值,指定的是 em框高度,而em框的宽度则是不同的字体、不同的字符各不相同。

所以不同字体em框应该是一同大的这个理解可能并不正确,
个人认为正确的应该是:不同字体em框宽高不尽相等

DEMO:https://jsbin.com/qozugihuci/edit?html,output
image

也可以参考正文中的这一段:
image

@Aze-ziv
Copy link

Aze-ziv commented Jan 29, 2021

感谢您的回答,是我的表述存在一些问题,em框的高度应该是相同的,我赞同您的观点

Repository owner deleted a comment from BhavyClover Jan 2, 2024
Repository owner deleted a comment from BhavyClover Jan 2, 2024
Repository owner deleted a comment from qfengthree Jan 2, 2024
Repository owner deleted a comment from a510734714 Jan 2, 2024
Repository owner deleted a comment from qfengthree Jan 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants