文本换行是排版中最容易被忽视、又最容易出问题的环节:中文该在哪里断行、英文单词要不要拆开、长 URL 会不会溢出页面、连续数字如何处理,这些细节决定了 PDF 文档是否整洁可读。浏览器里换行效果不对,滚动一下就过去了,但导出的 PDF 是要交付、打印和存档的,换行问题会永久留在文件里,直接拉低文档的专业度。dompdf.js 基于真实 CSS 排版引擎渲染文本,浏览器对 word-break、overflow-wrap、white-space 等属性的处理规则同样适用于 PDF 输出,这意味着开发者在网页上验证过的换行样式,导出后基本保持一致。本文系统梳理 dompdf.js 场景下的文本换行与断词策略:换行算法原理、中文与英文的断行差异、关键 CSS 属性的用法、长 URL 与连续字符的处理,以及空白字符的常见陷阱,配合真实代码示例,帮助开发者一次把换行问题解决到位,交付的 PDF 干净整洁。
文本换行由排版引擎按字符类别决定:拉丁文字在空格和连字符处断行,中文在任意汉字之间都可以断行,标点不能出现在行首。dompdf.js 复用浏览器内核的排版规则,网页上怎么换行,PDF 里就怎么换行,不会像早期坐标式库那样把整段文字塞进一行导致溢出,这是渲染真实 DOM 的天然优势,也是模板可以所见即所得的原因。
断行机会(line break opportunity)是理解换行的核心概念:每个字符位置是否允许断行,由语言与字符类别共同决定。英文单词内部默认不可断,中文汉字之间默认可断,URL 这类连续无空格文本默认不可断。CSS 的换行属性本质就是在调整这些断行机会的规则,理解了这一点,任何换行问题都能对症下药,而不是靠试错。
另外要区分断行与断词:断行是正常换行位置的确定,断词是在单词内部强行拆开。中文没有空格,每个汉字都是断行机会,所以中文文档几乎不会溢出;英文必须靠空格断行,遇到超长单词才需要考虑断词策略,两者的处理思路完全不同,不能混用一套方案,分开理解才能选对属性。
中文排版按字符断行,每个汉字之间都可以换行,因此中文文本几乎不会出现英文那种溢出问题。真正的难点在标点:句号、逗号、引号不能出现在行首,左引号不能出现在行尾,排版规范里有明确的禁则处理规则,dompdf.js 遵循这些规则,保证标点不会孤零零地挂在行首,版面干净规范,阅读节奏稳定。
连续的中文与英文数字混排时,断行机会以字符类别为准:中文与拉丁字符之间通常可以断行,数字串内部不可断。实践中建议把整段中文与英文混排的文案交给排版引擎自动处理,不要手工插入换行符或空格来对齐,手工处理在字号变化或字体更换后立刻失效,维护成本极高,也容易在数据更新后留下错误。
中文里还有一类特殊场景是竖排与标点宽度,日常横排文档较少涉及;更常见的是中文引号与英文引号的混用,同一段文字里引号样式不统一会显得不专业。模板层面统一标点风格,比在换行层面修补更有效,排版引擎的禁则处理也能因此更稳定,文档整体观感更严谨。
overflow-wrap: break-word 允许在单词内部断行,但只在单词本身超出容器时才生效,是处理长 URL 最常用的属性;word-break: break-all 则无条件在任意字符处断行,适合需要榨干每一像素宽度的窄列场景,但会牺牲英文的可读性,中文文本用 break-all 会让标点位置变得不自然,要谨慎使用。
keep-all 与默认行为相反:它禁止中文在任意位置断行,只在空格等明确位置断行,适合中英混排中对断行位置有严格要求的场景;anywhere 与 break-word 类似但断行机会更多,表格里的长 URL 用它配合 max-width 约束,能让窄列内容完整换行而不撑破表格,是表格场景的推荐组合。
这些属性在 dompdf.js 中的行为与浏览器一致,可以先在浏览器里用同样的 CSS 验证换行效果,确认后再生成 PDF,所见即所得;注意属性名与取值的大小写和拼写,一旦写错会被静默忽略,换行效果回到默认值,排查时先确认属性是否真的生效,再调整策略,效率更高。
<style>
.wrap-normal { word-break: normal; overflow-wrap: normal; }
.wrap-break-word { overflow-wrap: break-word; }
.wrap-break-all { word-break: break-all; }
.wrap-keep-all { word-break: keep-all; }
.url-cell { overflow-wrap: anywhere; }
table td { max-width: 120px; }
</style>
<p class="wrap-normal">Normal paragraph with a long URL https://example.com/very/long/path/that/might/overflow</p>
<p class="wrap-break-word">Long URL https://example.com/very/long/path/that/might/overflow</p>
<p class="wrap-break-all">超长单词 Pneumonoultramicroscopicsilicovolcanoconiosis 在窄列中的表现</p>
<p class="wrap-keep-all">keep-all 时中文按词断行,英文单词不拆开</p>
<table><tr><td class="url-cell">https://example.com/very/long/path/in/table</td></tr></table>
URL、订单号、序列号这类无空格长字符串是最常见的溢出源:默认规则下它们内部不可断行,容器宽度不够就直接溢出,在 PDF 里表现为文字画出边框或与相邻列重叠。处理思路有两个:允许内部断行(overflow-wrap),或者提前在模板层面对字符串做格式化,比如给长 URL 预留独立行或缩小字号,按场景选择。
允许断行的代价是断点位置不美观,URL 在斜杠处断开最自然,但 break-word 可能从任意位置断开;对需要精确控制的场景,可以先用 JavaScript 按斜杠和连字符插入零宽空格(​),把 URL 变成可断行序列,既保持了原文内容,又让断点可控,显示效果更专业,适合对外展示的正式文档。
表格是长字符串溢出重灾区:单元格宽度由内容撑开,一个长 URL 就能把整列表格撑变形。推荐组合是给 td 设置 max-width 或固定宽度,加上 overflow-wrap: anywhere,让长字符串在单元格内换行而不是撑宽表格,配合 table-layout: fixed 还能让列宽完全可控,多列表格不再被单个长串破坏,版式稳定。
HTML 里的连续空格默认合并为一个,换行符也被当作空格处理,这是网页排版的基本规则,PDF 渲染同样遵循。但数据填充场景经常出现意外:数据库里的文本带有多余换行或全角空格,渲染到 PDF 里可能产生奇怪的断行位置,或者本应保留的缩进被合并掉,输出与预期不符,排查起来很费时间。
需要保留空白时用 white-space 属性控制:pre 保留所有空格与换行,nowrap 禁止换行,pre-wrap 保留空白但允许自动换行。代码片段、地址、诗歌这类对空白敏感的文本,用 pre-wrap 最稳妥,既保留原文格式,又不会因为内容过长而溢出页面,是文档类 PDF 的高频需求,一处声明全局受益。
nbsp(不换行空格)与普通空格的行为完全不同:nbsp 两侧不可断行,适合固定年份单位、姓名这类不应拆开的组合;但 nbsp 也经常被误用,比如用它来对齐文本,一旦字体或字号变化,对齐立刻错乱。规范做法是缩进用 text-indent、对齐用表格或 flex,nbsp 只用于真正不可断的语义,避免留下后患。
Q: 中文段落右侧参差不齐?A: 中文默认按字符断行,参差多因中英混排或标点挤压造成,可先检查是否误用了 word-break: break-all,正常中文文档应使用默认断行规则,配合 text-align: justify 让两侧对齐,效果会明显改善,版面更方正。
Q: 长单词把容器撑破了?A: 检查是否设置了 overflow-wrap 与容器的 max-width;表格场景还需要 table-layout: fixed 配合,三步缺一不可,多数溢出问题都源于这三项没有同时到位,逐个补上即可解决,表格与正文的溢出问题都能根治。
最佳实践小结:正文中文用默认断行,长 URL 用 overflow-wrap: break-word,表格窄列用 anywhere 加固定列宽,空白敏感内容用 pre-wrap,手工换行与 nbsp 对齐一律避免。按这套规范写模板,PDF 的换行问题基本绝迹,交付文档始终整洁专业,团队协作也少很多返工,验收一次通过。
下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:
这是由 dompdf.js 渲染的示例 PDF 内容。