跳到主要内容
文心 · 万形

代码与语法高亮

文章里的一段代码仍然是散文——读者在读它,不是在扫描它找错误。所以这套色板只有四种相近的暖色加正文墨,而不是六种饱和色相。

两个所有者,一条判据

同样是代码块,两个文件各管一半,分界线是这段 HTML 的 class 属性归谁控制。

文件管什么选择器策略
kit/components/code.css你自己写的 <pre class="wx-code">,带标题行与复制按钮。class 选择器,你控制标记。
kit/markdown/syntax.css渲染器吐出的 .wx-md pre > code,class 由高亮器决定。后代选择器,靠 @layer 排序保证不越权。

支持哪些高亮器

类名同时遵循 highlight.js 与 Prism 的约定,不需要中间映射层:把任一个的输出直接放进 .wx-md 即可。

高亮器输出渲染结果

<pre><code class="language-js">
<span class="hljs-comment">// …</span>
<span class="hljs-keyword">const</span>
<span class="hljs-string">"…"</span>
</code></pre>
// 注释是代码块里最常被当散文读的部分
const measure = (text) => {
  return text.length > 36
    ? "过长"
    : "合适";
}

Token 色板与实测对比度

下表的值从 kit/markdown/syntax.css 直接取,对比度是对代码块底色实测的。 check:colors 会逐条量它们——语法色板和正文一样是文字,不享受任何豁免。

Token用于浅色 · 对比度暗色 · 对比度
--code-comment注释与块引用#77726D · 4.55:1#8C857D · 4.57:1
--code-punctuation标点与分隔符#665F58 · 6.01:1#A9A197 · 6.52:1
--code-operator运算符(正文墨)#3A3837 · 11.16:1#E8E3DC · 13.03:1
--code-keyword关键字、选择器#6B5B3E · 6.30:1#C0A878 · 7.22:1
--code-string字符串、属性值#6B5B3E · 6.30:1#A8B98A · 7.90:1
--code-type类型、类名#6B5B3E · 6.30:1#C0A878 · 7.22:1
--code-function函数名#5C4A2F · 8.12:1#D6BE92 · 9.22:1
--code-property属性名、标签名#5C4A2F · 8.12:1#D6BE92 · 9.22:1
--code-number数字、字面量#7A5C3A · 5.88:1#C9A57A · 7.24:1
"退让"有底线

注释和标点曾经是 #9A948D 与 #888580,对代码底 2.87:1 和 3.52:1,两个主题都不合格, 而当时的 check:colors 只测 bg-warm 一个底色,从没量到它们。 注释是代码块里最常被当散文读的部分,是最不该先淡出去的东西。 详见 spec/DECISIONS.md 的 D-28。

代码块的底色

代码面用 --code-bg(浅色 --color-bg-base,比页面底色更亮),而不是更暗的 --color-bg-subtle。两个原因:

  • 余量——更亮的底给标题行的元数据文字和最退让的注释色留出通过 AA 的空间。
  • 方向——阅读轨禁止用色块背景分区。代码块是这条规则里少数几个合理的"面", 它像一张嵌进正文的纸,而不是一块压在正文上的色板。

行内代码

Markdown渲染结果

行内 `--stroke-mark` 与
`border-inline-start` 保持
正文节奏,不换字号档位。

行内 --stroke-mark 与 border-inline-start 保持正文节奏,不换字号档位。

行内代码保留 --color-bg-subtle 的浅底——它需要读作嵌在句子里的一小块, 和整块代码面是两件事。它的文字是正文墨,9.98:1。

没有"正在高亮"这种状态

这套系统禁止 spinner 与骨架屏。如果高亮是在客户端做的, 未高亮的代码块必须已经是可读的——它本来就是正文墨的等宽文字, 高亮只是往上加区分,不是从不可读变可读。这条约束顺带解决了高亮脚本加载失败的情况。