语义正确的代码块应使用 嵌套结构: 保留空白与换行, 标明计算机代码语义;需为 添加 language-xx 类以支持高亮,样式应通过 span.token 精准控制关键词、字符串、注释等,避免 !important;行号与复制按钮须独立于 结构,用 或容器包裹并合理定位;响应式下优先 pre-wrap 折行,长代码启用横向滚动并添加视觉提示,移动端注意 -webkit-overflow-scrolling: touch 兼容性。

用 <pre class="brush:php;toolbar:false;"></pre> 和 <code> 搭配才是语义正确的起点
直接套 <div> 包代码块,高亮样式能加,但语义错位、可访问性差、复制体验也打折。浏览器和屏幕阅读器靠 <code><pre class="brush:php;toolbar:false;"></pre> 识别保留空白与换行,<code> 标明内容为计算机代码——两者嵌套是基础规范。
常见错误是只用 <pre class="brush:php;toolbar:false;"></pre> 不套 <code>,或反过来把 <code> 单独当容器用。正确写法:
<pre class="brush:php;toolbar:false;"><code class="js">const x = 1;</code>
-
<pre class="brush:php;toolbar:false;"></pre>控制布局(white-space: pre),<code>控制语义和默认字体(monospace) - 必须给
<code>加class(如language-python),否则语法高亮库无法识别语言 - 不要在
<pre class="brush:php;toolbar:false;"></pre>上设overflow-x: auto,而应在<code>或其父级加,否则滚动条可能遮挡行号(如果启用)
手动加 CSS 实现基础高亮,避开 JS 库的加载延迟
如果只是展示几段小代码,不值得引入 highlight.js 或 Prism。纯 CSS 就能做关键词、字符串、注释的区分着色,且无阻塞渲染问题。
关键不是写全所有语法,而是覆盖高频元素:关键字(function、return)、字符串(双引号/单引号包裹)、注释(// 和 /* */)。示例规则:
code.language-js span.token.keyword { color: #d73a49; }<br>code.language-js span.token.string { color: #032f62; }<br>code.language-js span.token.comment { color: #6a737d; font-style: italic; }
- 必须用
span包裹不同 token,靠 JS 或构建时预处理生成;手写 HTML 就得自己加<span class="token keyword">const</span> - 避免用
!important覆盖默认样式,优先提高选择器 specificity,比如用pre code.language-js span.token - 深色背景配浅色文字时,注意字符串颜色别太淡(如
#999在#1e1e1e上难读),实测#a6e22e更稳
行号和复制按钮需独立 DOM 结构,不能硬塞进 <code>
行号不是代码内容,复制按钮也不是,强行往 <code> 里插会破坏语义、干扰选中逻辑、导致复制带多余空格或按钮 HTML。
正确结构是:外层 <figure></figure> 或 <div class="code-block">,内部并列 <code><div class="code-header">(含复制按钮)、<code><pre class="brush:php;toolbar:false;"></pre>(含 <code>)、<div class="line-numbers">(绝对定位覆盖左侧)。<ul>
<li>行号用伪元素或 JS 动态生成,不要用 <code><ol></ol>,否则复制时会把数字一起带走
navigator.clipboard.writeText(),传参必须是 code.textContent,不是 innerHTML
position: absolute 叠加行号,记得给 <pre class="brush:php;toolbar:false;"></pre> 设 padding-left 预留空间,否则代码被遮挡响应式截断和横向滚动要分场景控制
小屏上长代码行不能简单缩放字体——可读性崩坏。该截断就截断,该滚动就滚动,但得让用户明确知道有隐藏内容。
核心原则:默认 white-space: pre-wrap 允许折行;对明确不允许折行的语言(如 JSON、命令行输出),才启用横向滚动。
- 启用滚动前,加视觉提示:在右下角固定显示
<span class="scroll-indicator">→</span>,CSS 用background: linear-gradient(90deg, transparent, #eee)模拟渐隐效果 - 移动端慎用
overflow-x: auto,iOS Safari 对<pre class="brush:php;toolbar:false;"></pre>的滚动支持不稳定,建议加-webkit-overflow-scrolling: touch - 别给
<code>设固定宽度,用max-width: 100%+overflow-x: auto,否则在窄屏下内容溢出容器
真正麻烦的是混排场景:一段代码里既有需要折行的配置项,又有不该折的哈希值。这时候得靠 class="no-wrap" 单独控制某几行,而不是一刀切。











