1955年,IBM的字体设计师Howard “Bud” Kettler接到一个任务:为公司的电动打字机设计一套新字体。他交出的作品就是Courier——这个名字源于他最初的想法:“让文字像信使一样传达信息。“七十多年过去了,Courier和它的后代们依然统治着程序员的屏幕。

但一个有趣的问题是:为什么程序员必须使用等宽字体?

答案可能会让你意外——不是因为等宽字体更适合编程,而是因为历史惯性。更重要的是,这个选择可能正在损害你的编码效率和眼睛健康。

从古希腊到打字机:等宽字体的意外诞生

等宽字体的历史比计算机早得多。古希腊人在公元前5世纪就使用了一种称为"Stoichedon"的雕刻风格——每个字母都被雕刻在等大的方格中,无论字母本身的宽窄如何。这种做法不是为了易读性,而是为了美学上的秩序感。

近代等宽字体的真正起点是打字机。打字机的机械结构决定了:每敲击一次按键,纸张必须向左移动固定的距离。这意味着所有字符必须占用相同的水平空间。

这个技术限制深刻影响了字体设计。宽字母如"m"和"w"被压缩,窄字母如"i"和"l"则被加上巨大的衬线来填充空间。Courier的设计师Kettler巧妙地在这些约束中找到了平衡——较大的x-height(小写字母高度)、开阔的字谷(counter,字母内部的空白区域)、圆润的板状衬线。IBM没有为Courier申请专利,这让它迅速成为行业标准。

当计算机出现时,早期终端和显示器继承了这一遗产。文本模式显示将屏幕视为字符网格——这与Stoichedon的逻辑完全一致。内存极其有限的年代,等宽字体是唯一可行的选择。

一个被打破的技术限制

问题在于:这个技术限制在几十年前就不存在了。

现代显示器可以精确控制每个像素。现代操作系统支持任意字体渲染。现代编辑器可以动态调整文本布局。等宽字体作为技术要求已经消失了,但它作为文化习惯却根深蒂固。

支持等宽字体的程序员通常会提出两个理由:对齐和可读性。让我们逐一检验。

对齐:真正的问题是什么?

程序员喜欢对齐代码:

let name    = "Alice";
let age     = 25;
let address = "Beijing";

等宽字体让这种对齐变得简单——只需插入空格即可。但这也暴露了一个更深层的问题:为什么我们需要手动对齐?

2009年,程序员Nick Gravgaard提出了"弹性制表符”(Elastic Tabstops)的概念。他的核心洞察是:对齐应该是编辑器的责任,而不是字体的责任。如果编辑器能够智能处理对齐,那么我们就可以使用任何字体——包括比例字体。

Gravgaard在自己的测试中发现,比例字体如Verdana在可读性上"明显优于"等宽字体。他不是第一个有这种想法的人——Smalltalk、Oberon和Plan 9的Acme编辑器都使用比例字体显示代码。

可读性:证据指向何方?

可读性是一个更复杂的议题。字体设计师和研究者已经进行了大量眼动追踪实验。

2015年发表在MDPI期刊上的一项研究比较了Georgia和Verdana两种字体在LCD屏幕上的阅读表现。研究发现,字体大小对阅读速度有显著影响——14磅字体比12磅字体更易读。但不同字体类型之间的差异并没有那么大。

更重要的是,没有证据表明等宽字体在代码阅读上具有先天优势。事实上,比例字体通常被认为在长文本阅读中更具优势,因为:

  1. 字符间距更自然:宽字母有更多呼吸空间,窄字母不会浪费空间
  2. 视觉节奏更好:文本密度更均匀,眼睛更容易扫描
  3. 更高的信息密度:同等宽度下可以显示更多字符

编程字体的设计哲学

如果等宽字体不是必须的,为什么近年来涌现出如此多专为编程设计的字体?JetBrains Mono、Fira Code、Cascadia Code、Source Code Pro……这些字体的设计师们到底在优化什么?

答案在于:编程文本有其独特的视觉需求,但这与等宽无关。

字符区分度:最重要的设计原则

编程字体设计师面临的核心挑战是:让相似字符截然不同

考虑这组字符:0O1lI{}[]()。在某些字体中,这些字符几乎无法区分。想象你在调试代码时,把数字0误认为字母O,或者把小写l误认为数字1——这种错误可以浪费数小时的调试时间。

Evil Martians的字体设计师Irina Nazarova在分析编程字体时总结了关键设计原则:

  • 零必须有标识:斜划零(slashed zero)或点零(dotted zero)是必须的,用于区分大写O
  • 1、l、I必须完全不同:数字1应该有明显的基底,小写l应该有明显的顶部弯钩,大写I应该有明显的衬线
  • 括号必须易于区分{}[]()在嵌套时必须能快速识别

Fira Code的字符区分度测试

图片来源: betterwebtype.com

JetBrains Mono的设计逻辑

JetBrains在2020年发布的JetBrains Mono展示了现代编程字体设计的成熟思考。

设计团队发现,传统等宽字体存在一个矛盾:为了保持字符等宽,字母高度通常被压缩,导致可读性下降。JetBrains Mono的解决方案是:保持字符宽度不变,但最大化小写字母高度

这带来一个意外的好处:更多的垂直像素意味着更清晰的渲染。在相同字号下,JetBrains Mono的字符比Consolas占据更多像素,即使两者的宽度相同。

另一个细节是数学符号的处理。在编程中,+-*/=等符号扮演着核心角色,但传统字体往往将它们设计得过小。JetBrains Mono将这些符号放大,并确保它们在视觉上对齐——这种设计让复合运算符如<=>==>更容易识别。

连字:争议中的创新

Fira Code在2014年引入的编程连字(ligatures)引发了持续的争议。

连字的概念很简单:将多个字符组合成单个字形。=>变成真正的箭头!=变成>=变成。支持者认为这减少了视觉噪声,让代码更接近数学表达式;反对者则认为这会造成误导。

字体设计师Matthew Butterick提出了强烈的反对意见:

“编程字体中的连字是一个糟糕的主意。它们很可能误传达代码的含义,或者在读者中引起误判。即使它们看起来很可爱,错误的风险也不值得。”

Butterick的核心论点是:代码中的每个字符都有精确的语义意义。连字改变了视觉呈现,可能导致歧义——特别是当你需要逐字符阅读代码时(比如调试或代码审查)。

更实际的问题是兼容性。当你在屏幕上看到时,你不确定源文件中是=>还是->还是其他什么。这在协作场景中尤其麻烦——你的同事可能使用完全不同的字体。

这并不是说连字没有价值。对于个人开发场景,如果它能让你感到愉悦和高效,那就使用它。但如果你需要展示代码、进行代码审查或教授编程,关闭连字可能是更负责任的选择。

眼睛的负担:字体对疲劳的影响

程序员每天花在阅读代码上的时间远超过编写代码的时间。这意味着字体的选择直接影响眼睛健康和工作效率。

认知负荷与眼动

阅读代码时的眼动模式与阅读自然语言有显著差异。程序员需要频繁地在字符、标识符、运算符之间跳转,识别语法结构,追踪嵌套层级。

字体设计师可以在两个方面降低认知负荷:

字符识别速度:清晰的字形让眼睛更快地识别字符。这不仅仅是大字体的问题——字形的对比度、笔画的均匀性、衬线的清晰度都会影响识别速度。

视觉分组:好的字体帮助眼睛将相关字符组织成语义单元。比如,functionName应该被视为一个整体,而不是12个独立的字符。

阅读障碍友好字体:科学怎么说?

针对阅读障碍人群设计的字体(如OpenDyslexic和Dyslexie)声称通过加粗字符底部来防止"字母翻转”,从而改善阅读体验。这些字体在设计圈获得了大量关注。

但科学研究给出了不同的结论。2016年发表在Annals of Dyslexia上的一项研究对12名有阅读障碍的小学生进行了测试,比较OpenDyslexic、Arial和Times New Roman三种字体。结果显示:OpenDyslexic在阅读速度或准确性上没有任何改善,部分学生甚至表现更差。

研究者指出,阅读障碍的根本原因不是视觉感知问题,而是语音编码缺陷。字体可以微调视觉体验,但无法解决核心的认知障碍。

这对于普通程序员的启示是:没有"万能"的友好字体。最好的字体是最适合你的字体——而这也因人而异。

屏幕刷新率与字体的交互

2023年的一项研究发现,更高的屏幕刷新率可以减少眼疲劳。这与字体选择有一个微妙的交互:高刷新率屏幕可以更好地渲染细笔画字体。

对于使用高分辨率、高刷新率显示器的程序员,轻量级字体如Victor Mono可能是一个好选择。而对于使用普通显示器的用户,笔画更重的字体如JetBrains Mono可能提供更好的渲染效果。

中英文混排的特殊挑战

对于中文用户,编程字体选择面临额外的复杂性。

字宽不匹配问题

大多数编程字体是拉丁字母优先设计的。当显示中文时,编辑器会回退到系统中文字体。这导致了宽度不匹配:中文字符通常是英文的两倍宽,但不同字体的比例可能略有差异。

解决方案之一是使用专门设计的中英文等宽字体,如更纱黑体(Sarasa Gothic)。更纱黑体为每个拉丁字母精确分配半个中文字符的宽度,确保对齐完美。

但这也带来一个问题:为了对齐,英文部分可能被迫压缩或拉伸,牺牲了原始字体的设计意图。

VS Code的字体配置技巧

Visual Studio Code允许为中文和英文分别指定字体:

{
  "editor.fontFamily": "'JetBrains Mono', 'Sarasa Mono SC', monospace"
}

这个配置会优先使用JetBrains Mono显示英文代码,当遇到中文字符时回退到更纱黑体。关键是要确保两个字体的视觉协调性——大小、粗细、风格应该接近。

如何选择适合你的字体

没有适合所有人的"最佳"字体。以下是一个决策框架:

第一步:确定你的约束

  • 显示器:分辨率、刷新率、屏幕尺寸
  • 视力状况:是否近视、散光、老花?是否需要特殊辅助?
  • 工作内容:前端开发?后端?数据科学?不同场景对字符需求不同
  • 团队协作:是否需要共享代码?是否进行代码演示?

第二步:候选字体测试

使用以下测试字符串评估字体:

o0O s5S 9gq z2Z Il1|!ij a-+^*~=b .,;: _ `'"
@ {([|])} /* <-> <=> <~> <|> |= /= += ~= */

关注以下字符对的区分度:0O1lI{}[]、`’"``。

第三步:实际环境测试

在真实编码场景中测试至少一周。关注:

  • 长时间编码后的眼睛疲劳程度
  • 快速扫描代码时的流畅感
  • 调试时识别字符的准确度

第四步:微调

找到喜欢的字体后,调整以下参数:

  • 字号:通常13-15px是最佳区间
  • 行高:1.2-1.4倍行距通常最舒适
  • 字重:根据显示器和个人偏好选择

等宽字体正在失去其必要性

等宽字体在编程中的统治地位,是技术限制的历史遗产,而非最优解。现代技术已经打破了这些限制——我们可以用任何字体写代码。

但这不意味着等宽字体会消失。它们有着独特的美学价值和实用价值,特别是在对齐和等宽显示场景。关键是:选择字体应该基于明确的需求和偏好,而非盲目的习惯。

下一件值得思考的事是:为什么编辑器没有提供更好的自动对齐功能?如果编辑器能够智能处理对齐,我们就可以自由选择最适合阅读的字体——无论是等宽还是比例字体。

毕竟,编程的核心是清晰表达意图。字体应该服务于这个目标,而不是限制它。


参考资料

  1. Production Type. From Stoichedon to programming: a concise history of monospaced typefaces. https://productiontype.com/article/from-stoichedon-to-programming-a-concise-history-of-monospaced-typefaces
  2. JetBrains. JetBrains Mono: A free and open source typeface for developers. https://www.jetbrains.com/lp/mono/
  3. Evil Martians. Beyond monospace: the search for the perfect coding font. https://evilmartians.com/chronicles/beyond-monospace-the-search-for-the-perfect-coding-font
  4. Better Web Type. An analysis of 5 monospaced fonts with coding ligatures. https://betterwebtype.com/5-monospaced-fonts-with-coding-ligatures/
  5. Wery JJ, Diliberto JA. The effect of a specialized dyslexia font, OpenDyslexic, on reading rate and accuracy. Ann Dyslexia. 2016;66:1-11. https://pmc.ncbi.nlm.nih.gov/articles/PMC5629233/
  6. Butterick M. Ligatures in programming fonts: hell no. https://practicaltypography.com/ligatures-in-programming-fonts-hell-no.html
  7. Nick Gravgaard. Programming fonts: proportional vs monospaced. https://nick-gravgaard.com/elastic-tabstops/programming-fonts
  8. MDPI. Eye-Tracking Study of Reading Speed from LCD Displays. https://www.mdpi.com/1995-8692/8/1/3
  9. Wikipedia. Slashed zero. https://en.wikipedia.org/wiki/Slashed_zero
  10. History of Information. The Courier Monospaced Typeface Debuts. https://www.historyofinformation.com/detail.php?id=2059
  11. Nielsen Norman Group. Legibility, Readability, and Comprehension. https://www.nngroup.com/articles/legibility-readability-comprehension/
  12. ResearchGate. Evaluating Code Readability and Legibility. https://www.researchgate.net/publication/346584030
  13. OpenDyslexic. Official website. https://opendyslexic.org/
  14. Fira Code GitHub. https://github.com/tonsky/FiraCode
  15. Microsoft Learn. Typography.SlashedZero Property. https://learn.microsoft.com/en-us/dotnet/api/system.windows.documents.typography.slashedzero
  16. Reddit. dotted zero or slashed zero for programming? https://www.reddit.com/r/fonts/comments/rywfbf/dotted_zero_or_slashed_zero_for_programming/
  17. CSDN. VS Code中适用于任何中文字体的中英文混合等宽显示的配置方案. https://blog.csdn.net/dxkh/article/details/119100904
  18. 知乎. 编程中需要中英混排时该选用哪种字体?https://www.zhihu.com/question/24732078
  19. 腾讯云. 5 款适合程序员的开源字体. https://cloud.tencent.com/developer/news/401491
  20. Medium. 设计师应该关注的一些字体排印技术. https://medium.com/@zway/
  21. LookAway. A Developer’s Guide to Preventing Eye Strain While Coding. https://lookaway.com/blog/2026/01/21/a-developers-guide-to-preventing-eye-strain-while-coding/
  22. ResearchGate. The Effects of Font Type and Spacing of Text for Online Readability. https://www.researchgate.net/publication/339278256
  23. PMC. Serifs and font legibility. https://pmc.ncbi.nlm.nih.gov/articles/PMC4612630/
  24. GitHub. etcd-io/raft: Raft library. https://github.com/etcd-io/raft
  25. Hacker News. Ligatures in programming fonts discussion. https://news.ycombinator.com/item?id=30011775