15 字体

目录

15.1 介绍

设置字体属性将是样式表最常见的用途之一。不幸的是,目前没有定义良好且普遍接受的字体分类法,并且适用于一个字体系列的术语可能不适用于其他字体系列。例如,“italic”(斜体)通常用于标记倾斜的文本,但倾斜的文本也可能被标记为Oblique, Slanted, Incline, CursiveKursiv。因此,将典型的字体选择属性映射到特定字体并不是一个简单的问题。

15.2 字体匹配算法

由于没有公认的通用字体属性分类法,字体属性与字体的匹配必须谨慎进行。属性按照定义明确的顺序进行匹配,以确保这个匹配过程的结果在不同的用户代理之间尽可能一致(假设每个用户代理都使用相同的字体库)。

  1. 用户代理创建(或访问)一个包含所有已知字体的相关CSS 2.2属性的数据库。如果有两个字体的属性完全相同,用户代理将选择其中一个。
  2. 在给定元素的情况下,对于该元素中的每个字符,用户代理将汇集适用于该元素的字体属性。使用完整的属性集,用户代理使用'font-family'属性选择一个暂定的字体系列。其余属性根据每个属性描述的匹配标准进行测试。如果所有其余属性都匹配,那么这就是给定元素或字符的匹配字体。
  3. 如果在步骤2中处理的'font-family'中没有匹配的字体,并且字体集中的下一个替代'font-family'存在,那么使用下一个替代'font-family'重复步骤2。
  4. 如果存在匹配的字体,但它不包含当前字符的字形,并且字体集中的下一个替代'font-family'存在,那么使用下一个替代'font-family'重复步骤2。
  5. 如果在步骤2中选择的字体系列中没有字体匹配,那么使用用户代理依赖的默认'font-family'并重复步骤2,使用在默认字体中获得的最佳匹配。如果无法使用此字体显示特定字符,那么用户代理可以使用其他方法为该字符确定合适的字体。用户代理应将每个没有合适字体的字符映射到用户代理选择的可见符号,最好是用户代理可用字体之一的“缺少字符”字形。

(上述算法可以优化,以避免为每个字符重新访问CSS 2.2属性。)

上面步骤2中每个属性的匹配规则如下:

  1. 'font-style' 是首先尝试的。'italic'如果在用户代理的字体数据库中有一个标记为CSS关键字'italic'(优选)或'oblique'的字体,则此字体满足要求。否则,必须完全匹配值,否则字体样式将失败。
  2. 'font-variant' 是接下来尝试的。'Small-caps'匹配(1)标记为'small-caps'的字体,(2)通过合成生成的小型大写字母的字体,或(3)所有小写字母都被替换为大写字母的字体。可以通过电子缩放正常字体中的大写字母来合成小型大写字母字体。'normal'匹配字体的正常(非小型大写字母)变体。字体不能缺少正常变体。仅提供小型大写字母的字体应作为'normal'字体或'small-caps'字体选择。
  3. 'font-weight' 是接下来匹配的,它永远不会失败。(请参阅下面的'font-weight'。)
  4. 'font-size' 必须在用户代理依赖的容差范围内匹配。(通常,可缩放字体的大小四舍五入到最接近的像素,而位图字体的容差可能大到20%。)进一步的计算,例如,通过其他属性中的'em'值,基于'font-size'的计算值。

15.3 字体系列font-family 属性

名称: font-family
值: [[ <family-name> | <generic-family> ] [, [ <family-name>| <generic-family>] ]* ] | inherit
初始值: 取决于用户代理
适用于: 所有元素
是否继承:
百分比: 不适用
媒体: 视觉媒体
计算值: 如指定

该属性的值是一个优先级排列的字体系列名称和/或通用字体系列名称列表。与大多数其他CSS属性不同,组件值由逗号分隔,以表示它们是备选项:

body { font-family: Gill, Helvetica, sans-serif }

尽管许多字体提供了“缺失字符”字形,通常为一个开口的方框,但顾名思义,这不应被视为字体中找不到字符的匹配项。(然而,它应被视为U+FFFD,即“缺失字符”字符代码点的匹配项。)

字体系列名称有两种类型:

<family-name>
选择的字体系列的名称。在最后一个示例中,“Gill”和“Helvetica”是字体系列。
<generic-family>
在上面的示例中,最后一个值是通用字体系列名称。定义了以下通用字体系列:

建议样式表设计者提供通用字体系列作为最后的备选项。通用字体系列名称是关键字,不能加引号。

字体系列名称必须用字符串加引号,或作为一系列的标识符不加引号给出。这意味着大多数标点字符和数字在每个标记的开头必须在未加引号的字体系列名称中进行转义。

例如,以下声明是无效的:

font-family: Red/Black, sans-serif;
font-family: "Lucida" Grande, sans-serif;
font-family: Ahem!, sans-serif;
font-family: test@foo, sans-serif;
font-family: #POUND, sans-serif;
font-family: Hawaii 5-0, sans-serif;

如果将标识符序列作为字体系列名称给出,则计算值为通过用单个空格连接序列中所有标识符而转换的名称。

为避免转义错误,建议对包含空格、数字或除连字符以外的标点符号的字体系列名称加引号:

body { font-family: "New Century Schoolbook", serif }

<BODY STYLE="font-family: '21st Century', fantasy">

未加引号的字体系列名称与关键字值'inherit'、'default'和'initial'或通用字体关键字('serif'、'sans-serif'、'monospace'、'fantasy'和'cursive')相同的情况不匹配'<family-name>'类型。为了避免与同名关键字混淆,这些名称必须加引号。请注意,'font-family: Times, inherit'因此是一个无效的声明,因为在该位置的'inherit'既不能是有效关键字,也不能是有效字体系列名称。

15.3.1 通用字体系列

通用字体系列是一种回退机制,当无法选择指定的字体时,它可以在最坏的情况下保留部分样式表作者的意图。为了获得最佳的排版控制,样式表中应使用特定的命名字体。

所有五种通用字体系列在所有CSS实现中被定义为存在(它们不一定需要映射到五种不同的实际字体)。用户代理应提供合理的默认选择,以最大程度地在技术限制范围内表现每种字体系列的特征。

鼓励用户代理允许用户选择通用字体的替代选择。

15.3.1.1 衬线字体

在CSS中使用的衬线字体的字形通常具有结束笔画、外扩或收缩的末端,或实际的衬线结尾(包括粗衬线)。衬线字体通常是按比例间隔的。与'sans-serif'通用字体系列的字体相比,它们通常显示出更大的粗细笔画之间的差异。CSS使用'衬线'这个术语来应用于任何书写系统的字体,尽管对于特定的书写系统,可能有更熟悉的名称,例如明朝(日本)、宋体(中国)、Totum或Kodig(韩国)。任何如此描述的字体都可以用于表示通用的'衬线'系列。

符合此描述的字体示例包括:

拉丁字体 Times New Roman, Bodoni, Garamond, Minion Web, ITC Stone Serif, MS Georgia, Bitstream Cyberbit
希腊字体 Bitstream Cyberbit
西里尔字体 Adobe Minion Cyrillic, Excelsior Cyrillic Upright, Monotype Albion 70, Bitstream Cyberbit, ER Bukinist
希伯来字体 New Peninim, Raanana, Bitstream Cyberbit
日本字体 Ryumin Light-KL, Kyokasho ICA, Futo Min A101
阿拉伯字体 Bitstream Cyberbit
切诺基字体 Lo Cicero Cherokee

15.3.1.2 无衬线字体

在CSS中使用的无衬线字体的字形通常具有简单的笔画结尾——几乎没有或根本没有扩展、横划或其他装饰。无衬线字体通常是按比例间隔的。与'serif'系列的字体相比,它们通常显示出较小的粗细笔画之间的差异。CSS使用'无衬线'这个术语来应用于任何书写系统的字体,尽管对于特定的书写系统,可能有更熟悉的名称,例如Gothic(日本)、楷书(中国)或Pathang(韩国)。任何如此描述的字体都可以用于表示通用的'无衬线'系列。

符合此描述的字体示例包括:

拉丁字体 MS Trebuchet, ITC Avant Garde Gothic, MS Arial, MS Verdana, Univers, Futura, ITC Stone Sans, Gill Sans, Akzidenz Grotesk, Helvetica
希腊字体 Attika, Typiko New Era, MS Tahoma, Monotype Gill Sans 571, Helvetica Greek
西里尔字体 Helvetica Cyrillic, ER Univers, Lucida Sans Unicode, Bastion
希伯来字体 Arial Hebrew, MS Tahoma
日本字体 Shin Go, Heisei Kaku Gothic W5
阿拉伯字体 MS Tahoma

15.3.1.3 草书字体

在CSS中使用的草书字体的字形通常具有连接笔画或其他超出斜体字特征的草书特性。字形部分或完全连接,结果看起来更像手写的笔或刷子书写而不是印刷字体。对于某些书写系统,如阿拉伯语,字体几乎总是草书的。CSS使用'草书'这个术语来应用于任何书写系统的字体,尽管字体名称中也使用了Chancery、Brush、Swing和Script等其他名称。

符合此描述的字体示例包括:

拉丁字体 Caflisch Script, Adobe Poetica, Sanvito, Ex Ponto, Snell Roundhand, Zapf-Chancery
西里尔字体 ER Architekt
希伯来字体 Corsiva
阿拉伯字体 DecoType Naskh, Monotype Urdu 507

15.3.1.4 幻想字体

在CSS中使用的幻想字体主要是装饰性的,同时仍然包含字符的表示(与不表示字符的Pi或图片字体相对)。示例包括:

拉丁字体 Alpha Geometrique, Critter, Cottonwood, FB Reactor, Studz

15.3.1.5 等宽字体

等宽字体的唯一标准是所有字形具有相同的固定宽度。(这可能使某些书写系统,如阿拉伯语,看起来非常奇怪。)这种效果类似于手动打字机,并且经常用于设置计算机代码示例。

符合此描述的字体示例包括:

拉丁字体 Courier, MS Courier New, Prestige, Everson Mono
希腊字体 MS Courier New, Everson Mono
西里尔字体 ER Kurier, Everson Mono
日本字体 Osaka Monospaced
切诺基字体 Everson Mono

15.4 字体样式‘font-style’ 属性

名称: font-style
值: normal | italic | oblique | inherit
初始值: normal
适用于: 所有元素
继承性:
百分比: N/A
媒体: 视觉
计算值: 如指定

‘font-style’ 属性用于在字体系列中选择正常(有时称为“罗马体”或“直立”)、斜体和倾斜体。

‘normal’ 值选择在UA的字体数据库中被分类为“正常”的字体,而‘oblique’ 值选择标记为“倾斜”的字体。‘italic’ 值选择标记为“斜体”的字体,或在没有时选择标记为“倾斜”的字体。

在UA的字体数据库中标记为“倾斜”的字体实际上可能是通过电子方式倾斜的正常字体。

带有“Oblique”、“Slanted”或“Incline”字样的字体通常在UA的字体数据库中会被标记为“倾斜”;带有“Italic”、“Cursive”或“Kursiv”字样的字体通常会被标记为“斜体”。

h1, h2, h3 { font-style: italic }
h1 em { font-style: normal }

在上面的示例中,‘H1’ 中的强调文本将以正常字体显示。

15.5 小型大写字母‘font-variant’ 属性

名称: font-variant
值: normal | small-caps | inherit
初始值: normal
适用于: 所有元素
继承性:
百分比: N/A
媒体: 视觉
计算值: 如指定

字体系列中的另一种变化是小型大写字母。在小型大写字母字体中,小写字母看起来类似于大写字母,但尺寸较小且比例略有不同。‘font-variant’ 属性选择该字体。

‘normal’ 值选择一个非小型大写字母的字体,‘small-caps’ 选择小型大写字母的字体。如果小型大写字母字体是通过将正常字体的小写字母替换为缩放的大写字母来创建的,在CSS 2.2中也是可以接受的(但不是必须的)。作为最后的手段,可以使用大写字母来替代小型大写字母字体。

以下示例会导致‘H3’元素使用小型大写字母,任何强调的单词为倾斜体,‘H3’中的任何强调单词则为倾斜小型大写字母:

h3 { font-variant: small-caps }
em { font-style: oblique }

字体系列中可能还有其他变体,例如带有旧式数字、小型大写字母数字、字母压缩或扩展等的字体。CSS 2.2 没有选择这些变体的属性。

注意:在此属性将文本转换为大写字母的范围内,与‘text-transform’相关的考虑同样适用。

15.6 字体粗细‘font-weight’ 属性

名称: font-weight
值: normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
初始值: normal
适用于: 所有元素
继承性:
百分比: N/A
媒体: 视觉
计算值: 见文本

‘font-weight’ 属性选择字体的粗细。‘100’到‘900’的值形成一个有序的序列,每个数字表示一个至少比其前一个数字更深的粗细。‘normal’的值等同于‘400’,‘bold’的值等同于‘700’。除了‘normal’和‘bold’之外的关键字经常与字体名称混淆,因此为9值列表选择了一个数字尺度。

p { font-weight: normal }   /* 400 */
h1 { font-weight: 700 }     /* bold */

‘bolder’和‘lighter’值选择相对于从父元素继承的粗细的字体:

strong { font-weight: bolder }

字体(字体数据)通常具有一个或多个属性,其值是描述字体“粗细”的名称。这些粗细名称没有公认的、普遍的含义。它们的主要作用是在一个字体系列中区分不同深度的字型。在字体系列之间的使用相当不同;例如,一个被认为是粗体的字体可能被描述为Regular, Roman, Book, Medium, Semi-DemiBold, Bold,Black,这取决于字体设计中的“正常”字型有多黑。由于没有标准的名称使用,因此CSS 2.2中的粗细属性值是按数字尺度给出的,其中‘400’(或‘normal’)的值对应于该系列的“正常”文本字型。与该字型相关的粗细名称通常是Book, Regular, Roman, Normal或有时是Medium

将字体系列中的其他粗细映射到CSS尺度上的目的是仅保留该系列内深度的顺序。然而,以下启发式方法说明了如何在这种情况下进行分配:

一旦字体系列的粗细被映射到CSS尺度上,缺失的粗细则按如下方式选择:

以下两个示例显示了典型的映射。

假设“Rattlesnake”系列中有四种粗细,从最轻到最深分别是:Regular, Medium, Bold, Heavy

第一个字体粗细映射示例
可用字型 分配值 填充空缺
“Rattlesnake Regular” 400 100, 200, 300
“Rattlesnake Medium” 500  
“Rattlesnake Bold” 700 600
“Rattlesnake Heavy” 800 900

假设“Ice Prawn”系列中有六种粗细:Book, Medium, Bold, Heavy, Black, ExtraBlack。请注意,在此实例中,用户代理决定不为“Ice Prawn ExtraBlack”分配数值。

第二个字体粗细映射示例
可用字型 分配值 填充空缺
“Ice Prawn Book” 400 100, 200, 300
“Ice Prawn Medium” 500  
“Ice Prawn Bold” 700 600
“Ice Prawn Heavy” 800  
“Ice Prawn Black” 900  
“Ice Prawn ExtraBlack” (无)  

‘bolder’和‘lighter’的值表示相对于父元素粗细的值。根据继承的粗细值,使用下面的图表计算所使用的粗细。子元素继承计算后的粗细,而不是‘bolder’或‘lighter’的值。

‘bolder’和‘lighter’的含义
继承的值 bolder lighter
100 400 100
200 400 100
300 400 100
400 700 100
500 700 100
600 900 400
700 900 400
800 900 700
900 900 700

上表相当于在具有正常和粗体字型以及细体和重体字型的字体系列中选择下一个相对更粗或更细的字型。希望对给定元素使用的具体粗细值进行更精确控制的作者应使用数字值而不是相对粗细值。

并不能保证每个‘font-weight’值都有更深的字型;例如,有些字体可能只有正常和粗体字型,而有些字体可能有八种粗细。不能保证用户代理如何将字体系列内的字型映射到粗细值。唯一的保证是给定值的字型不会比更轻的值的字型更浅。

15.7 字体大小‘font-size’ 属性

名称: font-size
值: <绝对大小> | <相对大小> | <长度> | <百分比> | inherit
初始值: medium
适用于: 所有元素
继承性:
百分比: 参考继承的字体大小
媒体: 视觉
计算值: 绝对长度

字体大小对应于“em”方块,这是排版中使用的一个概念。请注意,某些字形可能会超出其“em”方块。值具有以下含义:

<绝对大小>
‘<绝对大小>’关键字是指向由用户代理计算并保持的字体大小表的索引。可能的值包括:

[ xx-small | x-small | small | medium | large | x-large | xx-large ]

下表为HTML标题和绝对字体大小提供了用户代理指南。‘medium’值是用户首选的字体大小,并用作参考中值。

CSS 绝对大小值 xx-small x-small small medium large x-large xx-large  
HTML 字体大小 1   2 3 4 5 6 7

实现者应构建一个绝对大小关键字相对于‘medium’字体大小和特定设备及其特性的比例因子表(例如设备的分辨率)。

不同的媒体可能需要不同的比例因子。此外,用户代理在计算表时应考虑字体的质量和可用性。不同的字体系列可能会有不同的表格。

注意 1:为了保持可读性,应用这些指南的用户代理应避免创建导致在计算机显示器上每em单位少于9像素的字体大小。

注意 2:在CSS1中,相邻索引之间建议的缩放因子为1.5,但用户体验证明该值过大。在CSS2中,对于计算机屏幕,相邻索引之间建议的缩放因子为1.2,但对于小尺寸仍然存在问题。实现经验表明,相邻绝对大小关键字之间的固定比例是有问题的,本规范不推荐这种固定比例。

<相对大小>
‘<相对大小>’关键字是相对于字体大小表和父元素的字体大小进行解释的。可能的值包括:[ larger | smaller ]。例如,如果父元素的字体大小为‘medium’,那么‘larger’值将使当前元素的字体大小变为‘large’。如果父元素的大小不接近表中的一个条目,用户代理可以在表条目之间进行插值或四舍五入到最近的一个。用户代理可能需要在数值超出关键字范围时推测表值。

在计算元素的字体大小时,长度和百分比值不应考虑字体大小表。

不允许使用负值。

在所有其他属性中,‘em’和‘ex’长度值是指当前元素的计算字体大小。在‘font-size’属性中,这些长度单位是指父元素的计算字体大小。

请注意,应用程序可能会根据上下文重新解释明确的大小。例如,在VR场景中,字体可能由于透视失真而获得不同的大小。

示例:

p { font-size: 16px; }
@media print {
  p { font-size: 12pt; }
}
blockquote { font-size: larger }
em { font-size: 150% }
em { font-size: 1.5em }

15.8 字体简写属性‘font’ 属性

名称: font
值: [ [ <'font-style'> || <'font-variant'> || <'font-weight'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
初始值: 见各自属性
适用于: 所有元素
继承性:
百分比: 见各自属性
媒体: 视觉
计算值: 见各自属性

‘font’ 属性是一个简写属性,除下面描述的情况外,用于在样式表的同一位置设置 ‘font-style’‘font-variant’‘font-weight’‘font-size’‘line-height’‘font-family’。该属性的语法基于传统的排版简写符号,用于设置与字体相关的多个属性。

所有与字体相关的属性首先被重置为其初始值,包括前段提到的属性。然后,将简写属性‘font’中明确指定的值应用于这些属性。有关允许值和初始值的定义,请参见前面定义的属性。

p { font: 12px/14px sans-serif }
p { font: 80% sans-serif }
p { font: x-large/110% "New Century Schoolbook", serif }
p { font: bold italic large Palatino, serif }
p { font: normal small-caps 120%/120% fantasy }

在第二个规则中,字体大小的百分比值(‘80%’)是相对于父元素的字体大小。在第三个规则中,行高的百分比是相对于元素自身的字体大小。

在上述前三个规则中,没有明确提及 ‘font-style’、‘font-variant’ 和 ‘font-weight’,这意味着它们都设置为其初始值(‘normal’)。第四个规则将‘font-weight’设置为‘bold’,‘font-style’设置为‘italic’,并隐式地将‘font-variant’设置为‘normal’。

第五个规则设置了‘font-variant’(‘small-caps’)、‘font-size’(父元素字体大小的120%)、‘line-height’(字体大小的120%)和‘font-family’(‘fantasy’)。因此,‘normal’关键字适用于剩下的两个属性:‘font-style’ 和 ‘font-weight’。

以下值指系统字体

caption
用于带有标题的控件(如按钮、下拉菜单等)的字体。
icon
用于标记图标的字体。
menu
用于菜单(如下拉菜单和菜单列表)的字体。
message-box
用于对话框的字体。
small-caption
用于标记小控件的字体。
status-bar
用于窗口状态栏的字体。

系统字体只能整体设置,也就是说,字体系列、大小、粗细、样式等都同时设置。这些值可以单独更改(如有需要)。如果某个平台上没有具有指示特性的字体,用户代理应智能地进行替换(例如,可以将‘caption’字体的较小版本用作‘small-caption’字体),或替换为用户代理的默认字体。对于系统字体,如果操作系统提供的用户首选项中没有某些个别属性,这些属性应设置为其初始值。

这就是为什么该属性被称为“几乎”是一个简写属性的原因:系统字体只能通过这个属性指定,而不能单独通过 ‘font-family’ 属性指定,因此‘font’允许作者做的不仅仅是子属性的总和。然而,像 ‘font-weight’ 这样的各个属性仍然会从系统字体中获取值,并且可以独立地进行更改。

示例:

button { font: 300 italic 1.3em/1.7em "FB Armada", sans-serif }
button p { font: menu }
button p em { font-weight: bolder }

如果某系统上的下拉菜单所使用的字体为,例如,9点的 Charcoal,权重为600,则 BUTTON 的后代元素 P 将显示为好像这个规则生效了一样:

button p { font: 600 9px Charcoal }

由于 ‘font’ 简写属性会重置任何未明确赋值的属性为其初始值,因此这与以下声明效果相同:

button p {
  font-family: Charcoal;
  font-style: normal;
  font-variant: normal;
  font-weight: 600;
  font-size: 9px;
  line-height: normal;
}