> ## 文章索引
> 在这里获取全部文章的索引：https://lrd.im/blog/llms.txt
> 这是 lrd.im 的个人博客，记录设计、技术与思考。

# 高级排版功能：Case-Sensitive Forms 是什么？

![封面图](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/01.png)

## 发现

自从转换到 Figma 工作后，我发现在部分字体下的字体设置里，有一个选项叫「Case-Sensitive Forms」，来回切换后，发现了一些有意思的现象。经过一段时间的查阅资料和实践后，获得了新的认识，遂写下这篇笔记来记录这有趣的现象。

## 认识

实际上「Case-Sensitive Forms」属于 OpenType 字体众多高级排版功能的其中一种，开启后，主要有以下影响：

1. 将部分标点符号的位置上移；
2. 将老式数字改为现代数字。

#### 影响一：将部分标点符号的位置上移

一直以来，我们在英文输入法下输入的标点符号，其垂直位置是基于小写字母 x 的中心 (x-height) 作为对齐线的。

而在开启「Case-Sensitive Forms」后，标点的垂直位置则是基于大写字母 X 的中心 (Cap height) 作为对齐线。

![对比示意图：Normal 模式下括号、短横线等标点符号以 x-height 为中心对齐；开启 Case-Sensitive Forms 后，标点位置上移，改为以 Cap height 为中心对齐，视觉上更贴合大写字母的高度。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/02.png)

#### 影响二：将老式数字改为现代数字

将数字字形从旧式数字转变为现代数字。旧式数字实际上也是 x-height 对齐，拥有高低错落的韵律美，常用在外语书籍中。

开启「Case-Sensitive Forms」后，会将旧式数字改为我们常见的现代数字，每个数字都等高，其高度为 Cap-height。

![字体对比示意图：上方 "Oldstyle Figures" 展示旧式数字，其中小写 x 与数字高低错落；下方开启 "Case-Sensitive Forms" 后，数字统一升为与大写 X 等高的现代数字。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/03.png)

## 实践场景

得益于「将部分标点符号的位置上移」这个特点，我不禁联想到它是适用于大写字母、数字和 CJK 文字的混排当中。下面就列举几个我在工作学习中发现到，应用「Case-Sensitive Forms」的文字能够获取到更优体验的几个场景吧。

（以下场景需要字体本身支持高级排版功能 Case-Sensitive Forms）

### 场景一：电话号码

来欢聚集团工作之后接触到了国际化电商业务，在业务需求中就会出现带有各个地区区号的手机号码，纯数字的场景就特别适合使用「Case-Sensitive Forms」，因为数字的字高与大写字母的字高一致。

![电话号码排版对比图：上方「Normal」模式下，括号位置偏低，与数字垂直对齐不佳；下方启用「Case-Sensitive Forms」后，括号上移至数字视觉中心，整体排列更整齐协调。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/04.png)

（同理，在验证码场景也适用）

### 场景二：时间/时区

与上一个场景类似，时间/时区基本上都是由数字和大写字母组成。也很适合应用该做法。

![时间/时区文本「2022-05-14 9:39 PM (GMT+8)」的对比示意图：Normal 状态下括号位置偏低；启用 Case-Sensitive Forms 后，括号和短横线都与其他文字垂直居中对齐，视觉上更协调。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/05.png)

### 场景三：大写西文或 CJK 文字

如果某些标题位置用到了强制大写的样式，特别适用「Case-Sensitive Forms」，因为这个样式的原意就是为了让标点在大写字母中间时，位置更靠近上下文的垂直中心。

![对比图展示大写文本「CHECK-IN」在两种排版设置下的差异：启用 Case-Sensitive Forms 后，连字符「-」位置上移，与大写字母垂直居中对齐，视觉更协调。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/06.png)

同样地，CJK 文字的高度与大写字母 X 的中心 (Cap height) 接近，所以也适合使用。

![场景三 CJK 文字对比示例：文本「50 条/页 강남-신사」在 Normal 模式下，标点符号（/和-）位于字符垂直中心偏下；启用 Case-Sensitive Forms 后，标点上移至与 CJK 文字及韩文垂直居中对齐，视觉更整齐。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/07.png)

### 场景四：多语言拼接场景

举一个与公司业务贴近的例子。我做的数据中心里面有一个叫「数据报告页」的页面，该页面的名称是由「页面类型」+「分析维度」拼接而成。由于是拼接而成，那两段文本会是需要有首字母大写，一旦上下文中有大写字母，我认为就有「Case-Sensitive Forms」发挥的空间。

![多语言拼接场景对比示意图：上方 Normal 状态下，「Product sales : By SPU」中冒号位置偏低；下方启用 Case-Sensitive Forms 后，冒号垂直居中对齐于大写字母，视觉更工整。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/08.png)

### 场景五：无序列表

在无序列表 Bullet List 中，每一项都是一个完整的句子，所以也必定会有首字母大写。将无序列表最前面的标点上移至与大写字母垂直对齐，看起来会整齐了不少。

![无序列表对比示意图：Normal 模式下项目符号偏低，与大写字母垂直中心不对齐；启用 Case-Sensitive Forms 后，项目符号上移至与大写字母垂直中心对齐，视觉更整齐。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/09.png)

### 场景六：Text Face

一些用几个标点和字母组成的简易纯文字表情，使用「Case-Sensitive Forms」后效果也会更好。该场景比较少见。

![文字表情「:D」和「:-)」的排版对比：Normal 模式下标点位置偏低，启用 Case-Sensitive Forms 后冒号和连字符垂直居中对齐，与字母视觉重心一致，整体更协调。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/10.png)

## 支持的字体

支持这个特点的字体比较少，我在各种主流字体或系统默认字体下都试了下，发现生效的字体有：

1. DIN Pro
2. Inria Sans
3. Inter
4. SF 系列（Apple 设备系统字体）
5. Warnock Pro
6. …

而我们耳熟能详的字体，有大部分都是不支持的：

1. Arial
2. Helvetica
3. Noto Sans
4. Roboto
5. Source Sans
6. …

所以如果我们网站的字体策略是用的系统默认字体，那么「Case-Sensitive Forms」效果只会在 Apple 设备生效。

## 如何使用

### 在 Figma 中应用

选中字体后，在「Type settings」中切换至「Detail」面板，勾选「Case-Sensitive Forms」，就能看到效果。

![Figma 文字面板操作步骤截图：①点击右侧面板省略号按钮，②在 Type settings 中切换至 Details 标签页，③勾选 Case-Sensitive Forms 选项以启用大小写敏感字形功能。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/11.png)

### 在网页中应用

在网页中给文本添加样式 `font-feature-settings: 'case';`，就能看到效果。

![代码编辑器截图，展示在网页中启用 Case-Sensitive Forms 的方法：对段落元素设置 `font-family: -apple-system, BlinkMacSystemFont, sans-serif;` 与 `font-feature-settings: 'case';`，预览区显示电话号码 +(1)(425) 555-0100 的排版效果，括号位置垂直居中对齐。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/12.png)

[兼容性](https://caniuse.com/font-feature "caniuse 中对 font-feature 的兼容性查询表")非常优秀，在不同版本的浏览器都能正常展示，前提是字体支持这个高级排版功能。

## 实际案例

恰好最近我也有将这个效果应用到公司项目里面，刚好又踩过一个小坑，正好在这记录下吧。

![对比图：旧做法（Normal）中括号显示为普通圆括号，与数字基线不对齐；新做法（Case-Sensitive Forms）中时区「8:42 PM (GMT+08:00)」的括号上移居中，视觉更协调统一。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/13.png)

「Case-Sensitive Forms」应用在特定场景下，确实是会好些。正好公司项目里就会经常出现时区、货币、数据等场景。从上图可以看到使用前后的对比，高下立判。

#### 遇到的小坑

当时我计划让前端实现「比例数字」+「Case-Sensitive Forms」时，是分别用两个样式的：

```css
/* 出错做法 */
font-variant-numeric: normal; /* 实现比例数字 */
font-feature-settings: 'case' on; /* 实现 Case-Sensitive Forms */
```

看起来没问题，我在 Stackblitz 里自己实践了一遍也能达到预期效果，但前端反馈到这两个属性放在一起后，打包工具会在 `font-feature-settings` 属性的值后面追加一个 `normal`（可能为了兼容性），使这句样式变成 `font-feature-settings: 'case' on, normal;`。这自然就会失效了。

然后我后面找了点资料，发现比例数字也能放进 font-feature-settings 里面，于是让前端把样式改成了：

```css
/* 最终做法 */
font-feature-settings: 'case', ‘pnum’; /* 同时实现 Case-Sensitive Forms 和比例数字 */
```

最后打包出来效果与预期一致，顿时感到神清气爽，正好顺便把这做法记录下来了。

![与前端的聊天记录截图：前端说明打包工具会在 font-feature-settings 后追加 normal 导致样式失效；设计师提议改用 font-feature-settings: 'case', 'pnum'；前端确认测试环境验证通过，问题解决。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/14.png)

## 小科普：什么是 OpenType 高级排版功能？

> OpenType 功能就像字体中的密室。解锁它们，您将找到使字体以微妙而生动的方式呈现不同外观和行为的方法。并非所有 OpenType 功能都适合在所有时候使用，但是某些功能对于出色的排版至关重要。 —— [Adobe](https://helpx.adobe.com/cn/fonts/using/use-open-type-features.html "Adobe 对 OpenType 高级排版的介绍")

支持 OpenType 的字体，允许我们做更多富有细节的文字样式处理。比如将数字「0」设置为中间有斜线的样式，更有区分度：

![OpenType 特性「Slashed Zero」对比示意图：左侧为普通数字「0」，右侧为启用该特性后中间带有斜线的「0」，斜线版本区分度更高，可避免与字母「O」混淆。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/15.png)

或者将小写字母转换为小型大写字母：

![OpenType Small Caps 功能对比：左侧「Normal」正常显示「iPhone XR」，右侧启用「Small Caps」后，大写字母「XR」变为视觉上较小但比例协调的小型大写字母形式。](https://lrdim.oss-cn-shenzhen.aliyuncs.com/blogimg/2022-05-14-e0efbeed2ca0/16.png)

还有很多，不妨去张鑫旭大神的[博客](https://www.zhangxinxu.com/wordpress/2018/12/css-font-feature-settings-keyword-value)，或者在其他[示例网站](https://sparanoid.com/lab/opentype-features/)上了解更多。

OpenType 的世界很庞大，但不是每一个都有用。就像上面我引用的那段文字所说，如果我们找到一个适合当前场景的高级排版样式，那页面中的文字将会更富有细节、更耐人寻味。

#### 尚存的疑问

到底「Case-Sensitive Forms」中文应该叫什么？我觉得「大写标点」好像不错，知道这个术语中文名的观众请提点一下… 网上查了半天没查到。

## 参考链接

- [OpenType Feature: case - Case sensitive Forms](https://www.preusstype.com/techdata/otf_case.php)
- [使用 OpenType 功能](https://helpx.adobe.com/cn/fonts/using/use-open-type-features.html)
- [Oldstyle Figures - Fonts.com | Fonts.com](https://www.fonts.com/content/learning/fontology/level-3/numbers/oldstyle-figures)
- [OpenType 字体特性指南 - CSS（层叠样式表） | MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide)