主题导航

Typography

排版

本站西文用 Geist、等宽用 Geist Mono、中文用思源黑体 Noto Sans SC —— 三副都是 OFL 授权、自托管,中文按 unicode-range 切成 97 片按需加载。字号沿用 Tailwind CSS v4 的 text-* 比例。

字号阶梯

每行使用真实尺寸渲染。

颜值 + 好用 Aatext-xs
颜值 + 好用 Aatext-sm
颜值 + 好用 Aatext-base
颜值 + 好用 Aatext-lg
颜值 + 好用 Aatext-xl
颜值 + 好用 Aatext-2xl
颜值 + 好用 Aatext-3xl
颜值 + 好用 Aatext-4xl
颜值 + 好用 Aatext-5xl

字重

颜值 + 好用 Aa 123正文font-normal
颜值 + 好用 Aa 123次强调 / 导航font-medium
颜值 + 好用 Aa 123标题font-semibold
颜值 + 好用 Aa 123重强调font-bold

字体栈

字体由两个运行时变量驱动,库不写死任何字族。不设这两个变量的项目,渲染与接这层 token 之前完全一致。

--hl-font-sans: Geist, ui-sans-serif, system-ui, "PingFang SC", "Microsoft YaHei", sans-serif; --hl-font-mono: "Geist Mono", ui-monospace, Menlo, monospace;

换成自己的字体

全局改 :root 上的变量即可,库里 48 个用 font-mono 的组件会一起跟上。

:root { --hl-font-sans: "Your Sans", ui-sans-serif, system-ui, sans-serif; --hl-font-mono: "Your Mono", ui-monospace, monospace; }

只换某一块

在容器上写同一个变量。要注意正文与等宽不对称:等宽只写变量就生效,正文还要给容器加一个 font-sans 类 —— 自定义属性会继承,但 font-family: var(…) 只在声明了这条属性的元素上重新解析,普通文字继承的是根节点那里已经解析完的字体名,不会回头读变量。

{/* 等宽:写变量就够,font-mono 的元素会在自己的作用域重新解析它 */} <div style={{ "--hl-font-mono": '"IBM Plex Mono", monospace' }}> <Snippet>pnpm add @hulianui/ui</Snippet> </div> {/* 正文:变量之外还要一个 font-sans 类,否则文字仍继承根节点解析好的字体 */} <div className="font-sans" style={{ "--hl-font-sans": "Georgia, serif" }}> 这一段用 Georgia </div>

中文是怎么装进来的

思源黑体全量是 MB 级,整包下发会拖死首屏,所以切成 97 个 unicode-range 分片,浏览器只取页面实际用到的那几片(本页实测 15 片)。分片本身是可变字体,一套覆盖全字重。字体栈里中文必须排在 ui-sans-serif / system-ui 之前 —— 那几个通用族对汉字会直接命中系统字体,排在它们后面的思源黑体永远轮不到。

/* 本站实际的栈:西文 Geist、中文思源黑体、系统字体兜底生僻字 */ --hl-font-sans: Geist, "Noto Sans SC", ui-sans-serif, system-ui, "PingFang SC", "Microsoft YaHei", sans-serif;