window.print()是浏览器原生打印预览入口,但存在预览不准、内容截断、样式错乱等问题;需由用户手势触发,避开跨域iframe限制,并配置electron/webview打印权限;打印样式须用@media print配合display: none、page-break-inside: avoid等规则优化分页与布局。

浏览器原生的 window.print() 就是打印预览的入口,它不依赖任何库,调用后自动触发系统打印对话框(含预览),但“预览效果不准”“页面内容被截断”“样式错乱”才是真问题。
为什么 window.print() 点了没反应或直接跳过预览?
常见于以下情况:
- 代码在非用户手势(如
setTimeout、fetch回调)中调用 —— 现代浏览器会静默拦截,必须由click、keydown等用户主动事件触发 - 页面处于 iframe 且跨域,父页无法调用子页的
window.print() - 某些 Electron 或 WebView 容器禁用了打印接口,需检查
webPreferences.print配置
验证方式:在控制台手动输入 window.print(),如果弹出对话框,说明环境支持;否则先排查触发时机。
打印样式错乱?加 @media print 不够,还得处理这些
@media print 是基础,但实际中光写它远远不够。重点要覆盖三类干扰元素:
- 隐藏非内容区域:
.header, .nav, .sidebar, .btn-print { display: none !important; } - 重置尺寸和换行:
body { font-size: 12pt; line-height: 1.4; },避免rem或vh导致缩放异常 - 图片/表格溢出:给
img, table加max-width: 100% !important;和page-break-inside: avoid !important;
注意:不要在 @media print 中用 visibility: hidden,它仍占布局空间;务必用 display: none。
如何让长表格/列表不被截断在两页中间?
浏览器默认按物理分页切割,表格行、卡片块常被硬生生劈开。关键控制点有三个:
- 对整行/整块容器加:
page-break-inside: avoid;(Chrome/Firefox 支持良好) - 对表格的
thead加:page-break-after: avoid;,防止表头被甩到下一页底部 - 对可能撑满一页的内容块,加
break-before: page;强制另起一页(慎用,易留大片空白)
实测发现:page-break- 系列在 Safari 中兼容性较差,可降级为 break- 前缀并同时声明,例如:page-break-inside: avoid; break-inside: avoid;。
想在打印前动态生成内容(比如加水印、页码)?别改 DOM,用 CSS 伪元素
修改真实 DOM 再打印,容易引发重排、异步延迟、还原困难。更稳妥的做法是用纯 CSS 注入:
@media print {
body::after {
content: "第 " counter(page) " 页";
position: fixed;
bottom: 20px;
right: 20px;
font-size: 10pt;
color: #999;
}
}
页码需要配合 @page 规则启用计数器:
@media print {
@page {
counter-increment: page;
}
body {
counter-reset: page 1;
}
}
注意:@page 不能嵌套选择器,所有样式必须写在 @page 块内或通过 ::before/::after 注入;页码在无内容的空白页上不会显示,这是浏览器行为,无法绕过。
真正难的不是调用 window.print(),而是让 CSS 在脱离屏幕渲染上下文后依然稳定输出 —— 这意味着放弃 Flex/Grid 的复杂布局、避开 transform 缩放、禁用 background-image(多数打印机默认关闭背景图打印)、提前测试 A4 尺寸下的实际分页位置。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











