最快且正确的方式是使用 ,它表示不可断行、不被合并的空格;但需注意分号不能省略,且在动态内容中优先用 white-space: pre-wrap 配合 textcontent 保证安全与可维护性。

直接写 最快,但必须写对格式
浏览器默认把一串空格、换行、制表符全压缩成一个空格,这是 HTML 规范行为,不是 bug。想让“hello ——它代表一个不可断行、不被合并的空格。
常见错误现象:
- 写成
 (漏掉分号)→ 浏览器当普通文本,原样输出 - 在 Vue/React 模板里直接写
,但父元素用了v-html或dangerouslySetInnerHTML且没转义 → 可能被二次解析或触发 XSS - 用
做中英文混排对齐 → 中文下宽度常比英文窄,视觉错位
实操建议:
- 静态文本中,数量控制在 1–4 个以内;超过建议换方案
- 别嵌套写,比如不要写
,就老老实实写三遍 - 在模板字符串或 JS 动态拼接时,记得用
innerHTML赋值,textContent会把当纯文本,不解析
white-space: pre-wrap 是整段文本的首选方案
如果要保留的不是几个空格,而是一整块带缩进、换行、多空格的文本(比如代码片段、日志、JSON 字符串), 就太零碎了。white-space: pre-wrap 是更干净、可维护的方式:它告诉浏览器“原文怎么写的,就怎么渲染”,同时允许自动换行,避免溢出容器。
参数差异注意点:
-
pre:保留所有空白,但不换行 → 长文本直接撑破容器 -
pre-wrap:保留所有空白,且允许换行 → 大多数场景最安全 -
pre-line:只保留换行,空格仍被合并 → 不满足“连续空格”需求
性能影响很小,但别滥用:给整个 或长列表加这个样式,会导致文本无法折行,破坏响应式布局。
<pre class="brush:php;toolbar:false;"></pre> 标签不是“加空格工具”,是语义标记
<pre class="brush:php;toolbar:false;"></pre> 本质是 white-space: pre 的快捷写法,但它自带等宽字体和上下 margin,语义上表示「预格式化文本」。适合代码块、ASCII 图形、日志这类真正需要原样复刻的场景。
容易踩的坑:
-
<pre class="brush:php;toolbar:false;"></pre>默认用font-family: monospace→ 中文显示发虚、字号偏小,需手动覆盖:font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; - 内容里有
、<code>>等符号,没做 HTML 转义 → 直接被解析为标签,结构错乱 - 用
<pre class="brush:php;toolbar:false;"></pre>包裹 API 返回的动态字符串,但忘了过滤或转义 → XSS 风险
实操建议:
- 纯展示、内容可信(如自己写的示例代码),用
<pre class="brush:php;toolbar:false;"></pre>最省事 - 内容来自用户或外部接口,优先用
<div style="white-space: pre-wrap;"> + <code>textContent设置内容Vue/React 模板里别硬拼
,优先走 CSS 控制在框架模板中,直接写
看似简单,但可读性差、难维护,尤其空格数随逻辑变化时。更可持续的做法是:数据层保持原始字符串(含真实空格),视图层用 CSS 控制渲染方式。例如 Vue 中:
<p class="preserve-spaces">{{ rawText }}</p> <style scoped> .preserve-spaces { white-space: pre-wrap; } </style>React 同理,用
className绑定样式,而非在 JSX 里塞一堆。真正容易被忽略的是上下文:静态 HTML 里用
最稳;动态内容多、格式复杂时,white-space: pre-wrap+ 安全的内容注入才是长期可维护的选择。











