font-size设置的是什么?line-height设置的是什么?各种行高是怎么计算出来的?你真的知道吗?

1 从font-size讲起,说文字高度:

当你按住鼠标左键选中一段文字的时候,这段文字背后会有一个颜色变化的区域,这个区域可以近似的视为是这段文字的content-area(内容区域)。

又或者当我们给一行文字设置background的时候,文字背景所占的区域可以近似的视为是这段文字的content-area(内容区域)。

我们通常用content-area的高度代表文字高度 ,这是字体设计领域的一个概念。

你先别质疑这种思想!我们知道有些文字的样子喜欢往上突出,有些文字喜欢往下突,再者,行与行文字之间需要一定的空间,所以content-area在上下两个区域预留出空白的区域是很正常的,如图:


先说结论:

font-size 相同时,font-family 不同,得到的文字高度也不同:

上图表明,同样是font-size为100px,三款不同字体在浏览器画面上的高度是不同的。

我们再来分析一下,在font-size设置为100px时,Catamaran字体的那164px是怎么构成的:

我们假设画面由相对单位构成方便缩放拉伸,再假设现在1px对应画面上的10个相对单位。(这点你可以不用理会)

那么我们所能设置的font-size: 100px其实设置的是上图左方1000个单位(em-square)这部分的高度而已; 我们可以把em-square区域视为content-area的主体区域。

(em-square这个概念的产生是有历史原因的,但是这点我们不用理会。)
em-square之内,图中"B"上方预留的小区域,大概是考虑到有些字母模仿手写体会有起笔效果,需要一定的位置;"a"下方预留的区域是为了写类似g这样的字母的时候,下方需要一定的区域。
em-square之外,上方和下方都预留了一定空白区域,这样可以防止行与行间文字挤在一起。
事实上对于所有font-family而言,规则都是这样的,对于中文字体而言也是如此。
我们可以得到第二个结论:

font-size不能直接控制文字的高度(content-area的高度),它控制的是文字主体部分的高度(em-square的高度)。 而content-area和em-square之间的比例,完全是由字体设计师决定,作为程序员是无法统一的。

所以再经过调查, 没有属性能直接控制文字的高度,我们只能这样通过font-size间接 控制文字的高度。

2 计算一个p元素的内容高度

(我们既然说是内容高度,就直接把margin、border厚度、padding排除在外了。)

当 p 元素出现在屏幕上时,它可能包含了多行的内容,其内容高度由每一行的高度堆叠而成。这点很好理解。

2.1 line-box的默认高度

每一行可视为一个line-box。通常来讲,line-box的默认高度是由这一行的内容撑大的,这一行里面的元素谁的高度最大,line-box的高度就等于它,由它撑大:

<p>Good design will be better.<span class="a">Ba</span><span class="b">Ba</span><span class="c">Ba</span>We get to make a consequence.
</p>

如图,我们给class=“a”、class=“b”、class="c"设置了不同的font-family或者font-size,导致这些文字的高度各不相同。每一个line-box代表每一行的区域。一个line-box的默认高度由这行内的最大高度决定。

补充:还记得吗?对于文字而言,文字高度就是它的content-area的高度。

3 line-height的作用

当我们没有设置line-height的时候,一个line-box的默认高度由这行内的最大高度决定。

所以通常情况下,line-box的高度 >= content-area的高度 > em-square的高度

当我们设置了line-height的时候,line-box的高度就是由line-height所设定的。 因此此时我们可以把line-box的高度设置得比content-area甚至em-square小,导致文字看上去挤在一起。

一行内的内容,除了文字外;通常就是行内块级元素了,通常可以分为三类:

  • img元素、input元素、svg元素等
  • display:inline-block、display:inline-table、display:inline-flex 的元素
  • 处于某种特殊格式化上下文的内联元素:例如 flexbox 元素中的子元素都处于 flex formatting context(弹性格式化上下文)中,这些子元素的 display 值都是「blockified」
    这些行内块级元素,其所占的高度通常由height,margin,border,padding盒子模型的高度来决定。

如果你将其 height 设置为 auto 的话,那么其高度的取值就是 line-height,其 content-area 的取值也是 line-height。

4 line-height是怎么计算的

官方对line-height的定义是:

两行文字基线(baseline)之间的距离。

4.1 额外谈谈"基线"

为什么是基线呢?

line-height可不可以定义为是两行文字的“中线”之间的距离呢?

可不可以定义为是两行文字的“底线”之间的距离呢?

张鑫旭认为都是都可以的。

那么为什么选基线作为定义的依据?

因为, 基线乃其他线定义之根本也。

了解“基线”大有好处。

回到刚才那幅图:

这么多线,都是字体设计师为了比对位置用的。这几条线,可以视为是字体设计的度衡。任何一款字体都会给出以上各种线的位置参数,所有线的位置参数都是相对于基线的位置而确定的 。我们把某款字体放到 FontForge 中,分析它的字体度量:

首先说明的是HHead Ascent是针对macOS的计算值,Win Ascent是针对Windows系统的计算值,这点可以不用理会。

设计一款字体的时候从基线开始定位。

我们看到,Em Size设置为1000,就是基线到基线以上1000个单位的那片区域都是em-square的区域。

Ascent设置为770,就是Ascender线距离基线770个单位。

Descent设置为230,就是Descender线距离基线230个单位。

Capital Height是680,也是相对于基线的。是大写字母顶部位置的线距离基线多少。

X Height是485,也是相对于基线而言的。是小写字母顶部位置的线距离基线多少。

Ascender线到Descender线之间的高度 加上Line Gap就是content-area的总高度。(笔者注:这点可能有误)

所以说,我们选基线来定义line-height:line-height是两行文字基线(baseline)之间的距离。

但是这个定义说了等于没说,因为它不能告诉我们怎么设置line-height啊!

还是我们早之前做的定义比较棒!!当我们设置了line-height的时候,line-box的高度就是由line-height所设定的。

4.2 line-height的计算(画重点!)

line-height的计算要根据这行文字的font-size多少 ,即是根据em-square的高度计算。本文说的"计算"就是这个意思。

w3c说,line-height可以设置的值有5种:

  • normal
  • 数字
  • 多少px(都写死了,不必计算)
  • 百分数(多少%)
  • inherit(对于该元素而言,不必计算)

4.2.1 line-height:normal的时候

我们来看看 Arial 字体,它的 em-square 是 2048,ascender 是 1854,descender 是 434,line gap 是 67。那么当 font-size: 100px 时:

line-height:normal为 100/2048*(67+1854+434) 约为 115px

4.2.2 line-height设为数字/百分数的时候

line-height设为数字/百分数的时候,line-height就是拿 数字/百分数 去乘以em-square的高度。

所以如果设置line-height:1或者line-height:100%肯定是有问题的啊——本来em-square基本上就比content-area要小,你还让line-height是em-square的高度的一倍?!行与行之间的文字绝对是要挤在一起了:

那怎么设置呢?反正line-height最终的计算结果超过content-area就应该比较符合常理了。

张鑫旭大神鼓励大家用数字来设置line-height。

  • 如果是博客类型的网站,line-height设置为1.5到1.6,行与行之间比较宽,适合舒适地阅读。
  • 如果是研发正规的产品,推荐大家使用20px匹配法 ,方便计算。

4.2.3 20px匹配法

为什么呢?

首先我们一般来说会设置font-size在14px到16px之间,然后content-area的高度也不会比这个高太多的吧。所以我们想着让line-height设置为20px应该够用了。而且20px方便计算。像这样:

body { font-size: 14px; line-height:??? }

只要把???结果计算出来就行啦!

20除以14等于1.42857后面还有小数位。

如果你写line-height:1.42857,虽然它乘以14非常接近20,但是没有超过20,chrome会把它设置为19px。

所以我们一般设line-height为1.4286,稍微大那么一点点,chrome把它们乘起来,然后再约等于,就是20px了。

结果写法就像这样:

body { font-size: 14px; line-height: 1.4286; }

或者

body { font-size: 14px/1.4286 'microsoft yahei'; }

4.2.4 补充:line-height: 1.5和line-height: 150%的区别?

这是一个在网上被人讲烂了的知识点了,line-height设置为数字和百分数时之间的区别:

  • line-height:1.5: 所以可继承元素根据font-size重新计算行高
  • line-height:150%: 当前元素根据font-size计算行高,继承给下面的元素
  • line-height: 1.5em :当前元素根据font-size计算行高,继承给下面的元素(与百分比效果相同)
<style>
.parent { font-size: 30px; }
.child { font-size: 60px; }
.p1 { line-height: 1.5; }
.p2 { line-height: 150%; }
</style>
<body>
<div>
<p class="parent p1">文字<span class="child">算出子级line-height为90px</span>文字</p><hr>
<p class="parent p2">文字<span class="child">算出子级line-height为15px</span>文字</p>
</div>
</body>

5 后记:

5.1 全文总结

  • 首先文字高度和font-size只有间接的关系
  • 然后,line-height的计算是根据font-size的
  • 当我们没有设置line-height的时候,一个line-box的默认高度由这行内的最大高度决定。
  • 当我们设置了line-height的时候,line-box的高度就是由line-height所设定的。

5.2 预告:文字在一行中的位置的计算?

有没有发现?根据我们上面的理论,如果想要确定一段文字在一行(line-box模型)中的位置太难了!是不是垂直居中?文字位置偏上还是偏下?要经过一系列计算才能得出结论。

进而,我们联想到,平时我们想让行内元素垂直居中的办法:设置vertical-align:middle,这种居中方法是错的吗?

嗯,是错的,这只能使得行内元素近似垂直居中。

如果想要行内的文字或者图片完美居中,就要研究清楚line-height和vertical:middle的原理了。

你可以系统地看一看张鑫旭在慕课网上的视频教程。如果急着想看结论,直接翻到他每个视频的最后一章就可以了。

或者你可以直接翻看我下一篇文章 深入理解vertical-align:middle 的结论。

本文标题:深入理解文字高度和行高的设置

文章作者:Alex Zhong

发布时间:2018-02-06, 13:15:57

原始链接:https://alexzhong22c.github.io/2018/02/06/height-calculate/

深入理解文字高度和行高的设置相关推荐

  1. 前端开发中表格table单元格高度或者行高的设置

    最近开发中遇到一个问题:在width一定的情况下,如何设置table的单元格高度? td的height.max-height属性设置以后,发现完全没有效果.后来多方收集资料后才明白,单元格高度由以下因 ...

  2. 深入理解css基线与行高

    一.基本概念 1.基线.底线.顶线.中线 注意:基线(base line)并不是汉字文字的下端沿,而是英文字母"x"的下端沿. 2.内容区 内容区是指底线和顶线包裹的区域(行内元素 ...

  3. 深入理解 CSS 中的行高与基线

    百度面试直接被面试官问住了,回来总结下css 行高相关问题! 1.基本概念 1.  基线.底线.顶线.中线 注意:基线(base line)并不是汉字文字的下端沿,而是英文字母"x" ...

  4. 深入理解CSS中的行高

    1.  基线.底线.顶线 行高指的是文本行的基线间的距离. 基线并不是汉字的下端沿,而是英文字母"x"的下端沿 2.  行距.行高 3.  内容区 底线和顶线包裹的区域,实际中不一 ...

  5. html5设置单元格行高,单元格的行高怎么设置 EXCEL文档怎么统一设置行高

    我要把有几行设置为同样的高度,可是一行一行的拉,太慢了. 在Excel中,如何设置表格最合适的行高.列宽? EXCEL中的单元格行高不够怎么调整可以自动调整,根据字的内容来调整: 请问怎么统一设置EX ...

  6. html table设置行高_单元格的行高怎么设置 html语言怎么设置设置表格行高?

    在Excel中,如何设置表格最合适的行高.列宽? 本次操作使用的软件为Excel电子表格,软件版本为office家庭和学生版2016. 小编只是难过不能陪你一起到老,再也没有机会,看到你的笑. 请问怎 ...

  7. html table设置行高_html5行高怎么设置 Excel做的表格怎么打印

    尝试了很多方法 CSS中设置行高 front-size 可以用 但是 line-heigh就不固定高度html源代码: 固定高度 .div-height{border:1px solid #F00; ...

  8. php中调行高代码_单元格行高怎么设置

    单元格行高怎么设置? 如图一张表,全选,全选的快捷键是Ctrl+A.全选之后第一种方法是直接用鼠标放到最前面的竖栏上,放在数据与数据之间交叉的框上,会出现一个+字的符号. 这个时候点击鼠标左键拉动,就 ...

  9. 前端html——文字水平位置 行高 文字样式

    line-height:文字在此行的高度中垂直居中 line-height: 2em;文字内容占2倍行高, em是参照当前文字的实际文字大小 需要设置字体大小,否则为默认高度 text-indent: ...

最新文章

  1. [JS,CSS] - CSS圆角框组件
  2. php正则表达式2,php正则表达式(2)
  3. R语言KMeans聚类分析确定最优聚类簇数实战:Calinski-Harabasz准则(确定最优聚类簇数)
  4. 给热爱学习的同学们推荐一些顶级的c# Blogs链接
  5. web自动化测试常见面试题
  6. CentOS下Yum使用
  7. 【计算机组成原理】定点运算器的基本结构
  8. JavaEE 7 正式发布
  9. Lanstar v2.2.0跨年版 三栏简约的typecho主题
  10. OpenCV-数字图像处理之拉普拉斯算子
  11. 调试方法和技巧(zz)
  12. Java中List与ArrayList的区别及用法
  13. Jquery.ajax不能解析json对象,报Invalid JSON错误的原因和解决方法
  14. CodeForces - 786B Legacy (线段树+DIjkstra+思维)
  15. JavaScript 的语法(网摘)
  16. Linux基础学习记录
  17. 企业微信管理员可以看到打卡位置吗
  18. 设定自己的100个人生目标
  19. 性能测试工程师职业现状分析
  20. 物理挖洞之分块 !Cocos Creator !

热门文章

  1. MKB0805心率血压模块使用方法
  2. Django之restframework中路由Routers
  3. Python 数据分析微专业课程--项目实战11 中国城市资本流动问题探索
  4. android 层叠view,RecyclerView进阶之层叠列表(上)
  5. 校招回顾,大疆校招可内推
  6. 【转】Hibernate中session的clear(),flush(),evict()方法详解
  7. switch日版有中文吗_Switch中文系统终于到来!近日将推送更新,美版日版港版均支持...
  8. 关于条形码的属性与一些自定义操作
  9. 判断清浊音 matlab,基于MATLAB的语音信号的清浊音分析.docx
  10. 参与CSDN1024程序员节活动