首页
/ impeccable typeset 全流程指南:在不推翻视觉身份的前提下打磨字体层次、阅读体验与字体交付

impeccable typeset 全流程指南:在不推翻视觉身份的前提下打磨字体层次、阅读体验与字体交付

2026-09-08 11:36:12作者:卓炯娓

字体的本质是信息、层级与声音的载体。impeccable 项目的 typeset 命令(定义为 "Improve typography hierarchy and fonts")是一条面向 AI 设计助手(Agent)的排版专项参考指令,它的工作原则很克制:在既有视觉世界内部改良字体,除非用户明确要求,否则绝不擅自替换产品身份。本文以 .rovodev/skills/impeccable/reference/typeset.md 为骨架,结合同一技能库的 SKILL.mdlive.mdnew-work.md 与 iOS/Android 平台规范,完整还原并深入讲解这套排版的评估—设系统—落地—验证工作流,读完你将掌握:如何按访问者模式决定排版的表达边界、如何用双通道独立评估找出真正的问题、如何用最少角色与字族建立不可混淆的层级、如何保证阅读度量(measure)、行高、字距、深色表面补偿等细节落地,以及如何在 Live 变体模式下用受控的 scale 参数为字体排印开放试错空间。

一切从既有世界出发:先确认"是否换脸"

排版改良不是从白纸开始的。文档开篇即给出铁律:Typography carries information, hierarchy, and voice. Improve it inside the established visual world; do not replace the identity unless the user asked to. 即先确认当前代码与 DESIGN.md 中已确立的字族、字重与角色分工,再在其上改良使用方式。

这里有一条关键的边界判定:

  • 如果替换字体会产生一套新的视觉身份,必须改道走 new-work.md 的"新视觉工作"流程,并在完成后更新 DESIGN.md——因为 DESIGN.md 是产品持久视觉决策的载体,字体身份的变更属于系统级决策,不能作为一次局部排版微调悄悄完成。
  • 否则,保留已确认的字族,只改进它们的使用方式

new-work 流程(见 .rovodev/skills/impeccable/reference/new-work.md)给出了判断既有事实的方法论:DESIGN.md 缺失不等于绿地项目;缺失的 DESIGN.md 不抹去代码中已经一致的视觉身份——"Visual authority is evidence, not a filename"。排版评估同样适用这一原则:已确认的字族是权威证据,要在它们之上建立更清晰的排印,而不是用"换个更好看的字体"来回避结构问题。

用访问者模式决定表达边界

impeccable 的核心框架是四种访问者模式(来自 SKILL.md:Persuade / Operate / Read / Experience),模式命名的是"这个表面的成功长什么样"。typeset 指令把模式直接映射为排版的表达权限:

模式 排版表达边界
Persuade + Experience 展示级(display)字体可以承担"声音/性格"的职责;当构图受益时,允许果断的对比与响应式字号
Operate + Read 稳定、可扫读、度量优先;一个精调的字族加一套固定的角色刻度往往就是正确答案
Native(iOS / Android) 遵循对应平台规范,包括平台缩放与无障碍行为

一句话概括:营销与作品集页面允许展示字体替产品发声,而工具型、文档型界面要的是稳定与可扫读,展示欲让位于任务完成。模式的判定依据是请求的表面对应什么模式,而不是产品整体——一个工具的落地页仍是 Persuade,一个时装品牌的文档仍是 Read。

原生平台的排版铁律

当目标是原生平台时,typeset 要求你遵循 ios.mdandroid.md。这两份文档对排版划定了不容妥协的基线:

iOS(ios.md

  • 使用系统文本样式(Large Title 到 Caption),让文字跟随用户的阅读字号,禁止硬编码 point 尺寸
  • 界面字体由 San Francisco(SF Pro / SF Compact)承担,品牌字体只允许出现在展示(display)场景;
  • 有明确下限:正文 17 pt,最小 11 pt;44×44 pt 是每个可点击控件的最低触达面积。

Android(android.md

  • 使用 Material 3 的 type scale(Display / Headline / Title / Body / Label,各含 large/medium/small 分级),把文本映射到角色,绝不逐屏手挑字号
  • Roboto 是系统字体,品牌字体通过 type scale 主题化进入界面;
  • 单位必须用 sp,绝不使用固定 px,字号才能跟随系统设置。

双通道独立评估:审美判断与机械扫描互不污染

改代码之前,先做诊断。typeset 要求两套彼此隔离的评估,且明确警告:不要让检测器的发现先入为主地锚定设计评估(Do not let detector findings anchor the design assessment)。如果有可用的子 Agent 工具且被允许,两条通道应独立并行运行;否则按顺序由自己执行。

通道一:字体排印评估(typographic assessment)

检查代表性页面与样式,对下列每个问题都必须用文件、选择器或计算值作答,而不是凭感觉:

  1. 权威性与契合度(Authority and fit):当前确立了哪些字体、字重与角色?它们契合产品与所选视觉世界,还是未经审视的默认值?每个字族都是必要的吗?
  2. 层级(Hierarchy):标题、正文、标签、元数据、数据等角色能否一眼区分?相邻的字号或字重是否过于接近,以至于无法承担不同职责?
  3. 刻度与一致性(Scale and consistency):存在有意的角色刻度,还是一堆任意值?同一角色在不同屏幕与状态间是否保持一致?
  4. 阅读(Reading):正文行长是否落在舒适的 45–75 字符(ch) 区间?行高、段落节奏、对比度与字距(tracking)是否针对真实的字体、字宽、语言与表面做了调校?
  5. 压力测试(Stress):长标题、本地化膨胀、缩放、窄容器、缺失字重、字体回退(fallback)时会发生什么?
  6. 交付(Delivery):是否只加载了实际使用的资源?回退度量(fallback metrics)、加载策略与可变字体(variable-font)设置是否避免了不可见文字与破坏性 reflow?

通道二:机械扫描(mechanical scan)

随后运行检测器:

node .rovodev/skills/impeccable/scripts/detect.mjs --json --scope type [target files or dirs]
  • --json 输出结构化结果,便于后续程序化处理;
  • --scope type 把扫描范围收窄到字体排印相关信号;
  • 末尾的 [target files or dirs] 传入本次要检查的文件或目录。

同时,检测器无法解读的动态或任意字体值(例如由 JS 注入、或来自 CSS 变量拼接的字体值)需要人工另行检查。编辑前必须综合两通道的结论,并记录哪些发现是某一通道单独捕捉到的。一个关键认知是:干净的扫描结果只是地板(floor),不是字体排印优秀的证明——机械扫描证明"没有明显的坏信号",但证明不了层级设计得对。

先设系统,再动手:把排版决策写下来

动手编辑前,typeset 要求你**陈述(state)**这次排版系统的设计意图:

  • 界面需要哪些角色(role);
  • 角色之间预期的对比度
  • 阅读度量与密度(measure 与 density);
  • 哪些既有字体与字重是权威的;
  • 有哪些性能、本地化或无障碍约束

陈述这些不是走形式,它把"审美偏好"变成"可验证的设计契约"。在此基础上遵循两条原则:

  • 用最少的角色与字族让层级不可混淆(Use the fewest roles and families that make the hierarchy unmistakable);
  • 刻意地组合字号、字重、间距与调性(tone),而不是让字号独自承担全部工作;
  • 角色名与 token 应描述用途而非数值(purpose over value)——例如用 --text-body--text-eyebrow 这类语义名,而不是 --font-16 这类裸值名,这样后续调整数值不会污染调用方语义。

落地细则:从 16px 地板到深色表面的三维补偿

typeset 的 Apply 部分给出了一组可执行、可复现的排版施工规则,逐条展开如下:

  • 正文地板:正文应保持舒适的可读性与可缩放性。Web 普通正文以 1rem / 16px 为地板,除非高密度角色、平台惯例或用户设置证明确有理由更低。
  • 阅读度量:散文类内容保持在 45–75ch。行高与度量成反比调校:行越宽通常需要越多 leading(行距),避免长行加紧凑行高造成串行。
  • 深色表面的浅色文字补偿:浅色文字压在深色表面上会产生光学收缩,需要在三个感知轴上同时补偿——略微加大行高、略微增加字距、在字体需要时再加一档字重。只加一档是不够的。
  • 行高要按字体/宽度/语言/对比度调,而不是套一个万能比例(如一律 1.5);不同字族的 x-height、字宽与字形密度差异很大。
  • 重复角色跨屏幕、跨状态保持一致——这是可扫读性的根基。
  • 善用 OpenType 特性:当内容受益时使用数字特性(numeric)、等宽表格数字(tabular)、代码样式(code)与标签(label)特性。
  • 字体交付:只加载用到的字体资源与字重;提供度量兼容的回退字体;避免阻塞文字渲染。
  • 展示字体与密集界面的区别对待:营销类展示文字在空间允许时响应可用空间是有益的;而密集的产品界面与阅读表面要保持空间可预测(spatially predictable)。
  • 保留平台无障碍机制:浏览器缩放、用户字体设置、iOS Dynamic Type、平台文字缩放都必须原样保留。
  • 段落节奏单一化:用段间距或首行缩进之一作为主要段落节奏信号;两者并用通常会造成边界被双重标记(double-marking)。

两条不可逾越的底线:不要让字体装饰性凌驾于可理解性之上不要引入第二个字族,除非存在只有它能单独完成的明确角色

验证:每一条都要给出证据,不许用"是"敷衍

改完不是结束。typeset 的 Verify 清单要求逐项用渲染或源码证据作答:

  1. 主(primary)、次(secondary)、正文(body)、元数据(metadata)角色不读文字也能被认出
  2. 长文本在相关宽度与语言下依然舒适;
  3. 这套字体排印属于这个产品及其已确立的视觉世界
  4. 加载过程不产生破坏性 reflow,也没有不可见文字
  5. 缩放、文字缩放、焦点、对比度、收窄视口等路径依然可用;
  6. 最终的机械扫描没有无法解释的发现

每回答一项都要给证据(render 截图或源码行),然后重跑一遍扫描。禁止用光秃秃的"是"来替代验证。这与 impeccable 全局的"用有界的一轮验证,而不是无限自循环"哲学一致:批量检查一轮,一次性修复,最多再确认一轮,然后停止打磨。

当层级确实立住之后,把工作移交给 /impeccable polish(对应 polish.md)做最终的质量收尾——typeset 负责把层级做对,polish 负责在交付前的最后一公里查漏补缺。

在 Live 变体模式下为字体排印保留参数

如果这次排版工作需要进入 impeccable 的 Live 可视化变体模式(在浏览器里选中元素、生成并对比多个变体),typeset 定义了**签名参数(signature params)**契约:

Every variant declares a coarse scale parameter and authors its type ramp against var(--p-scale, 1).

即:每个变体都必须声明一个粗粒度(coarse)的 scale 参数,并把整套字号刻度(type ramp)写成相对该 CSS 变量的表达式。声明的 JSON 结构是:

{"id":"scale","kind":"range","min":0.85,"max":1.3,"step":0.05,"default":1,"label":"Scale"}

字段语义与 live.md 的参数契约(见 live.md)对齐:

  • kind: "range" 对应滑杆控件,运行时通过 CSS 变量 --p-scale 驱动排版刻度;CSS 中应写成 var(--p-scale, 1),第二个参数 1 是默认回退值;
  • min: 0.85 / max: 1.3 给出了合理的收放边界(压缩至 85%、放大至 130%),step: 0.05 控制滑杆粒度;
  • default: 1 是变体初始值——live.md 明确指出"Reset on variant switch is a known limitation: each variant starts at its declared defaults",所以默认值必须审慎;
  • label 是浏览器停靠栏(dock)上展示给用户的控件名。

live.md 的其余参数纪律同样适用:硬上限是每个变体 4 个参数(four per variant);除了 scale,typeset 允许至多再加一个配对(pairing)或字重(weight)参数,且前提是它代表一个真实的系统级选择,而不是一次性的微调——live.md 的准则是"若用户可能嘀咕'再紧一点'或'多一点强调'就值得开一条参数轴,而微小的边距与一次性微调不是参数"。按 action 加载子命令参考(SKILL.md 的 live 段写明 typeset 等 action 的 MUST params 要叠加在预算之上),排版类变体即须携带本 scale 参数。

参数本身属于设计的一部分:在规划阶段就要命名好每个变体的 2–3 个旋钮(knobs),而不是事后补救。range 参数在预览 CSS 里用 var(--p-<id>, default) 承接;最终被接受(accept)的值会被 live-accept.mjs 记录,carbonize 清理阶段再把它们烘焙成字面量或更新变量的默认值(详见 live.md 的 carbonize 步骤)。

工作流全景:从判定到收尾的一体化闭环

把散落的步骤串起来,一次完整的 typeset 改良遵循这样的顺序:

  1. 判定边界:确认这是在既有世界内的改良;若替换字体会创造新身份 → 改道 new-work + 更新 DESIGN.md;若是原生平台 → 先读 ios/android 规范。
  2. 双通道评估:字体排印评估 + detect.mjs --json --scope type 机械扫描,独立进行、综合裁决,并补充检查检测器读不到的动态字体值。
  3. 陈述系统:写下角色清单、角色间对比度、度量与密度、权威字族字重、性能/本地化/无障碍约束。
  4. 落地修改:按 Apply 细则施工(16px 地板、45–75ch、行高与度量反比、深色表面三维补偿、语义化 token、最小字族数)。
  5. 证据化验证:对 Verify 清单逐项给出渲染/源码证据,重跑扫描确认无未解释发现。
  6. 交接:层级成立后交 /impeccable polish;需要 Live 变体试错时,为每个变体声明 scale 参数并遵守 live.md 的参数契约。

整体上,这条指令把"把字体弄好看"这种模糊诉求,改造成了一个有证据、有边界、可验证、可交接的工程流程。它与 impeccable 的整体原则一脉相承:任何局部改良都要服务于产品真相与已确立的视觉权威,评估要有界、证据要落到文件与计算值、打磨要止于该止的地方。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391