技能|同值令牌化零视觉重构法
适用场景
需要消除硬编码字面量(颜色/圆角/阴影/动效时长)改用设计令牌,但项目红线是
「界面即最终稿」——不准动任何视觉。本法在红线内完成重构。
核心原理
CSS 变量解析后与原字面量逐字节等价,因此渲染结果完全相同:
:root { --tk-fff: #fff; } /* 值与原字面量完全相同 */
.card { color: var(--tk-fff); } /* 解析结果 === #fff */
操作步骤
-
全量枚举字面量并按频次降序:
bash grep -oE '#[0-9a-fA-F]{3,6}' kb_main.css | sort | uniq -c | sort -rn -
定覆盖率上限即停:达到 90% 左右就收手。
剩余 count=1 的低频零散色值留白名单——批量改它们的视觉收益为零、风险却不成比例。 -
脚本化逐色处理(不要手工 sed),每个色值三步:
- 在:root顶部插入--tk-<hex>: <hex>;(值同原字面量)
- 把主体区该字面量的所有出现替换为var(--tk-<hex>)
- 校验:从主体区剔除令牌块后,该字面量归零;花括号平衡;令牌定义齐全 -
处理顺序(先高频后低频):
#fff→#cbd5e1→#111/#0f172a→ 灰阶族 → 语义色族(绿/琥珀/红)→ 低频零散 -
零视觉变化三重验证:
- 脚本内:替换后主体区该色字面量余 0(仅令牌定义 1 处)
- 语法:node/CSS 解析无误、括号平衡
- 线上:静态资源是从磁盘实时读取的,抓取线上 CSS 确认--tk-*已生效(无需重启)
注意边界
- 严禁一次性全量替换:必须逐色、每色三步验证,出视觉 delta 立即停。
- 令牌名用
--tk-<hex>而非语义名(如--tk-fff不是--color-on-accent)——
纯同值替换零风险;语义化会诱导顺手改值,那是另一件事,需单独确认。 - JS 内联
style="...#fff"属运行时拼接,本法不动,避免触碰 JS 逻辑。 rgb()/rgba()形态与 hex 形态不同批次处理,别混在一次替换里。
反例避雷
| 反例 | 后果 |
|---|---|
| 手工逐处 sed 替换 | 漏改、错改,且无法回归验证 |
令牌定义写归一化值(如 #ffffff) |
虽然等价但引入"看起来变了"的审计噪音,仍应逐字节相同 |
| 一次替换 62 种色 | 无法定位是哪一处引发视觉差异,出问题难回滚 |
| 把 10px/11px 字号一并"顺手规范化" | 撞界面红线(本轮教训:10px 密集数据标签必须入白名单而非强改) |