[{"data":1,"prerenderedAt":885},["ShallowReactive",2],{"content:\u002F2025\u002Ffont-tips":3,"surround:\u002F2025\u002Ffont-tips":873},{"id":4,"title":5,"body":6,"categories":846,"date":848,"description":849,"draft":850,"extension":851,"image":852,"meta":853,"navigation":855,"path":856,"permalink":857,"published":857,"readingTime":858,"recommend":857,"references":857,"seo":863,"sitemap":864,"stem":865,"tags":866,"type":870,"updated":871,"__hash__":872},"content\u002Fposts\u002F2025\u002Ffont-tips.md","前端字体二三事",{"type":7,"value":8,"toc":812},"minimark",[9,13,17,21,24,41,44,55,63,66,93,96,99,108,123,135,138,141,150,153,157,161,164,179,191,197,200,203,206,213,224,227,230,237,243,246,249,255,273,276,279,285,288,291,297,306,309,312,315,318,321,324,327,340,371,378,385,388,394,401,408,458,465,468,471,474,481,503,509,512,518,521,524,540,551,563,566,582,590,593,600,607,616,619,634,645,663,695,698,701,712,745,754,760,766,769,783,789,795,802],[10,11,12],"h2",{"id":12},"这个世界是一个巨大的合成",[14,15,16],"p",{},"从 Minecraft 中奇妙的物品合成玩法，到现代化工领域里复杂的物质合成过程，合成深刻地影响着我们体验世界的方式。在前端的数字世界里，浏览器的字体合成 (synthesis) 为缺失的字形提供了必要的补救。然而，就像所有工具都有其局限性，在某些场景下，这种合成效果并不尽如人意。",[18,19,20],"h3",{"id":20},"浏览器合成的粗体",[14,22,23],{},"中文字体——当你轻易地选择网络字体、艺术字体时，粗体会拉你陷入泥潭深沼。",[14,25,26,27,34,35,40],{},"设想一下：当你想给网站选择一个科技感的标题字体（",[28,29,33],"a",{"href":30,"rel":31},"https:\u002F\u002Fwww.iconfont.cn\u002Ffonts\u002Fdetail?cnid=clpB5hhpYWUN",[32],"nofollow","钉钉进步体","）或是优雅且便于阅读的正文字体（",[28,36,39],{"href":37,"rel":38},"https:\u002F\u002Fgithub.com\u002Flxgw\u002FLxgwWenKai",[32],"霞鹜文楷","）时，总是不可避免地使用到粗体样式。等等，这些字体有粗体吗？",[14,42,43],{},"我对用户界面十分敏感，每当看到黏在一起（也许普通用户无法察觉）的笔画时，我便知道浏览器合成的粗体发力了。",[45,46,52],"pre",{"className":47,"code":49,"language":50,"meta":51},[48],"language-css",":root {\n\tfont-synthesis: style;\n}\n","css","",[53,54,49],"code",{"__ignoreMap":51},[14,56,57,58,62],{},"请务必像这样干掉它！因为我们还有粗心的前端选手，对于使用 Unicode 私有区的图标字体，都错误地应用了粗体样式——你能想象到 CC-BY 的 ",[59,60],"icon",{"name":61},"fa6-brands:creative-commons-by"," 小人图标，在粗体下圆形脑袋被揍成了双圈头吗😨？",[18,64,65],{"id":65},"浏览器合成的斜体",[67,68,70],"alert",{"title":69},"参阅文档",[71,72,73,84],"ul",{},[74,75,76],"li",{},[28,77,80,83],{"href":78,"rel":79},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-synthesis",[32],[53,81,82],{"code":82},"font-synthesis"," - CSS | MDN",[74,85,86],{},[28,87,90,83],{"href":88,"rel":89},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-style",[32],[53,91,92],{"code":92},"font-style",[14,94,95],{},"中文语境下，具有良好美学素养的设计师不会轻易调用斜体。因为中文字体一般没有专门为斜体设计的字形，而排版软件只会粗暴地倾斜字形，导致字体不协调。",[14,97,98],{},"但在代码语法高亮中，我们还会遇到斜体——英文字体有斜体 (italic) 和倾斜体 (oblique)，但等宽字体呢？",[14,100,101,102,107],{},"非常遗憾的是，我在开发时注意到了受人喜爱的著名编程字体 ",[28,103,106],{"href":104,"rel":105},"https:\u002F\u002Fgithub.com\u002Ftonsky\u002FFiraCode",[32],"Fira Code"," 具有不协调的斜体字形，这显然是由浏览器合成的。",[14,109,110,111,116,117,122],{},"即使 Fira Code 具有良好的连字 (ligature) 特性，但不提供斜体字形是难以容忍的（参阅 ",[28,112,115],{"href":113,"rel":114},"https:\u002F\u002Fgithub.com\u002Ftonsky\u002FFiraCode\u002Fissues\u002F134",[32],"Issue #134","）。我对于 JetBrains Mono 和 Fira Code 多年里的纠结便轻易地到此为止（",[28,118,121],{"href":119,"rel":120},"https:\u002F\u002Fgithub.com\u002FL33Z22L11\u002Fblog-v3\u002Fcommit\u002F0df1410150db09943dd520c39dfdab065cd7d386",[32],"commit #0df1410","）了。",[14,124,125,126,129,130,134],{},"如果你要干掉合成斜体，可能得设置 ",[53,127,128],{"code":128},"font-synthesis: none"," 了，但我没有",[131,132,133],"em",{},"对抗合成斜体","的勇气😿。",[10,136,137],{"id":137},"排版优化",[18,139,140],{"id":140},"深色模式下减少字重",[14,142,143,144,149],{},"在游玩「绝区零」时，我难以辨认游戏内风格字体显示的文本，阅读深色背景下的白色粗体「",[28,145,148],{"href":146,"rel":147},"https:\u002F\u002Fwww.inpin.cn\u002Finpin\u002Fdetail_new.html?fontId=inpinHongMengTi-a049701dbe5f451d82e7c5b78a88d6d4",[32],"印品鸿蒙体","」格外吃力。你一定听过这种说法：黑色是「收缩色」，白色是「扩张色」。因此黑底白字超粗体说是视觉灾难也毫不过分。",[14,151,152],{},"在我玩了半年这游戏后，我偶然得知竟然能在「游戏设置」的一个犄角旮旯里调整字体粗细！？Bro，不在默认情况下给出最佳设置，反而让用户手动调整，我真的在视觉上过于敏感吗？！在选择了「全局细体」后，终于能轻松阅读界面文本了。",[18,154,156],{"id":155},"基线字距和行高","基线、字距和行高",[158,159,160],"h4",{"id":160},"行文中元素的垂直居中",[14,162,163],{},"也许你听说过所谓「元素垂直居中的 N 种方式」，但应该根据具体情况选择更合适的方式。比如这里有几种通过「不居中」实现的「居中」：",[14,165,166,167,170,171,174,175,178],{},"如果你有一个高度略大的图标混合在行文中，比如 ",[59,168],{"name":169},"ri:github-fill","，它想要在视觉上垂直居中，可以通过 ",[53,172,173],{"code":173},"vertical-align: sub"," 把图标的基线对齐到父元素的下标基线；如果你有一个更大的图标，可以通过 ",[53,176,177],{"code":177},"vertical-align: text-bottom"," 把图标的基线对齐到父元素的字体底部。",[14,180,181,182,187,188,190],{},"如果有一个高度略大的 flexbox 混合在行文中，比如 ",[183,184,186],"badge",{"link":185},"https:\u002F\u002Fblog.zhilu.site\u002F","纸鹿摸鱼处","，flexbox 的底部会对齐到行文的基线，它内部的文本就偏高了。何解，是使用 ",[53,189,177],{"code":177},"，然后当一个调参大侠吗？其实 flexbox 内的文本基线应该对齐到行文的基线，然后单独调整图片的对齐方式即可。",[45,192,195],{"className":193,"code":194,"language":50,"meta":51},[48],".badge {\n\tdisplay: inline-flex;\n\talign-items: baseline;\n\theight: 1.6em;\n\tline-height: 1.6;\n}\n\n.badge-icon {\n\t\u002F* `center` 为的不是居中而是拉齐😈 *\u002F\n\talign-self: center;\n\theight: 100%;\n}\n",[53,196,194],{"__ignoreMap":51},[14,198,199],{},"哦对，如果用思源黑体 (Noto Sans SC)，你可能会发现它难以垂直居中，下文我会具体指出。",[158,201,202],{"id":202},"宽敞一些",[14,204,205],{},"微信公众号的推文应用了以下规则：",[45,207,211],{"className":208,"code":209,"language":50,"meta":210},[48],"body {\n\tfont-family: PingFang SC, system-ui, -apple-system, BlinkMacSystemFont, Helvetica Neue, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;\n\tletter-spacing: 0.034em;\n\tline-height: 1.6;\n\tword-wrap: break-word;\n\ttext-align: justify;\n\thyphens: auto;\n\ttext-underline-position: under;\n\ttext-decoration-skip-ink: none;\n\ttext-underline-offset: 0.1em;\n\ttext-size-adjust: 100%;\n}\n","wrap",[53,212,209],{"__ignoreMap":51},[14,214,215,216,219,220,223],{},"在这个小标题下，我更想强调合理使用 ",[53,217,218],{"code":218},"letter-spacing"," 和 ",[53,221,222],{"code":222},"line-height","，可以让排版变得宽松，避免拥挤。留白也是一种美。",[158,225,226],{"id":226},"不止为了宽敞",[14,228,229],{},"设置行高除了能让内容变得不拥挤，还能帮助你保持元素高度、垂直居中的一致性。",[14,231,232,233,236],{},"默认情况是 ",[53,234,235],{"code":235},"line-height: normal","，它使用字体预设的行高。只出现中文或英文的元素就会由此产生不同的高度。另外，一些字体在不设置行高时，文字在字体框不能垂直居中（可选中后观测），而这种情况是无论外层设置多少种“居中”都无法解决的。",[45,238,241],{"className":239,"code":240,"language":50,"meta":51},[48],":root {\n\t\u002F* 解决文本垂直居中问题😎 *\u002F\n\tline-height: 1.4;\n}\n\n.foo {\n\t\u002F* 输入即可召唤文本垂直居中问题 + 中英文高度不一致 *\u002F\n\tline-height: normal;\n}\n",[53,242,240],{"__ignoreMap":51},[14,244,245],{},"还有些字体就更拉了，比如“抖音美好体”，设置了行高也无法垂直居中，前端也很难调，我的建议是别用或切成图再用。CSS Houdini 的 Font Metrics API 草案、实现、推广后也许可以精调，但我觉得那是十年后的事情。",[18,247,248],{"id":248},"必要时打断",[45,250,253],{"className":251,"code":252,"language":50,"meta":51},[48],":root {\n\tword-wrap: break-word;\n\thyphens: auto;\n}\n",[53,254,252],{"__ignoreMap":51},[14,256,257,258,261,262,265,266,272],{},"你可能注意到刚刚微信公众号的 CSS 考虑到了这些。如果不这样写，长单词会直接撑开元素或者整个网页。那么微信公众号的 CSS 赢了吗？赢了一部分，比如下文还会继续提到 ",[53,259,260],{"code":260},"text-size-adjust: 100%"," 的妙用，但 ",[53,263,264],{"code":264},"hyphens: auto"," 在中文语言下没有发挥作用，只有网页设置 ",[53,267,270],{"className":268,"code":270,"language":271},[269],"language-html","\u003Chtml lang=\"en\">","html"," 等西文时才会生效；另外，字体选择似乎也能优化？",[18,274,275],{"id":275},"平衡换行与两端对齐",[14,277,278],{},"你也许会遇到这种问题：居中对齐的文本万一遇到了换行，且只将一两个字符换到下一行时，会显得很突兀。",[45,280,283],{"className":281,"code":282,"language":50,"meta":51},[48],".text-center {\n\ttext-align: center;\n\ttext-wrap: balance;\n}\n",[53,284,282],{"__ignoreMap":51},[14,286,287],{},"这样做便可以使换行的字符尽量均匀分布在几行之间，避免突兀的换行。",[14,289,290],{},"如果文本更长些或者不居中呢？左对齐时平整的段落右侧会出现参差的负形，这时就可以使用两端对齐：",[45,292,295],{"className":293,"code":294,"language":50,"meta":51},[48],"p {\n\ttext-align: justify;\n}\n",[53,296,294],{"__ignoreMap":51},[298,299,300,303],"ol",{},[74,301,302],{},"Word 等排版软件默认使用的是左对齐吗？不，是两端对齐！",[74,304,305],{},"两端对齐会把最后一行文本分散到一整行吗？不，分散对齐才会这样！",[10,307,308],{"id":308},"字体选择",[18,310,311],{"id":311},"正文不使用艺术字体",[14,313,314],{},"正文应当易于辨识。前几年 oooooohmygosh 设计的得意黑大火，我便观测到一些滥用现象。还有东方大楷、书法体等，这些艺术字体用在正文中容易造成视觉疲劳，严重影响阅读效率。",[14,316,317],{},"可以在标题上使用艺术字体，正文使用平凡的字体会更好些。",[18,319,320],{"id":320},"思源黑体有几种",[14,322,323],{},"相信各位听过思源黑体的鼎鼎大名，但它到底有几种，都能用在前端吗？",[14,325,326],{},"首先，便是提供厂商之分：Adobe 家给出的是 Source Han Sans，Google 家给出的是 Noto Sans。它的基线偏低，CJK 字符会在字体框的下部，因此它很难垂直居中。",[14,328,329,330,333,334,339],{},"其次，便是不同的语言和字形变体：Google Fonts 里常用 ",[53,331,332],{"code":332},"Noto Sans SC","，Adobe Fonts 里有 SC（语言特定）和 CN（地区子集）版本，具体区别可以查阅 ",[28,335,338],{"href":336,"rel":337},"https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F526734630",[32],"思源黑体版本指南","。",[14,341,342,343,347,348,352,353,356,357,360,361,370],{},"不管使用何种字体的何种版本，都应",[344,345,346],"strong",{},"在 HTML 标签中注明 lang attribute"," ",[53,349,351],{"className":350,"code":351,"language":271},[269],"\u003Chtml lang=\"zh-CN\">","（",[53,354,355],{"code":355},"zh-Hans"," 也可用，但不推荐)，否则 OpenType 字体的 locl 特性会自动选择用户语言对应的字形。许多中文网站都没有做好这一点，比如 DeepSeek 甚至标注了 ",[53,358,270],{"className":359,"code":270,"language":271},[269],"（可阅读",[28,362,365,366,369],{"href":363,"rel":364},"https:\u002F\u002Fayaka.shn.hk\u002Flangtag\u002F",[32],"HTML 设置 ",[53,367,368],{"code":368},"lang"," 属性的意义","了解更多）。",[14,372,373,374,377],{},"也许是我对于字形过于敏感了？我向不少使用 Linux 的朋友指出「你浏览器里的字并非简体中文字形」时（要配置 ",[53,375,376],{"code":376},"fontconfig"," 呀），他们常常会愣一下，然后才可能注意到字形的细微差异。",[18,379,381,384],{"id":380},"system-ui-与具体字体之争",[53,382,383],{"code":383},"system-ui"," 与具体字体之争",[14,386,387],{},"当我们理解字体家族的 fallback 之后，我们可能写出这样的代码：",[45,389,392],{"className":390,"code":391,"language":50,"meta":210},[48],"[data-domain=\"zhihu.com\"] {\n\tfont-family: -apple-system, BlinkMacSystemFont, \"Helvetica Neue\", \"PingFang SC\", \"Microsoft YaHei\", \"Source Han Sans SC\", \"Noto Sans CJK SC\", \"WenQuanYi Micro Hei\", sans-serif;\n}\n\n[data-domain=\"nowcoder.com\"] {\n\tfont-family: PingFang SC, Source Han Sans CN, Microsoft YaHei, system, -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, wenquanyi micro hei, Hiragino Sans GB, Hiragino Sans GB W3, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, sans-serif;\n}\n",[53,393,391],{"__ignoreMap":51},[14,395,396,397,400],{},"打住，打住。",[53,398,399],{"code":399},"font-family: system-ui, sans-serif"," 也许就够了。",[14,402,403,404,407],{},"假设你是一名设计师或大厂的前端开发人员（一般使用 macOS 了），你观察到 ",[53,405,406],{"code":406},"PingFang SC","（苹方）字体下的界面符合预期。你又在 Windows 下做了测试（大概你也主动装了苹方字体）。但是纸鹿来了，他会告诉你亿些问题：",[298,409,410,430,441],{},[74,411,412,415,416,419,420,422,423,425,426,429],{},[53,413,414],{"code":414},"苹果字体 !== PingFang SC","：苹果的英文字体是 ",[53,417,418],{"code":418},"San Francisco","，中文字体才是 ",[53,421,406],{"code":406},"。如果直接使用 ",[53,424,406],{"code":406}," 作为中英文字体，你会",[344,427,428],{},"缺点「果味」","。微信公众号的网页便是如此。",[74,431,432,433,436,437,440],{},"UI 字体有特殊优化：Windows 上说不定是 ",[53,434,435],{"code":435},"Segoe UI"," 或者 ",[53,438,439],{"code":439},"Microsoft YaHei UI"," 呢？",[74,442,443,444,219,447,450,451,455],{},"你的前端 CSS 习惯有点好，但前端 CSS 习惯好又不太可能：你也许考虑到了某些东亚语言的注音字符可以无限叠加，斜向上生长而「戳」坏你的界面布局；亦或是想要实现单行文本溢出隐藏，于是残忍地为某些元素设置了 ",[53,445,446],{"code":446},"line-height: 1",[53,448,449],{"code":449},"overflow: hidden","。那么代价是什么呢？下划线不见了（也许苹方字体的还在），g\u002Fj\u002Fp\u002Fq 字母的小短腿也不见了。 ",[452,453,454],"blur",{},"你可以打开牛客帖子评论区，看看盖楼回复的用户名变成了什么样。",[344,456,457],{},"字体的 fallback 机制定向地向设计师蒙蔽了单倍行高的潜在风险。",[459,460],"link-banner",{"banner":461,"description":462,"link":463,"title":464},"https:\u002F\u002Fstatic.hsu.cy\u002Fblog\u002F2024\u002F5e81e82408924e7598460af3934e43cd.png","对于苹果系统字体，用得上的时候就不要乱用，用不上的时候也不要硬用。遵守规范，思维放开，才是正道。","https:\u002F\u002Fhsu.cy\u002F2024\u002F04\u002Fnopingfang\u002F","当你以为自己用的是苹果系统字体",[10,466,467],{"id":467},"字体进阶",[18,469,470],{"id":470},"自动空格",[14,472,473],{},"中英文间到底要不要加空格？要不要手动加空格？",[14,475,476,477,480],{},"我的见解是，中英文之间应当有适当的空白，但空白最好",[344,478,479],{},"交由排版引擎实现","而非手动添加。比如 Word，比如微信聊天界面。",[14,482,483,484,489,490,498,499,502],{},"Chrome 120 实现了 ",[28,485,488],{"href":486,"rel":487},"https:\u002F\u002Fdeveloper.chrome.google.cn\u002Fblog\u002Fcss-i18n-features?hl=zh-cn#inter-script_spacing_text-autospace",[32],"CSS 文本模块级别 4 中的脚本间距","，",[491,492,493,494,497],"del",{},"启用 ",[53,495,496],{"code":496},"chrome:\u002F\u002Fflags\u002F#enable-experimental-web-platform-features"," 便可在不同脚本（中英文）间自动添加空白","。Chrome 140 已经支持 ",[53,500,501],{"code":501},"text-autospace: normal"," 特性，在 CSS 中设置即可使用：",[45,504,507],{"className":505,"code":506,"language":50,"meta":51},[48],":root {\n\ttext-autospace: normal;\n}\n",[53,508,506],{"__ignoreMap":51},[14,510,511],{},"但用户代理（浏览器）样式表中似乎缺少了这个：",[45,513,516],{"className":514,"code":515,"language":50,"meta":51},[48],"code, pre {\n\ttext-autospace: no-autospace;\n}\n",[53,517,515],{"__ignoreMap":51},[14,519,520],{},"~~Look into my eyes，回答我，Chrome！！~~现在需要用户手动处理，因为加空格不是默认行为了。",[18,522,523],{"id":523},"对抗文本溢出算法",[525,526,527,530],"blockquote",{},[14,528,529],{},"因为缩放适配小屏幕而导致文字会变得很小，许多手机浏览器会使用文本溢出算法放大文本，改善可读性。当一个包含文本的元素使用了 100% 的屏幕宽度，该算法会增加文本大小，但是不会修改布局。text-size-adjust 这个属性允许开发者去除或者修改浏览器的这种行为，比如，当网页已经适配了小屏幕之后，就不需要这么做了。",[14,531,532,533],{},"—— ",[28,534,537,83],{"href":535,"rel":536},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ftext-size-adjust",[32],[53,538,539],{"code":539},"text-size-adjust",[14,541,542,543,546,547,550],{},"我的网站自豪地认为响应式布局良好，但移动端浏览器依然会放大文本（平板读博客时字体巨大），甚至会导致预期外的换行（未限制 ",[53,544,545],{"code":545},"width"," 的按钮中的最后一个字换到下一行），当时研究出了 ",[53,548,549],{"code":549},"white-space: no-wrap"," 能避免，后来才发现是此实验特性在「搞鬼」。上篇文章也提到了类似哲学——",[552,553,554,560],"quote",{},[555,556,557],"template",{"v-slot:icon":51},[14,558,559],{},"😨",[14,561,562],{},"一些贴心的自适应设计，在一些情况下竟然变成了心智负担！",[18,564,565],{"id":565},"过度优化可能弄巧成拙",[525,567,568,574],{},[14,569,570,573],{},[53,571,572],{"code":572},"font-smooth"," CSS 属性控制字体渲染时应用的抗锯齿效果。",[14,575,532,576],{},[28,577,580,83],{"href":578,"rel":579},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-smooth",[32],[53,581,572],{"code":572},[14,583,584,585,339],{},"听起来很美好？但是，MDN Web Docs 也告诉你",[28,586,589],{"href":587,"rel":588},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-smooth#%E5%8F%82%E8%A7%81",[32],"不要干涉字体平滑",[18,591,592],{"id":592},"可变字体的轮廓",[14,594,595,596,599],{},"你也许了解文字描边，低版本是用多个阴影叠加出来的，高版本可以用 ",[53,597,598],{"code":598},"-webkit-text-stroke"," 实现。但它和可变字体，会碰撞出神奇的火花，比如字体连接处的轮廓——",[601,602,604],"div",{":style":603},"[{\"font-size\":\"3em\"},{\"font-family\":\"InterVariable\"},{\"font-weight\":800},{\"line-height\":1},{\"color\":\"transparent\"},{\"-webkit-text-stroke\":\"1px var(--c-text)\"}]",[14,605,606],{},"中文1234",[14,608,609,610,615],{},"字体拐角处独特的轮廓是「",[28,611,614],{"href":612,"rel":613},"https:\u002F\u002Fmp.weixin.qq.com\u002Fs\u002FbYh3ai4SIYbsLgPzTq9wbA",[32],"开放角","」，用于在字体参数变化时实现更好的视觉连续性。但这种特性会污染简洁的轮廓，因此需要字体轮廓时不建议使用可变字体，尤其注意一些安卓手机的默认字体可能就是 VF。",[18,617,618],{"id":618},"字体高级特性",[14,620,621,622,625,626,629,630,633],{},"你可能还想问 !== 如何显示为 ",[53,623,624],{"code":624},"!==","、\u003C= 如何显示为 ",[53,627,628],{"code":628},"\u003C=","，这是连字 (ligature) 特性，Iosevka、Fira Code、JetBrains Mono 等编程字体都支持，VS Code 手动启用 ",[53,631,632],{"code":632},"\"editor.fontLigatures\": true"," 后即可看到效果。",[14,635,636,637,640,641,644],{},"再比如，我博客左上角鼠标放在 Logo 上时，字体粗细和方圆变化动画如何实现？我使用了阿里妈妈方圆体这款可变字体 (VF, Variable Font)，它除了支持 ",[53,638,639],{"code":639},"wght"," (粗细) 轴上的操作外，还支持 ",[53,642,643],{"code":643},"BEVL"," (圆角) 轴上的调节。",[14,646,647,648,651,652,655,656,219,659,662],{},"再比如 ",[53,649,650],{"code":650},"font-variant-numeric: tabular-nums"," \u002F ",[53,653,654],{"code":654},"font-feature-settings: \"tnum\""," 可以实现等宽数字，在表格、金额场景下还是很有用的，但字体不一定支持了。CSS 的 ",[53,657,658],{"code":658},"font-feature-settings",[53,660,661],{"code":661},"font"," 均不推荐使用，前者对所有字体同时设置而容易产生预期外的效果，后者则会清除所有字体的特征设置而不从父级继承。",[67,664,665],{"title":69},[71,666,667,674,681,688],{},[74,668,669],{},[28,670,673],{"href":671,"rel":672},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002FCSS_fonts\u002FVariable_fonts_guide",[32],"可变字体指南 - CSS | MDN",[74,675,676],{},[28,677,680],{"href":678,"rel":679},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-variation-settings",[32],"font-variation-settings - CSS | MDN",[74,682,683],{},[28,684,687],{"href":685,"rel":686},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-variant",[32],"font-variant - CSS | MDN",[74,689,690],{},[28,691,694],{"href":692,"rel":693},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FCSS\u002Ffont-feature-settings",[32],"font-feature-settings - CSS | MDN",[18,696,697],{"id":697},"网络字体",[14,699,700],{},"中文字符众多，网络字体的传输便会到达 MB 级别。所以有多种方式优化：",[71,702,703,706,709],{},[74,704,705],{},"字体子集化：只加载网页用到的字符。或者极少字符直接使用图片或 SVG。",[74,707,708],{},"字体压缩：使用 woff2 等先进格式。",[74,710,711],{},"字体分包：将字体按 Unicode 码点范围拆分成多个文件，按需加载。",[67,713,715],{"title":714},"网络字体渠道介绍",[71,716,717,724,731,738],{},[74,718,719],{},[28,720,723],{"href":721,"rel":722},"https:\u002F\u002Ffonts.google.com\u002F",[32],"Google Fonts",[74,725,726],{},[28,727,730],{"href":728,"rel":729},"https:\u002F\u002Fwww.thyuu.com\u002F62610\u002F",[32],"免费引入商用黑体字体系列整理及 CSS 字体引入亲妈式教程（20240915更新） – 风记星辰",[74,732,733],{},[28,734,737],{"href":735,"rel":736},"https:\u002F\u002Fchinese-font.netlify.app\u002Fzh-cn\u002F",[32],"中文网字计划",[74,739,740],{},[28,741,744],{"href":742,"rel":743},"https:\u002F\u002Ffonts.zeoseven.com\u002F",[32],"释放字体自由 - ZeoSeven Fonts",[14,746,747,748,753],{},"当然，考虑到 ",[28,749,752],{"href":750,"rel":751},"https:\u002F\u002Fzhuanlan.zhihu.com\u002Fp\u002F1888247674832139754",[32],"Windows、Edge 已经引入 Noto Sans","，我们也可以帮用户、CDN减负，有本地字体时不加载网络资源：",[45,755,758],{"className":756,"code":757,"language":271,"meta":210},[269],"\u003C!-- 使用 .cn 域名增强可访问性 -->\n\u003Clink rel=\"preconnect\" href=\"https:\u002F\u002Ffonts.gstatic.cn\" crossorigin>\n\u003Clink rel=\"stylesheet\" href=\"https:\u002F\u002Ffonts.googleapis.cn\u002Fcss2?family=Noto+Sans+SC:wght@100..900\">\n",[53,759,757],{"__ignoreMap":51},[45,761,764],{"className":762,"code":763,"language":50,"meta":51},[48],":root {\n\t\u002F* Noto Sans SC 通过 CDN 提供 @font-face，无法更名或插入本地源 *\u002F\n\tfont-family: \"InterVariable\", \"Noto Sans SC-Local\", \"Noto Sans SC\", system-ui, sans-serif;\n}\n\n\u002F* 仅在 Chrome 130+ 启用本地可变字体，因为低版本会将 VF 显示为细体 *\u002F\n@supports (box-decoration-break: clone) {\n\t@font-face {\n\t\tfont-family: \"Noto Sans SC-Local\";\n\t\tfont-weight: 100 900; \u002F* 不指定则为 400 *\u002F\n\t\tsrc: local(\"Noto Sans SC\");\n\t}\n\n\t@font-face {\n\t\tfont-family: \"Noto Serif SC-Local\";\n\t\tfont-weight: 100 900;\n\t\tsrc: local(\"Noto Serif SC\");\n\t}\n}\n",[53,765,763],{"__ignoreMap":51},[10,767,768],{"id":768},"用起来吧",[14,770,771,772,775,776,778,779,782],{},"讲了这么多，大家应该收获颇丰。不过鉴于 Noto Sans SC 的西文字形实在太丑，也为避免麻烦的苹果字体调用，我还是想引一个 ",[53,773,774],{"code":774},"Inter"," 字体。Google Fonts 的 ",[53,777,774],{"code":774}," 可变字体其实是砍去许多特性的 ",[53,780,781],{"code":781},"InterVariable","，还是从官方 CDN 源加载吧：",[45,784,787],{"className":785,"code":786,"language":271,"meta":210},[269],"\u003C!-- 防止阻塞 -->\n\u003Clink rel=\"stylesheet\" href=\"https:\u002F\u002Frsms.me\u002Finter\u002Finter.css\" media=\"print\" onload=\"this.media='all'\">\n",[53,788,786],{"__ignoreMap":51},[45,790,793],{"className":791,"code":792,"language":50,"meta":210},[48],":root {\n\t--font-basic: \"InterVariable\", \"Noto Sans SC-Local\", \"sans-serif\", \"PingFang SC\", \"Noto Sans SC\", system-ui, sans-serif;\n\n\tfont-family: var(--font-basic);\n\t\u002F* CDN 提供的 CSS 已经预定义字体函数，这是本站使用的变体 *\u002F\n\tfont-variant-alternates: styleset(open-digits, disambiguation, round-quotes-and-commas);\n}\n\n\u002F* 低像素密度设备下，可以使用 Hint 良好的 system-ui 字体 *\u002F\n@media (max-resolution: 1.2dppx) {\n\t:root {\n\t\t--font-basic: \"InterVariable\", system-ui, sans-serif;\n\t}\n}\n",[53,794,792],{"__ignoreMap":51},[14,796,797,798,801],{},"本地的 Inter 字体不能简单地「通过字体名称调用以实现优先加载本地字形」或者「通过 ",[53,799,800],{"code":800},"font-variant-alternates"," 应用 OpenType 变体」，网上也很难找到正确实现，读者可以动手试试。",[552,803,804,809],{},[555,805,806],{"v-slot:icon":51},[14,807,808],{},"😄",[14,810,811],{},"调用 Inter 网络字体当然是为了一致性，绝不是我想偷懒。",{"title":51,"searchDepth":813,"depth":813,"links":814},4,[815,821,831,837,845],{"id":12,"depth":816,"text":12,"children":817},2,[818,820],{"id":20,"depth":819,"text":20},3,{"id":65,"depth":819,"text":65},{"id":137,"depth":816,"text":137,"children":822},[823,824,829,830],{"id":140,"depth":819,"text":140},{"id":155,"depth":819,"text":156,"children":825},[826,827,828],{"id":160,"depth":813,"text":160},{"id":202,"depth":813,"text":202},{"id":226,"depth":813,"text":226},{"id":248,"depth":819,"text":248},{"id":275,"depth":819,"text":275},{"id":308,"depth":816,"text":308,"children":832},[833,834,835],{"id":311,"depth":819,"text":311},{"id":320,"depth":819,"text":320},{"id":380,"depth":819,"text":836},"system-ui 与具体字体之争",{"id":467,"depth":816,"text":467,"children":838},[839,840,841,842,843,844],{"id":470,"depth":819,"text":470},{"id":523,"depth":819,"text":523},{"id":565,"depth":819,"text":565},{"id":592,"depth":819,"text":592},{"id":618,"depth":819,"text":618},{"id":697,"depth":819,"text":697},{"id":768,"depth":816,"text":768},[847],"开发","2025-04-16 08:49:50","前端字体排版有许多细节需要注意，文章从我的实际开发经验出发，介绍合成字形、对齐技巧、排版优化，以及自己的一些踩坑心得。",false,"md","https:\u002F\u002Fassets.zhilu.cyou\u002Fcover4\u002Ffont-tips.jpg",{"slots":854},{},true,"\u002F2025\u002Ffont-tips",null,{"text":859,"minutes":860,"time":861,"words":862},"21 min read",20.32,1219200,4064,{"title":5,"description":849},{"loc":856},"posts\u002F2025\u002Ffont-tips",[867,868,869],"前端","字体","排版","tech","2025-10-06 23:22:09","A69MDJg3-T_Hn0t6O77WQ9DgHD5Sb8K6KGSBPZheYig",[874,879],{"title":875,"path":876,"stem":877,"date":878,"type":870,"children":-1},"深色模式开发的最佳实践","\u002F2025\u002Fdark-mode-guide","posts\u002F2025\u002Fdark-mode-guide","2025-04-14 10:07:16",{"title":880,"path":881,"stem":882,"date":883,"type":884,"children":-1},"生成式AI正在生成","\u002F2025\u002Fai-abuse","posts\u002F2025\u002Fai-abuse","2025-06-10 21:52:43","story",1782091371717]