字体子集化后中文显示成方块怎么办?

UX-怡博 阅读 59

我用 fontmin 做了字体子集,结果页面上的中文全变成方块了,是不是哪里配置错了?

项目是 React 的,我只保留了英文和几个常用中文字符,但实际渲染时连英文也出问题了。试过把字体文件换成 woff2 格式,还是不行。

import './App.css';

function App() {
  return (
    <div style={{ fontFamily: 'MySubsetFont, sans-serif' }}>
      Hello 你好
    </div>
  );
}

export default App;
我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
Tr° 可欣
看起来你的问题主要出在字体子集化过程中,可能丢失了一些关键字符或者字体文件加载顺序不对。让我一步步来帮你排查和解决这个问题。

首先你需要确认生成的字体文件是否完整包含了你需要的所有字符。我建议你在生成字体时加上调试选项,确保每个字符都在里面。Fontmin 默认可能会忽略一些特殊字符。

接着我们来看看你的代码实现。你这样写 fontFamily 是有问题的,因为浏览器会优先使用系统默认字体,除非明确指定本地字体文件路径。下面是改进后的代码:


import './App.css';

function App() {
return (
<div style={{
fontFamily: "'MySubsetFont', sans-serif", // 注意这里的引号
src: "url('./fonts/MySubsetFont.woff2') format('woff2')", // 添加字体路径
}}>
Hello 你好
</div>
);
}

export default App;


原理是这样:当指定多个字体时,需要用单引号包裹自定义字体名,并且要通过 src 属性明确告诉浏览器去哪里加载这个字体文件。

另外要注意字体文件的格式转换可能会造成字符丢失。建议用 fontforge 这种专业工具检查一下生成的 woff2 文件内容是不是完整的。有时候简单的在线转换器可能会丢东西。

最后别忘了在 CSS 里也声明一下字体:


@font-face {
font-family: 'MySubsetFont';
src: url('./fonts/MySubsetFont.woff2') format('woff2');
}


这个 @font-face 规则要放在全局样式里,让整个应用都能用到这个字体定义。

经过这些步骤应该就能解决你的问题了。记得清理浏览器缓存再测试哦,有时候旧的字体文件会被缓存下来影响效果。要是还是不行,就一个一个字符去排查,看看是不是某些特定字符出了问题。这活儿确实挺磨人的,但慢慢调总能搞定的。
点赞
2026-03-27 13:11
慕容梦幻
这个问题我遇到过,子集化后显示方块一般是这几个原因:

先检查子集化过程

你用 fontmin 做子集的时候,字符是怎么指定的?如果是用文本文件传入要保留的字符,确保文件编码是 UTF-8,而且字符确实写进去了。我见过有人用记事本保存字符列表,结果编码不对,子集化出来的字体是空的。

检查 @font-face 声明

你的 CSS 里要类似这样写:

@font-face {
font-family: 'MySubsetFont';
src: url('./fonts/your-subset.woff2') format('woff2');
font-weight: normal;
font-style: normal;
font-display: swap;
}


注意 font-display: swap 这个属性,加上能避免字体加载时的闪烁问题。

回退字体链要写好

你的样式里只写了 sans-serif 作为回退,这个不够。改成:

font-family: 'MySubsetFont', 'PingFang SC', 'Microsoft YaHei', sans-serif;


这样如果子集字体加载失败或者缺字符,至少能正常显示。

快速验证方法

打开浏览器开发者工具,在 Elements 面板找到那个 div,看看 computed 里的 font-family 应用上了没有。然后在 Network 面板确认字体文件请求返回 200 并且能预览到内容。

如果字体文件请求成功了但大小是 0 或者很小,基本就是子集化过程有问题,重新跑一遍,确保字符列表正确传入。

你用的是哪个版本的 fontmin?现在项目里用的是什么方式引入子集化后的字体文件?
点赞
2026-03-13 11:04