<p>默认white-space: normal,浏览器合并所有空白符(含换行),导致用户输入的多行文本被压成一行;正确做法应按语义选择:结构化文本用多个<p>、机器文本用<pre><code>、富文本过滤后用<div>+white-space: pre-line。

直接用 <p> 包裹用户输入的纯文本,大概率会丢换行、挤成一团,这不是 bug,是设计使然。
为什么 <p> 会吃掉换行符
<p> 默认使用 white-space: normal,浏览器会把源码里的多个空格、制表符、回车都合并成一个空格。所以用户粘贴的带换行的地址、日志或诗歌,一塞进 <p> 就全扁平化了。
- 常见错误现象:后台返回一段含
\n的字符串,前端直接<p>${text}</p>渲染,结果所有换行消失 - 真实场景:用户提交的「收货地址」、「错误日志片段」、「多行备注」
- 别指望加
style="white-space: pre-line"临时救急——它只对单个<p>生效,无法批量控制语义结构
<pre> 不是万能解药,但它是正确起点
<pre> 保留原始空白和换行,但它本身有默认 font-family: monospace 和无缩进,视觉上像代码块,不适合正文段落。
- 用法必须配 CSS:至少加
white-space: pre-wrap(保留换行+自动折行)+font-family: inherit - 不能嵌套
<strong>或<a>等行内标签——<pre>是“原样输出”,HTML 标签会被当作文本显示 - 如果内容含用户可控 HTML(如富文本编辑器输出),
<pre>会直接暴露标签字符,不安全
多行纯文本该用什么标签组合
没有单标签银弹。得按语义分情况选:
立即学习“前端免费学习笔记(深入)”;
- 地址、联系方式等结构化多行文本 → 拆成多个
<p>,每行一个,靠 CSS 控制margin间距 - 日志、堆栈、配置片段 →
<pre><code>...</code></pre>,既保格式又暗示「这是可复制的机器文本」 - 诗歌、歌词等需保留换行+强调个别词 → 用
<p>+white-space: pre-line,再在需要加粗的地方套<strong> - 用户评论含换行但可能混 HTML → 先用 DOMPurify 过滤,再用
<div>容器 +white-space: pre-line,禁用<p>避免语义污染
<br> 只该出现在明确需要「段内强制换行」的场合
<br> 是换行符的 HTML 显式表达,但它破坏段落语义——<p>第一行<br>第二行</p> 在逻辑上仍是「一个段落」,SEO 和屏幕阅读器都会这么理解。
- 适合场景:签名档(姓名+职位+公司三行)、化学式(H<sub>2</sub>O)、极简列表(无需语义化的短项)
- 绝对避免:用一堆
<br>模拟段落间距,这会让 CSS 维护崩溃,且无法响应式调整 - 替代方案:想控制「段与段之间距离」?统一用
<p>+margin-block,别动不动就<br>
最易被忽略的点:很多人以为「只要内容有换行,就得用 <pre>」,其实关键在语义归属——是「一段自然语言」还是「一段需字面呈现的数据」。选错标签,后期加无障碍支持或 SEO 优化时会反复踩坑。



















