html解析器在词法分析阶段即合并空白字符:将连续的u+0020、u+0009、u+000a、u+000d统一转为u+0020并压缩为单个空格;u+00a0等非空白unicode字符及、white-space仅影响渲染,不改变已压缩的dom文本结构。

HTML解析器在词法阶段就合并空白字符
浏览器不是等到渲染时才“压缩”空格,而是在构建DOM树的词法分析阶段,就把所有连续的空白字符(U+0020空格、U+0009制表符、U+000A换行、U+000D回车)统一转成U+0020,再把连续多个合并为一个。这意味着:即使你写的是<p>hello<span> </span>world</p>,DOM里看到的文本节点也只含一个空格。
为什么 能绕过合并规则
本质是Unicode字符U+00A0(non-breaking space),它不属于HTML规范定义的“空白字符”范畴,因此不会被词法分析器识别为可合并对象。它被当作普通文本字符直接进入DOM,既不参与折叠,也不触发换行断点。
-
宽度≈普通空格,但语义上“不可断行” -
()和()同理,是独立Unicode字符,不被折叠 - 而
()、()等实体也属于Unicode空格变体,同样逃逸合并逻辑
<pre class="brush:php;toolbar:false;"></pre>和white-space改的是渲染行为,不是DOM结构
<pre class="brush:php;toolbar:false;"></pre>标签或white-space: pre只是告诉渲染引擎:“别按默认规则压缩我拿到的文本”,但它不改变DOM中已存在的节点结构。例如:
<p style="white-space: pre"> hello world </p>
这段代码在DOM中仍是单个文本节点,内容为" hello world "(含首尾空格),只是CSS强制浏览器原样渲染——它没让HTML解析器“不合并”,而是让渲染器“不理会合并结果”。
Pandoc这类工具的空格提取逻辑更底层
像Pandoc的extractSpaces行为(见test/command/4845),是在HTML AST解析阶段主动重分配空格归属:把链接文本首尾的U+0020从Link子节点里剥离,作为独立Space节点插入到父级序列中。这说明:空格在AST层面有明确的“所有权”,不是简单丢弃或保留,而是根据语义边界重新归类。
这种处理无法用CSS模拟,必须在解析器层介入——这也是为什么前端JS操作textContent时拿不到原始空格位置,而Pandoc的native AST却能精确表达Str "x" → Space → Link → Space → Str "x"这样的结构。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











