<pre>标签通过在HTML解析阶段标记为预格式化文本,使空格、换行符和制表符作为独立文本节点保留在DOM中,而非被浏览器默认压缩;其保留效果依赖等宽字体及原始HTML解析,JS动态插入或CSS覆盖会使其失效。
pre 标签不是“让浏览器多留点空格”,而是直接切换渲染模式:告诉解析器“这段文本别做任何空白压缩,原样进渲染树”。
HTML 默认会把连续空白字符(空格、Tab、换行)全压缩成单个空格,这是解析阶段就干的事——跟 CSS 无关,也跟字体无关。哪怕你写 <div> </div>,DOM 里实际只存一个空格节点。
而 pre 的作用是在解析时标记该元素为“preformatted”类型,触发浏览器的特殊处理路径:所有空白字符都作为独立 Text 节点保留在 DOM 中,后续布局阶段照单全收。
空格和换行确实保留了,但如果用的是非等宽字体(比如 font-family: Arial, sans-serif),Tab 和空格宽度不一致,缩进就塌了。这不是 pre 失效,是排版失准。
立即学习“前端免费学习笔记(深入)”;
font-family: monospace 或具体等宽字体(如 Courier New、Consolas、ui-monospace)font-family: system-ui 这类兜底值,它在不同系统可能 fallback 到非等宽字体code,记得给 code 也设等宽字体,否则 pre > code 继承可能被覆盖常见于 JS 拼接字符串或模板引擎渲染后塞进 pre。问题不在 pre,而在内容本身被转义或截断:
innerHTML 插入时,若源字符串含 <、> 未转义,会被当 HTML 标签解析,破坏结构textContent 插入最安全,它强制走纯文本路径,连 & 都不会被二次解析{{ raw }} 要用 v-html,但得自己保证内容可信)<%= unescaped %> 类语法能,但语义和行为要分清:
<strong>、<a>、<img> 是合法的,浏览器会正常渲染这些元素——此时 pre 只管保留空白,不管子元素语义<p> 或 <h3> 会导致结构混乱:它们会脱离 pre 的预格式化上下文,各自按块级规则换行、加 margin,缩进逻辑就断了<div>hello</div>,或者用 <code> 包裹再配语法高亮库真正容易被忽略的点是:pre 的“保留”只发生在 HTML 解析阶段;一旦内容通过 JS 改写、框架重渲染、或被 CSS white-space 覆盖,它的保护就失效了。别假设它是个万能格式罩子——它只在原始 HTML 文本进入解析器那一刻起效。