# 字体

# 字体族

字体族是不同字型的字体的统称,比如 Times 字体包括 TimesRegular, TimesBold, TimesItalic, TimesBoldItalic 等,这些字体各自都是一个字型(font-face),而 Times 就是一个字体族(font-family)。

CSS 定义了五种通用的字体族:

  • serif 衬线字体,字形宽度各异,而且有衬线。例如:小写字母 i 和小写字母 m 宽度不同,衬线就是字符笔画末尾的装饰,比如大写字母 A 两条竖线底部的短线。Times, Georgia,New Century Schoolbook 等都是衬线字体。

  • sans-serif 无衬线字体,字形宽度各异,但是无衬线。Helvetica, Geneva, Verdana, Arial, Univers 等都是无衬线字体。

  • monospace 等宽字体,字形宽度一样,一般用于显示编程代码或表格数据。衬线可有可无。Courier, Courier New, Consolas, Andale Mono 等都是等宽字体。

  • cursive 草书字体,模仿人类笔迹或手写体的字体,通常在笔划末端有较大的花饰,而且比衬线字体华丽,例如大写字母 A 左边竖线底部可能有个小卷,或者整条线都是花饰卷。Zapf Chancery, Author, Comic Sans 等都是草书字体。

  • fantasy 奇幻字体,也叫装饰字体或展示字体,没有统一的特征,但无法归类到其他类别中。Western, Woodblock, Klingon 等都是奇幻字体。

# 使用通用字体族

例如:只想使用无衬线字体,但不具体指定,由浏览器自行选择。

body {
  font-family: sans-serif;
}
1
2
3

# 指定字体族

h1 {
  font-family: Georgia;
}
1
2
3

上例中,假设用户安装了 Georgia 字体,如果没有安装,浏览器找不到的话将会使用默认字体。

如果不希望浏览器在找不到指定字体时直接使用默认字体,可以在最后设置一个想使用的通用字体族:

h1 {
  font-family: Georgia, serif;
}
1
2
3

通常都建议在设置 font-family 时指定一种通用字体族。

# 使用引号

如果字体名称中有空格,或是符号(比如 # 或 $ 等),应该使用引号包裹起来,非强制但是推荐这样做。

font-family 值中的关键字相同的字体则必须放在引号中。

而通用字体族这样的关键字则不能放在引号中,否则浏览器会以为这是一款字体的名称。

# 使用 @font-face

加入想要使用的字体没有广泛安装,是个特别的字体,通过使用 @font-face 可以定义一个特有的字体族名称,对应于服务器上的字体文件,浏览器会将这个字体文件下载并渲染页面中使用它的文本,就好像是用户的设备中安装了这个字体一样。

例如:

/* 自定义字体名称,并指定要加载的字体文件 */

@font-face{
  font-family: 'MyFontName';
  src: url('./font/MyFontName.otf');
}
1
2
3
4
5
6
/* 使用自定义的字体 */

div {
  font-family: MyFontName;
}
1
2
3
4
5

# 必须的描述符

自定义字体的全部参数都在 @font-face{} 中编写,参数被称为描述符,写法与属性相同。

多数的描述符都是直接使用现有的属性名,必填的描述符有 font-familysrc 两个。

src 就是指定字体要使用的一个或多个源,多个源以逗号分隔。源可以指向任何 URI,但字型必须与样式表同源。也就是不能把 src 指向别人的网站,下载别人的字体,应该在自己的服务器中存储一份,或者使用同时提供样式表和字体文件的字体托管服务。

如果服务器在请求中设置了 Access-Control-Allow-Origin 允许跨站加载,则不受此限制。

@font-face{
  font-family: 'MyFontName';
  src: url('./font/MyFontName.otf'),
       url('./font/MyFontName.ttf'),
       url('./font/MyFontName.woff');
}
1
2
3
4
5
6

上例中,src 设置了多个源,如果浏览器无法下载第一个,或字体格式不支持,则会自动下载下一个。

可以使用 format() 高速浏览器某个源是什么格式,这样当浏览器不支持时会直接跳过去下载下一个源。

@font-face{
  font-family: 'MyFontName';
  src: url('./font/MyFontName.otf') format('opentype'),
       url('./font/MyFontName.ttf') format('TureType');
}
1
2
3
4
5

支持的字体格式

格式
embedded-opentype EOT(Embedded OPenType)
opentype OTF(OPenType)
svg SVG(Scalable Vector Graphics)
truetype TTF(TrueType)
woff WOFF(Web Open Font Format)

除了 url()format() 组合之外,还可以使用 local() 指定已经安装在设备本地中的若干个字体族名称。

@font-face {
  font-family: "myFontName";
  src: local("myFontName"),
       local("myFontName-Regular "),
       url("myFontName-Regular.otf") format("opentype"),
       url("myFontName-Regular.true") format("truetype");
}
1
2
3
4
5
6
7

浏览器会先尝试从设备本地获取 local() 指定的字体,如果没有则加载下一个本地或在线字体。

借助 local() 可以为本地字体重新起一个名字:

@font-face {
  font-family: "H"; /* 为本地的 Helvetica 或 Helvetica Neue 字体起个别名叫做 H */
  src: local("Helvetica"), local("Helvetica Neue");
}
h1,
h2,
h3 {
  font-family: H, sans-serif; /* 使用自定义的字体名称 H */
}
1
2
3
4
5
6
7
8
9

# 确保完全兼容的 @font-face 写法

不同时代浏览器支持不同格式的字体,为了尽量支持所有,应该尽量使用如下安全的写法:

@font-face {
  font-family: "myFontName";
  src: url("myFontName.eot"); /* IE9 */
  src: url("myFontName.eot?#iefix") format("embedded-opentype"), /* IE6 ~ IE8 */
       url("myFontName.woff") format("woff"), /* 多数现代浏览器 */
       url("myFontName.ttf") format("truetype"), /* 多数 IOS 和 Android 设备*/
       url("myFontName.svg#myFontName_adf_regular") format("svg"); /* 旧 IOS 设备*/
}
1
2
3
4
5
6
7
8

上例中出现的如下两行:

  src: url("myFontName-Regular.eot");
  src: url("myFontName.eot?#iefix") format("embedded-opentype"),
1
2

这两行是为支持 eot 格式的浏览器(IE6 ~ IE9)提供 eot 文件。

前一行针对“兼容模式”下的 IE9,后一行针对 IE6 ~ IE8。

后一行出现的 ?#iefix 导致这些浏览器出现一个解析缺陷,从而绕过另一个解析缺陷(列出多个字体格式时返回 404)。IE9 修复了这个问题,但是没有扩充支持的字体格式,所以需要第一行的存在。

# @font-face 的其他字体描述符

@font-face 中除了 font-family 和 src 这两个必须的描述符以外,还有几个可选描述符:

描述符 默认值 说明
font-style normal 区分常规、斜体和倾斜字体
font-weight normal 区分不同的字重
font-stretch normal 区分不同的字符宽度(例如紧缩和加宽)
font-variant normal 区分众多字形变体(例如小号的大写字母)
font-feature-settings normal 直接访问 OpenType 的底层特性(例如启用连字)
unicode-range U+0-10FFFF 定义指定字体中可用的字符范围

如果未设置其中的某个描述符,则会使用默认值。

# 限制字符范围 unicode-range

这个描述符没有对应的 CSS 属性,用于指定自定义的字体可以应用到哪些字符上。设置一个 unicode 字符编码范围,只有范围内的字符会应用这个指定的字体。默认是全部 unicode 编码字符。

指定多个范围以逗号分隔。

值中指定范围时可以且仅允许使用一个特殊的字符 ? 来表示通配符,表示“任何数字”,比如 U+30?? 等效于 U+3000-30ff

除了范围外也可以设置单个字符编码值。

@font-face 是惰性加载的,仅当页面中出现了 unicode-range 包含的字符时,浏览器才会去下载这个字体文件。所以应该组织合理的写法来定义。

# 组合描述符

将多个描述符组合在一起,比如指定一个字型为粗体,一个为斜体,一个为加粗的斜体。

@font-face {
  font-family: "SwitzeraADF";
  font-weight: normal;
  font-style: normal;
  font-stretch: normal;
  src: url("SwitzeraADF-Regular.otf") format("opentype");
}
@font-face {
  font-family: "SwitzeraADF";
  font-weight: bold;
  font-style: normal;
  font-stretch: normal;
  src: url("SwitzeraADF-Bold.otf") format("opentype");
}
@font-face {
  font-family: "SwitzeraADF";
  font-weight: normal;
  font-style: italic;
  font-stretch: normal;
  src: url("SwitzeraADF-Italic.otf") format("opentype");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

加粗斜体字不被拉伸:

@font-face {
  font-family: "SwitzeraADF";
  font-weight: bold;
  font-style: italic;
  font-stretch: normal;
  src: url("SwitzeraADF-BoldItalic.otf") format("opentype");
}
1
2
3
4
5
6
7

紧缩的加粗斜体字:

@font-face {
  font-family: "SwitzeraADF";
  font-weight: bold;
  font-style: italic;
  font-stretch: condensed;
  src: url("SwitzeraADF-BoldCondItalic.otf") format("opentype");
}
1
2
3
4
5
6
7

紧缩的正常字重的斜体:

@font-face {
  font-family: "SwitzeraADF";
  font-weight: normal;
  font-style: italic;
  font-stretch: condensed;
  src: url("SwitzeraADF-CondItalic.otf") format("opentype");
}
1
2
3
4
5
6
7

# 字重 font-weight

可选值:normal | bold | bolder | lighter | 100 | 200 | 300 | 400(normal) | 500 | 600 | 700(bold) | 800 | 900

默认值: normal

是否继承:是

备注:有对应的 @font-face 描述符

bolder 会将字重设置为比继承的父元素的字重高一个等级里的最小数字值。到顶(900)后不再增大。lighter 同理。

# 字号

可选值:xx-small | x-small | small | medium | large | x-large | xx-large | smaller | larger | <length> | <percentage>

默认值: medium

是否继承:是

百分数值 <percentage> 相对于继承的父元素字体大小,长度值 1em 等效于 100%

# 调整字体高宽比值 font-size-adjust

可选值:<number> | none | auto

默认值: none,表示禁止浏览器自动调整字号。

是否继承:是

影响字体是否清晰易辨认的因素为:字号以及字母 x 的高度。x 的高度 除以 字号得到的结果成为高宽比值(aspect value)。随着字号减小,高宽比值越高,字体越清晰易辨认;相反,高宽比值较低的字体很容易变得模糊难以辨认。

截止2017年只有 Gecko (Firefox)系列浏览器支持此属性。

# 字形 font-style

可选值:italic(斜体) | oblique(倾斜) | normal(常规)

默认值: normal

是否继承:是

备注:有对应的 @font-face 描述符

# 字体拉伸 font-stretch

可选值:normal | ultra-condensed | extra-condensed | condensed | semicondensed | semi-expanded | expanded | extra-expanded | ultraexpanded

默认值: normal

是否继承:是

备注:有对应的 @font-face 描述符

仅当使用的字体族中有宽体和窄体时,此属性才起作用。而一般的字体族并没有这样的变体,如果有通常字体族的价格不菲。

截止 2017 年,Safari 和 Opera Mini都不支持此属性

# 字距调整 font-kerning

可选值:auto | normal | none

默认值: auto

是否继承:是

有些字体定义了字符之间相对位置的距离,比如 oc 与 ox 可能就不同,AB 和 AW可能也不同。

  • none 让浏览器忽略字体中的字距信息
  • normal 让浏览器正常处理字距,也就是使用字体中的字距数据
  • auto 由浏览器自行决定,但通常都建议使用字距数据。

注意:既调整字距,又使用 letter-spacing 属性,应该先调整字距,再应用 letter-spacing

# 字体变形 font-variant

可选值(CSS2.1):normal | small-caps

可选值(Level 3):normal | none | [ <common-lig-values> ‖ <discretionary-lig-values> ‖ <historicallig-values> ‖ <contextual-alt-values> ‖ stylistic(<feature-value-name>) ‖ historical-forms ‖ styleset(<feature-value-name>#) ‖ charactervariant(<feature-value-name>#) ‖ swash(<feature-value-name>) ‖ ornaments(<feature-value-name>) ‖ annotation(<feature-value-name>) ‖ [ smallcaps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] ‖ <numeric-figure-values> ‖ <numeric-spacing-values> ‖ <numeric-fraction-values> ‖ ordinal ‖ slashed-zero ‖ <east-asian-variantvalues> ‖ <east-asian-width-values> ‖ ruby ]

默认值: normal

是否继承:是

备注:有对应的 @font-face 描述符

  • small-caps 使用小号的大写字母,效果与 text-transform: uppercase 类似,之所以在这里用字体属性来设置,是因为有些字体有专门的小号大写字母字型。

# 字体特性 font-feature-settings

# 字体合成 font-synthesis

# font 属性(各种属性的简写形式)

可选值:[[ <font-style> ‖ [ normal | small-caps ] ‖ <font-weight> ]? <font-size> [ /<line-height> ]? <font-family>] | caption | icon | menu | message-box | small-caption | status-bar

默认值: 与各属性一致

百分数: <font-size> 基于父元素计算,<line-height> 基于当前元素的 font-size 值计算。

前三个值可以是 font-stylefont-weightfont-variant 可以不分顺序,如果有值为 normal 可以省略。

后两个值必须是 font-sizefont-family 这样的顺序,而且一个都不能省略,否则无效。

# 加入行高

font 本身只有之前的5个属性值,但还有一个可选的属性 line-height 可以写进去: font-size / line-height 也是可以的。

body {
  font-size: 12px;
}
h2 {
  /* 字体为 body 字体的2倍(24px),line-height 为 24px * 1.2 = 28.8px */
  font: bold italic 200%/1.2 Verdana, Helvetica, Arial, sans-serif;
}
1
2
3
4
5
6
7

使用简写属性时,省略的属性值都会被设为默认值。单写各个属性时则不会影响其他属性。

# 使用系统字体

在 font 声明中使用系统字体值,元素上应用的是操作系统中控件的字号,字体族,字重,字形和变形。

  • caption 用于说明文字的空间,比如按钮
  • icon 标注图标
  • menu 在菜单中使用,即下啦菜单和菜单列表
  • message-box 在对话框中使用
  • small-caption 用于标注小型控件
  • status-bar 用在窗口的状态栏中