pre标签缩进塌陷主因是制表符宽度不一致及中文字体非等宽,应统一用空格缩进、指定等宽中文字体栈、使用white-space:pre-wrap、textcontent安全注入、避免全局样式覆盖。

pre 标签缩进塌陷,根本不是 HTML 写错了
缩进看起来“少了一截”或完全错位,大概率不是你代码缩进少了空格,而是 pre 在浏览器里对 \t(制表符)的宽度解释不一致:它默认按 8 字符渲染,而 VS Code、WebStorm 等编辑器普遍设为 2 或 4。更麻烦的是,中文字体 fallback 时,monospace 可能落到非等宽字体上,导致中文字符和空格宽度不等,视觉上直接“塌”了。
实操建议:
- 统一用空格代替
\t:项目内约定缩进为 2 或 4 个,避免混用; - 强制指定等宽中文字体栈:
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, 'Microsoft YaHei Mono', monospace;; - 别依赖编辑器显示效果去判断
pre渲染结果——直接看 DevTools 中 computed 的font-family和font-size是否生效。
white-space: pre-wrap 是最实用的折中方案
pre 标签默认是 white-space: pre,它保留所有空白和换行,但禁止自动折行。长代码一行几百字符,横向滚动体验差,还容易撑破容器。这时候 white-space: pre-wrap 就成了实际项目中最常落地的选择。
它能做到:
- 保留原始缩进、空行、
\t和\n; - 允许长行在容器边界处自然折行(不像
pre那样硬扛); - 配合
overflow-x: auto,超长无空格字符串(如 base64、URL)也能被截断+滚动; - 注意:不要只写
word-break: break-word,它已废弃,改用overflow-wrap: break-word。
动态注入内容时,textContent 比 innerHTML 安全十倍
用 JS 往 <pre class="brush:php;toolbar:false;"></pre> 里塞后端返回的代码字符串,如果写成 preEl.innerHTML = str,\n 会被 HTML 解析器忽略,空格被压缩,甚至 XSS 风险——、<code>> 直接变成标签。
正确做法只有一条:
- 永远用
preEl.textContent = str,它把字符串当纯文本处理,\n和空格原样保留; - 如果内容本身含 HTML 标签且必须渲染(比如带
<code>的高亮片段),那就别用pre直接包,改用prism.js或highlight.js,它们内部已处理好 whitespace 和 token 边界; - 别在模板里写
<pre class="brush:php;toolbar:false;">{{ codeStr }}</pre>—— 大部分模板引擎默认转义,\n变成,得手动配置“不转义”或改用v-pre/{{{ }}}语法(依框架而定)。
reset.css 或 UI 框架会悄悄干掉 pre 的默认行为
很多项目引入了 Bootstrap、Normalize.css 或自定义 reset,它们常带一句 * { white-space: normal; } 或给 pre 单独设 white-space: normal。这时你的 <pre class="brush:php;toolbar:false;"></pre> 就退化成普通段落,缩进和换行全失效,连 DevTools 里都看不出异常——因为样式被覆盖了,不是 DOM 问题。
排查和修复很简单:
- 在 DevTools 的 Styles 面板里点开
pre元素,看white-space是否被划掉(表示被覆盖); - 加一条强制重置:
pre { white-space: pre-wrap !important; }(仅调试用),上线前去掉!important,改用更高优先级选择器; - 真正健壮的做法是:给所有代码块加 class,比如
<pre class="code-block"></pre>,然后写.code-block { white-space: pre-wrap; font-family: ...; },避开全局样式干扰。
缩进能不能对齐,从来不只是“多打几个空格”的事;它是字体、CSS 层叠、JS 注入方式、甚至编辑器设置共同作用的结果。最容易被忽略的,其实是那一行没写上的 font-family 和那一次误用的 innerHTML。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











