Files
wordpress-kratos-yang/assets/css/highlight.css
T
laoyang da0d9ae4a1 代码高亮整套自研:10 浅 + 10 深配色、语言标签、评论区贴代码 (#11)
不再依赖第三方高亮插件,全部由主题自己实现。

主题配色(20 套)
- 浅色 10:github / vs / atom-one-light / idea / xcode /
  stackoverflow-light / intellij-light / googlecode / magula / color-brewer
- 深色 10:github-dark / atom-one-dark / monokai / github-dark-dimmed /
  a11y-dark / stackoverflow-dark / night-owl / srcery /
  panda-syntax-dark / tomorrow-night-blue
- 深色卡片带 data-kind="dark",顶栏跟着换深色底
- 只加载当前选中的一套(20 套全加载会让后出现的规则压前面的,
  切换配色容易"看起来没变")

代码语言标签(用户要求:防止复制错语言)
- 作者标了 language-xxx → 实线边框、正体
- 自动识别猜出来的 → 虚线边框、斜体
- 认不出来 → 显示 "—",仍保持虚线斜体(不冒充作者标注)

行号
- 默认关;行号槽在 <pre> 外面,复制天然不带行号
- 改掉原主题的 word-break:break-all(任意字符断行,代码像乱码)
- 归零 hljs 主题自带的 pre code.hljs{padding:1em},
  否则代码被压低 1em、与行号槽错位 15.5px

复制
- 默认开;安全上下文判断 + execCommand 退路(HTTP 下 clipboard 是 undefined)
- 取 textContent 而非 innerHTML
- 默认 opacity:0、hover 显示、触屏覆盖回 1
  (旧写法只在 @media(hover:none) 里写 1,等于空操作)

自动识别
- 做成选项,默认开
- 只对没标语言的块生效;站内实测长块准确率 22%,不能覆盖作者标注

评论区贴代码
- 评论工具条加"代码"按钮 + 29 种语言面板
- kses 放行 pre 并给 pre/code 放开 class
  (WP 默认 pre 整条剥掉、code 属性全清,此前根本贴不了代码)
- 放行 pre 之后 wpautop/wptexturize/make_clickable 自动让路,
  代码里的连续空行、引号、URL 都不会被改写
- comments.js 用占位符保护代码块,避免 walk() 的 /\n{3,}/ 压缩

其它
- 资源版本号改为读主题头,不再写死(写死会导致以后升级后
  浏览器一直用旧缓存,改了 CSS/JS 完全不生效)
- 删除 footer.php 里旧的 Prism 兜底(两套高亮器同页会互相打架)

验收
- 用线上 284 个真实代码块跑产品代码:284/284 全部变卡片,内容丢字 0、双转义 0
- 47 个 text 标记全部映射到 plaintext(hljs 无 text 语言,不映射会静默不上色)
- 80 个裸 <pre>(无 code 子元素)全部覆盖
- 核心纯函数 65/65;核心反向 10/10 变红
- 浏览器端到端 32/32;行号几何逐行对齐偏差 0.00px,几何反向 4/4 变红
- 端到端反向 7/7 变红;语言标签反向 2/2 变红
- 全量 PHP 语法 95 文件 0 错误

发布:走 theme-update 通道(zip + readme + update.json),
未覆盖服务器主题目录;线上主题目录仍是 3.2.41,待后台升级。
2026-10-26 09:00:17 +08:00

208 lines
6.2 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 代码块样式(highlight.js 自研接管后的卡片外观)
*
* 与 kratos.css 里原有那段的关系:
* 原有 `.k-main .details .article .content pre { … }` 里有
* `background-color:#f8f8f8`、`font-size:11px`、**`word-break:break-all`**。
* 最后这条会在任意字符处断行,代码看起来像乱码 —— 必须压掉。
* 本文件加载在 kratos.css 之后,用更高的特异性覆盖。
*/
/* ── 卡片外壳 ── */
.k-main .details .article .content .cb,
.comment-body .cb,
.cb {
position: relative;
margin: 14px 0;
border: 1px solid #d0d7de;
border-radius: 8px;
overflow: hidden;
background: #fff;
}
/* ── 顶部条:语言标签 + 复制按钮 ── */
.k-main .details .article .content .cb .cb-bar,
.cb .cb-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 10px;
background: #f6f8fa;
border-bottom: 1px solid #d0d7de;
font-size: 12px;
line-height: 1.5;
}
/* 语言标签:让人一眼看到"这是 Java",防止把 Python 和 Java 的实现贴反。
站内实测有 19 篇文章含 ≥2 种语言、38 处相邻代码块语言不同 —— 确有实用价值。 */
.cb .cb-lang {
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 11px;
font-weight: 600;
letter-spacing: .02em;
color: #656d76;
padding: 1px 6px;
border-radius: 4px;
border: 1px solid #d0d7de;
background: #fff;
text-transform: none;
}
/* 🔴 自动识别出来的标签要**看得出来是猜的**:虚线边框 + 斜体。
站内 18 个 ≥4 行的未标注代码块实测自动识别只对了 4 个(22%)——
如果把它画得和作者标的一模一样,等于把 78% 的错误结果伪装成确定事实。 */
.cb .cb-lang[data-guess="1"] {
border-style: dashed;
font-style: italic;
opacity: .8;
}
.cb .cb-actions {
display: flex;
gap: 6px;
}
.cb .cb-copy {
font: inherit;
font-size: 11px;
padding: 3px 9px;
cursor: pointer;
color: #656d76;
background: #fff;
border: 1px solid #d0d7de;
border-radius: 5px;
transition: color .12s, border-color .12s, opacity .12s;
opacity: 0;
}
.cb:hover .cb-copy,
.cb .cb-copy:focus-visible { opacity: 1; }
.cb .cb-copy:hover { color: #0969da; border-color: #0969da; }
.cb .cb-copy.done { color: #1a7f37; border-color: #1a7f37; }
.cb .cb-copy.err { color: #cf222e; border-color: #cf222e; }
/* 🔴 触屏兜底:没有 hover 的设备上按钮必须常驻,否则永远点不到。
注意这里必须是「默认隐藏 + 触屏覆盖回 1」的写法。
如果默认是 1、只在 @media(hover:none) 里再写 1,那条规则等于空操作 ——
因为 1 本来就是默认值,删掉也不会变,故障测不出来。 */
@media (hover: none) {
.cb .cb-copy { opacity: 1; }
}
/* ── 代码区:左行号槽 + 右可滚动 pre ── */
.cb .cb-body {
display: flex;
align-items: stretch;
}
/* 行号槽。
🔴 它在 <pre> **外面**,所以行号文字永远不会进 code.textContent ⇒
"复制不带行号"是结构保证的,不靠 JS 删、也不靠正则过滤。
🔴 除了用户要求,这里还有一层现实原因:hljs 输出的是 token span,
没有行结构,想在 span 上挂 ::before 计数是挂不住的(没有 span.line 这种元素)。
原型阶段就是这么写的,结果 CSS 规则齐全、画面上零行号。 */
.cb .cb-ln {
display: none;
flex: 0 0 auto;
padding: 12px 0 12px 10px;
text-align: right;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 12.5px;
line-height: 1.62;
color: #9aa0a6;
background: #f6f8fa;
border-right: 1px solid #eaecef;
user-select: none;
-webkit-user-select: none;
overflow: hidden;
}
.cb .cb-ln > span { display: block; }
/* 行号开关(body 上带 opt-ln 类时显示)*/
.opt-ln .cb .cb-ln { display: block; }
/* 🔴 这里必须把 padding 显式写成 12px,和 .cb-ln 的 padding-top 对齐。
每套 hljs 官方主题都自带 `pre code.hljs{padding:1em}`,会把代码整体
往下压 1em。行号槽没有这个 padding,于是第一行代码的 top 比行号低 15.5px,
屏幕上就是"第 1 行代码旁边写着 2",往下每行错一位。
实测(原型页):修前逐行偏差 15.5px,修后 0.00px。 */
.k-main .details .article .content .cb pre,
.cb pre {
margin: 0;
padding: 12px 14px;
overflow-x: auto;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 12.5px;
line-height: 1.62;
/* 🔴 原有主题写的是 word-break:break-all,会在任意字符断行,代码像乱码。
长行必须横向滚动,不能折断。 */
word-break: normal;
overflow-wrap: normal;
white-space: pre;
tab-size: 4;
border: 0;
border-radius: 0;
background: transparent;
}
/* 主题自带的 code padding 必须归零,否则与行号槽错位(见上) */
.cb .cb-body > pre > code.hljs {
padding: 0;
overflow-x: visible;
}
.cb .cb-body > pre { flex: 1 1 auto; min-width: 0; }
.cb pre code {
display: block;
margin: 0;
padding: 0;
background: transparent;
font-size: inherit;
line-height: inherit;
color: inherit;
font-family: inherit;
}
/* 深色配色必须让卡片自带深色底与深色顶条。
站点正文是浅色,若只在浅底上印深色配色,
token 与背景对比不足(现有 Prism 出问题的地方正在这里)。 */
.cb[data-kind="dark"] {
border-color: #30363d;
background: #0d1117;
}
.cb[data-kind="dark"] .cb-bar {
background: #21262d;
border-bottom-color: #30363d;
}
.cb[data-kind="dark"] .cb-lang {
background: #21262d;
border-color: #30363d;
color: #8b949e;
}
.cb[data-kind="dark"] .cb-copy {
background: #21262d;
border-color: #30363d;
color: #8b949e;
}
.cb[data-kind="dark"] .cb-copy:hover {
color: #58a6ff;
border-color: #58a6ff;
}
.cb[data-kind="dark"] .cb-ln {
background: #161b22;
border-right-color: #30363d;
color: #6e7681;
}
/* 窄屏:行号槽收窄,避免挤占代码宽度 */
@media (max-width: 560px) {
.cb .cb-ln { padding: 12px 0 12px 6px; font-size: 11px; }
.cb .cb-ln > span { padding-right: 4px; }
.cb pre { padding: 12px 10px; font-size: 12px; }
}
/* 打印:行号与复制按钮都不需要 */
@media print {
.cb .cb-ln, .cb .cb-actions { display: none !important; }
.cb { break-inside: avoid; }
}