page-break-before: always 仅对正常文档流中的块级元素生效;若元素为绝对定位、浮动、内联显示或位于flex/grid容器中,则失效。

为什么直接加 page-break-before: always 有时不生效
它只对处于正常文档流中的块级元素起作用。如果目标元素本身是 position: absolute、float、display: inline,或者被包裹在 flex/grid 容器里,分页指令就会被忽略——浏览器压根不把它当“可分页的块”。
更常见的是:你给一个 <div class="section"> 加了 page-break-before: always,但它父容器用了 display: flex,结果整个 .section 被当成 flex item 处理,分页属性失效。
- 检查该元素是否在正常流中:右键 → “检查”,看 computed styles 里
display是否为block或table类型 - 若父容器是 flex/grid,把分页指令移到父容器上,或改用空
<div>插入作为锚点 - 避免对
<span>、<a>、<em>等内联元素设分页属性
@page 必须平级声明,且单位只能是 mm 或 in
@page 不是 @media print 的子集,它定义的是物理纸张本身。写在 @media print { @page { ... } } 里完全无效,现代浏览器会静默丢弃。
单位也极关键:px、rem、% 在 @page 中全部被忽略,只认 mm、cm、in、pt(1pt = 1/72in)。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
@page { size: A4; margin: 15mm; } - 首尾页差异化:
@page :first { margin-top: 25mm; },但注意:first仅对第一页生效,后续页不匹配 - 横向打印必须显式声明:
@page { size: landscape; },不能只靠 CSS 旋转容器
表格跨页断裂的三步兜底写法
单靠 page-break-inside: avoid 对 <table> 几乎没用——Chrome 和 Safari 的打印引擎对表格内部断页控制极弱,尤其是带 <thead> 的长表。
真正能稳住的组合是:
- 给
<table>加break-inside: avoid; page-break-inside: avoid;(双写,兼容旧版) - 给
<thead>加display: table-header-group;(否则跨页时表头消失) - 对每个
<tr>手动包一层<tbody>,再给<tbody>设break-inside: avoid;(比直接设在<tr>上可靠得多)
如果仍断裂,说明内容总高度已超单页容量,这时得接受分页,而非强行避免。
调试时别信“看起来像”,要查真实打印渲染树
你在屏幕上看的样式和打印预览里应用的样式,可能是两套完全不同的计算结果。比如某个 .no-print 类在屏幕样式里被覆盖了,但在 @media print 里却生效了——反之亦然。
打开打印预览(Ctrl+P / Cmd+P),右键 → “检查”,然后选中任意元素,在 Styles 面板里确认是否命中了 @media print 下的规则。重点看:
- 该规则是否出现在“Matched CSS Rules”里
- 有没有被
!important覆盖或被更高优先级选择器压制 - 是否用了 CSS-in-JS 工具(如 Emotion),导致
@media print规则没注入到<head>
最常被忽略的一点:PDF 导出工具(如 wkhtmltopdf)对 break-* 支持比浏览器原生打印差一大截,测试务必用 Chrome/Firefox 原生打印预览,而不是导出 PDF 后再看。



















