window.print() 打印混乱的根本原因是未将打印视为独立渲染通道;必须正确使用@media print(位置、作用域、优先级)、物理单位(pt/mm)、安全字体、表格分页控制及浏览器打印预览调试。

直接调用 window.print() 打印出的内容混乱,不是浏览器问题,是你没把打印当成独立渲染通道来对待。
为什么 @media print 必须写对位置和作用范围
很多人把 @media print 塞在 CSS 文件末尾,结果被前面的通用规则覆盖;或者分散在多个 <link> 样式表里,导致部分样式根本没生效。它必须作用于最终参与渲染的文档流,且优先级要压过屏幕样式。
- 所有打印专用样式必须包裹在
@media print { }内,不能只靠类名切换(比如.print-only) - 若用外部样式表,优先用
<link rel="stylesheet" media="print" href="print.css">,比内联@media print更可靠 - 避免在
@media print里写* { }这类宽泛选择器,容易误杀关键结构(如破坏<table> 的 <code>display行为) - 页面含
<iframe></iframe>?父页的@media print不会穿透生效,需提前提取内容或重置其样式 - 正文字体栈强制设为系统安全字体:
font-family: "Microsoft YaHei", SimSun, sans-serif; - 字号统一用
pt(如12pt)或mm(如4.2mm),禁用em、rem、% - 启用背景色和链接 URL:
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; }+a[href]:after { content: " (" attr(href) ")"; } -
<pre class="brush:php;toolbar:false;"></pre>和<code>块必须指定等宽字体:font-family: "Courier New", monospace; - 给
<table> 加 <code>page-break-inside: avoid;防止整表被拆;更细粒度可加在<tr> 上,但需配合 <code>display: table-row;(旧版 Chrome 要求) <thead> 跨页时不会自动重复,必须显式声明:<code>thead { display: table-header-group; }(<tfoot> 同理)<li>避免用 <code>flex或grid布局表格容器;一律转成display: block;+width: 100%;更稳- 横向打印长表?加
@page { size: landscape; },并确保容器max-width: none;,否则会被 A4 纵向宽度截断 - 打开浏览器打印预览(
Ctrl+P/Cmd+P),右键 → “检查” → 切到 Styles 面板,确认当前选中的元素是否应用了@media print下的规则 - 检查是否误用了
display: none或visibility: hidden—— 这些会让内容彻底不出现在打印输出中 - 如果用了 CSS-in-JS(如 Emotion、Styled Components),确认
@media print规则已注入到,且未被动态移除 - PDF 导出工具(如
wkhtmltopdf)对break-*支持更弱,测试时务必用原生浏览器打印预览,而非截图或 PDF 插件
字体、单位、颜色必须用物理维度锚定
用 rem、% 或 px 控制字号,打印预览时尺寸就可能差一大截;Web Font 在打印中加载失败,中文直接变方块;背景色默认不打印,链接只剩“点击这里”四个字。
表格和分页控制最容易翻车的三个点
表格跨页断裂、表头消失、列宽崩坏——这些问题几乎都源于没处理好三类 CSS 行为。浏览器打印引擎对 flex、grid 和隐式 display 值支持极弱。
调试必须用浏览器打印预览,别等真连打印机
90% 的问题靠预览就能暴露,但很多人跳过这步,直到打出一张全是空白页或半截表格。
最常被忽略的是:打印样式不是“微调”,而是重置整个渲染上下文;@page 和 @media print 必须平级声明,且 @page 无法插入页码或控制某段 HTML 出现在第几页——它只管纸张本身。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











