CSS 教程 / CSS 字体、字号与行高:回退字体和继承计算

使用 font-family 定义后备字体列表,使用 font-size 设置文本大小,使用 line-height 控制行间距。无单位的行高会随着每个元素的字体大小缩放,使继承的文本样式更易管理。

定义有序的字体回退列表

body {

  font-family: "Noto Sans SC", "Microsoft YaHei", sans-serif;

}

浏览器按顺序检查字体列表。如果某种字体不可用或缺少某个字符,则可以由另一种字体渲染该字符,因此一句话可能使用多种字体。sans-serif 是一个不带衬线的通用字体族,而不是特定的字体产品。为包含空格的字体名称加引号。

在 font-family 中列出字体不会下载它。示例把 Noto Sans SC、Microsoft YaHei 和 sans-serif 依次列为候选,只使用设备上可用的字体,不下载额外网页字体。要使用网页字体,请通过 @font-face 或提供者样式表提供其实际文件,并检查其 URL 及使用权限。参见 MDN:font-family。

为每个角色选择字体大小和粗细

属性 示例值 检查结果
font-size 正文 1rem,标题 2rem 如果根字体为16px,则为16px·32px
font-weight 正文 400,标题 700 普通字母与加粗字母的区别
line-height 文本 1.6 行高等于字体大小的1.6倍

rem 基于 HTML 字体大小。不同的浏览器偏好设置可能导致相同的 1rem 显示为不同的像素值。在因为文本看起来太小而将其更改为固定像素之前,请检查根值和实际字体。即使大小相同,视觉大小和换行位置也会因字体设计而异。在选择单位时,首先区分 CSS 颜色和单位:px、em、rem 和百分比 。

400 通常对应于 normal,而 700 对应于 bold。结果会根据字体提供的字重而有所不同,缺失的字重可能会被相近的值替代或合成。文档中的重要含义使用 HTML 的 strong 表示,视觉粗细则通过 CSS 控制。并非所有加粗字母都有语义上的重要性。

比较无单位和 em 的行高继承

line-height 有助于确定行框高度;它并不只是字符之间的空隙,也不等同于字形高度。段落间距则单独使用 margin。更多细节,请参见 CSS 段落和列表样式。

当父元素的字体大小为16px,而子元素的字体大小为32px时进行比较。父元素设置 line-height: 1.6 时,子元素继承倍数本身,导致子元素的行高为51.2px。line-height: 1.6em继承了从父元素计算得出的25.6px的长度。如果子元素的大字号文字跨越多行,这些行可能显得拥挤或重叠。

父元素声明 父元素字号为 16px 时的行高 子元素字号为 32px 时的行高
line-height: 1.6 25.6px 51.2px
line-height: 1.6em 25.6px 25.6px

这些继承计算假设子元素没有单独的 line-height 声明。子元素上声明的值优先于继承的值。无单位行高使调整标题和其他文本大小变得更容易,同时保持比例的行高。参见 MDN:line-height。

限制阅读宽度

max-width: 65ch 使用字体中“0”字形的步进宽度(advance width)来限制阅读宽度。这并不保证每行恰好 65 个字符。实际换行取决于字体、字重、字符和可用宽度。通过阅读实际的长段落来选择有用的宽度。

CSS 长度参考定义了与字体相关的单位,包括 ch,并解释了它们的参考测量。请参见 MDN:长度 。

检查渲染的字体和计算值

将下面的完整代码以 UTF-8 格式保存为 fonts.html,并在浏览器中打开。包括小号字体段落和 32px 对比段落,以便你检查大小和行间距之间的关系。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Compare fonts and line spacing</title>
  <style>
    html { font-size: 100%; }
    body { margin: 24px; color: #333; font-family: "Noto Sans SC", "Microsoft YaHei", sans-serif; }
    main { max-width: 65ch; }
    h1 { font-size: 2rem; font-weight: 700; }
    .copy { font-size: 1rem; font-weight: 400; line-height: 1.6; }
    .compare { font-size: 16px; margin-block: 24px; padding: 16px; background: #eef6f2; }
    .unitless { line-height: 1.6; }
    .length { line-height: 1.6em; }
    .large { margin: 0; font-size: 32px; }
  </style>
</head>
<body>
  <main>
    <h1>Small Garden fonts</h1>
    <p class="copy">The garden has plants that prefer sunlight and plants that grow in shade. Read their labels to find a suitable location for each one. Adjust the line spacing of this long paragraph to compare how easily the same text can be read.</p>
    <h2>Unitless line height</h2>
    <div class="compare unitless"><p class="large">Line spacing scales with the font size.</p></div>
    <h2>Line spacing specified by em</h2>
    <div class="compare length"><p class="large">The computed line height is inherited from the parent.</p></div>
  </main>
</body>
</html>
  1. 在开发者工具中选择正文段落。Computed 中的 font-family是候选字体列表,并不保证是实际使用的字体名称。在 Chrome·Edge 中,你可以在 Computed 下的 Rendered Fonts 查看实际使用的字体。其他浏览器可能具有不同的菜单结构,例如专用的字体面板。
  2. 比较两个.large段落计算得到的行高。无单位值为51.2px,em值为25.6px。将第二个父元素的1.6em改为1.6,看看差异是否消失,然后再改回。
  3. 将.copy的行高分别改为1.2和1.8。确保在保持字体大小的同时行位置有所变化。仅凭短短一行句子很难看出差异,所以使用较长的段落。
  4. 将main的最大宽度改为45ch。检查段落是否提前换行,然后再改回65ch。如果你的窗口宽度已经很窄,改变上限可能只会有很小的差异。

Chrome 开发者工具本地字体指南 还解释了如何检查已渲染的字体。如果预期的字体缺失,请检查其安装情况和支持的字符。对于单独链接的网络字体,请在 Network(网络)面板中检查字体请求的响应和被阻止的错误。已本地安装的字体可以在不发起网络请求的情况下使用,因此仅凭请求缺失并不表示字体失败。