应使用<pre><code>嵌套结构:pre为块级容器,code为语义内联元素;需转义HTML字符、设置等宽字体、处理缩进与换行,且确保传入纯文本空白符。

别从“学习格式化标签”开始,先明确你要解决什么问题:是想在网页里正确显示一段 Python 函数?还是把终端日志原样贴进页面?或是写技术文档时插入命令行示例?目标不同,pre、code、kbd 的用法和陷阱完全不同。
多行代码必须用 pre 套 code,顺序不能反
只用 code,缩进全丢;只用 pre,语义缺失、高亮不触发、屏幕阅读器读作普通段落。浏览器解析时,pre 是块级容器,code 是语义内联元素——嵌套关系是强制的,不是可选的。
- 正确写法:
<pre><code class="js">function foo() { return true; }</code></pre> - 错误写法:
<code><pre>...</pre></code>(语义倒置,Prism.js / highlight.js 通常跳过) - 错误写法:
<pre><div>...</div></pre>(HTML5 禁止在pre中直接嵌套div)
pre 里的 HTML 字符必须手动转义,pre 不负责这个
pre 只忠实地渲染你给它的字符,它不会自动把 < 变成 。如果你直接把 <code><div id="app"></div> 塞进 <pre><code></code></pre>,浏览器会在解析阶段就把它当真实标签执行,导致结构错乱甚至提前闭合。
- 服务端渲染:统一调用
htmlspecialchars()或等效函数 - 前端动态插入:用
textContent赋值,别用innerHTML - 模板中手写:把
<换成,<code>>换成>,&换成&
中文代码对不齐?不是 pre 失效,是字体没设对
默认字体下,一个汉字 ≈ 两个 ASCII 字符宽,console.log("你好") 和 console.log("hello") 必然错位。这不是 bug,是字体设计使然。
立即学习“前端免费学习笔记(深入)”;
- CSS 必须显式声明等宽字体栈:
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace; - 别只写
monospace——Windows 下它常映射到非等宽的“微软雅黑”,等于白设 - 注意
pre标签本身的缩进也会被渲染:如果模板里<pre>缩进了 4 格,首行就会多出 4 个空格;要么让标签顶格写,要么用注释消除:<!--<pre><code class="js">-->
长代码横向溢出?overflow-x: auto 不是万能解
加了 overflow-x: auto 却仍看不到滚动条,常见原因是没重置 code 的 display 行为。
- 必须加:
pre code { display: block; },否则code还是行内元素,横向滚动逻辑不生效 - 配合
white-space: pre-wrap可让超长行自动换行,避免必须横向滚动 -
tab-size: 2控制 Tab 显示宽度,比用空格缩进更可控
最常被忽略的点:所有这些样式和嵌套规则,都建立在“你传给 pre 的是纯文本字符”这个前提上。后端返回的 "line1\nline2"(带反斜杠的字符串),或模板引擎把换行符删了再塞进去,pre 也无能为力——它只渲染源码里真实存在的空白符,不修复、不还原、不猜测。



















