浏览器对<pre>标签内空白字符原样保留,不折叠空格、制表符和换行;该行为由HTML规范强制规定,等价于white-space: pre,但非CSS驱动;DOM解析器(如DOMParser)保留原始空白,提取时应使用textContent而非innerText。

浏览器如何对待 <pre> 标签内的空白字符
浏览器在解析 HTML 时,对 <pre> 标签的处理是硬编码级别的特殊逻辑:它会跳过默认的“空白折叠”规则(即不把多个空格/制表符/换行合并为单个空格),而是原样保留所有空白符序列,并按原始位置渲染。这意味着你在源码里敲的 4 个空格、1 个制表符、2 个连续换行,都会被 DOM 节点树如实记录为文本节点内容。
但要注意:这种保留仅作用于 <pre> 元素的直接子文本节点;如果里面嵌套了 <span> 或 <code>,其内部仍受常规空白处理影响——除非你也给它们加 white-space: pre CSS。
<pre> 和 white-space CSS 属性的关系
<pre> 的行为本质上等价于设置了 white-space: pre,但它不是靠 CSS 驱动的,而是 HTML 规范强制要求的 UA 样式(user agent stylesheet)。你可以用其他标签模拟它:
-
<div style="white-space: pre">...也能保留换行和空格,但不会默认用等宽字体 -
white-space: pre-wrap允许长行自动折行,适合代码块+响应式布局 -
white-space: pre-line会合并空格但保留换行,适合日志类文本 - 一旦显式设置
white-space: normal,<pre>就失去预格式化能力
DOM 解析器(如 DOMParser)是否尊重 <pre>
是的,但仅限于文本内容本身。当你用 DOMParser.parseFromString(htmlStr, 'text/html') 解析含 <pre> 的字符串时:
立即学习“前端免费学习笔记(深入)”;
-
<pre> hello\n\tworld </pre>的textContent会是" hello\n\tworld "(前后空格、中间换行和制表符全在) - 但若你后续调用
element.innerText,它会忽略<pre>的语义,按渲染后样式返回(可能已折行、去空格) - 想安全提取原始内容,必须用
element.textContent,而非innerText或innerHTML
服务端解析库(如 BeautifulSoup、html5lib)怎么处理 <pre>
主流 HTML 解析库基本都遵循 HTML5 规范,对 <pre> 做特殊标记或跳过空白归一化。但关键差异在「提取文本」环节:
- BeautifulSoup 的
.get_text()默认会把<pre>内换行转为空格——除非你传preserve_whitespace=True(v4.9.0+) - html5lib 更严格,
<pre>子节点的data字段直接保留原始字符串,不做 trim - 如果你用正则粗暴匹配
<pre>.*?</pre>,会漏掉嵌套标签、实体编码(如)、以及跨行注释干扰
真正容易被忽略的是:预格式化文本的「语义完整性」依赖整个 DOM 上下文。比如 <pre><code class="js">...,单独提取 <pre> 内容会丢失语言信息,而只取 <code> 又可能丢掉外层缩进。得根据用途决定切哪一层。



















