是行内语义标签,仅允许包裹文本及其他行内元素,禁止嵌套等块级元素;多行代码必须用结构,前者保留格式,后者声明语义,且原始代码需转义特殊字符、class名须严格匹配高亮库要求。

code 标签里不能塞 或块级元素
是行内语义标签,只允许包含文本和其他行内内容。一旦往里面塞 <pre class="brush:php;toolbar:false;">、<div>、<p>、</p> <ul> 这类块级元素,浏览器会直接“修复” DOM:把 <code> 提前闭合,块级内容被挤到外面,导致结构断裂、样式失效、JS 获取内容异常。 <p>常见错误写法:<code><code><pre class="brush:php;toolbar:false;">console.log(1)
结果不是你想要的代码块,而是解析成:<code>
console.log(1)
只能包裹纯文本或行内标签(如 <strong>、<em>、<span>)</span></em></strong>- 想展示多行、带缩进的代码?必须用
结构,而不是反过来
- HTML5 虽然放宽了部分嵌套限制,但
的内容模型没变——W3C 仍定义它为 <a href="https://www.php.cn/link/d7ccb841e1c86abdc1d1d6e6bacb6f17">phrasing content only</a>
pre 标签必须在外层,code 标签必须在内层
所有主流高亮库(Prism.js、highlight.js)、屏幕阅读器、搜索引擎和 HTML 规范,都只认
<code> 这一固定嵌套顺序。颠倒成 <code><pre class="brush:php;toolbar:false;"> 是非法嵌套,浏览器会自动修正 DOM,造成格式崩坏、高亮不触发、辅助技术读作“预格式化文本”而非“Python 代码”。
负责保留换行、空格、制表符;<code> 负责声明语义:“这是计算机源码”</code>
- 单独用
:格式对,但语义缺失 → 高亮库默认不扫描它,SEO 不识别为代码片段
- 单独用
:语义对,但它是行内元素 → 所有换行和多余空格被压缩成单个空格,Python 函数直接塌成 <code>def hello():print("Hi")
<pre class="brush:php;toolbar:false;">function foo() { return true; }
原始代码含 、& 必须先实体化
如果没转义,浏览器在 HTML 解析阶段就把
整体失效。
- 错误示例:
<code><div id="app"></div></code>
→ 浏览器尝试解析,导致被提前闭合 <li>正确做法:把 <,> 替换成 <code>>,& 替换成&- 推荐用工具处理:Node.js 用
he.escape(),PHP 用htmlspecialchars(),前端渲染前用DOMPurify.sanitize()配合SAFE_FOR_XML: true- 别依赖编辑器自动转义——很多 Markdown 渲染器或 CMS 在插入代码块时跳过这步
class 名必须匹配高亮库要求
即使
<pre class="brush:php;toolbar:false;"> 结构完全正确、字符也全转义了,如果 class 写错,Prism.js 或 highlight.js 依然不会生效。它们靠 class 属性识别语言类型和触发高亮逻辑。
- Prism.js 认
class="javascript" 或 <code>class="lang-js",不认class="js"或class="javascript" - highlight.js 认
class="hljs python"或class="python",旧版还支持class="python",但新版本已弃用 - 不要手写 class:用 Prism.js 就统一用
language-xxx前缀;用 highlight.js 就查官网当前文档确认格式 - 注意大小写:
language-HTML和language-html在多数库中效果不同
- 推荐用工具处理:Node.js 用











