css打印样式必须用@media print定义,浏览器仅识别其中规则;需显式设置字体、边距、隐藏非内容元素,避免依赖屏幕单位和背景色,分页控制需谨慎验证。

打印时 CSS 媒体查询必须用 @media print
浏览器只识别 @media print 中的样式规则用于打印预览和输出,@media screen 或未加媒体查询的样式默认被忽略(部分浏览器可能降级应用,但不可靠)。这意味着你写的 font-size: 14px 在页面上生效,但不写进 @media print 块里,打印时很可能回退到浏览器默认值(通常是 12pt 等比缩放)。
常见错误是直接在全局样式里改 body 字号或边距,结果打印出来还是挤成一团。正确做法是显式覆盖:
@media print {
body {
font-size: 12pt;
margin: 0.5in;
}
.navbar, .sidebar {
display: none;
}
}
- 不要依赖
!important强行覆盖——先确认规则是否进了@media print - 所有影响布局的关键样式(如
float、position、flex)在打印上下文中多数失效,优先用块级流式结构 - Chrome 和 Edge 的打印预览会实时响应
@media print修改,Firefox 需要刷新预览才能重载
display: none 是隐藏非内容元素最可靠的方式
导航栏、广告位、操作按钮这些纯交互元素,打印时必须移除。用 visibility: hidden 不行——它仍占文档流位置,可能导致空白页或错位;用 opacity: 0 更不行——内容照常输出,只是看不见。
真正起作用的是 display: none,它从渲染树中彻底剔除元素:
@media print {
.header-logo, .btn-print, #chat-widget {
display: none;
}
}
- 避免对父容器设
display: none后又试图单独显示某个子元素——子元素无法绕过父级的隐藏逻辑 - 动态生成的内容(如 React/Vue 组件)需确保其挂载节点本身也受
@media print控制,否则服务端渲染或 hydration 可能干扰 - 某些 CMS 或编辑器(如 TinyMCE)会内联
style属性,它们优先级高于外部@media print,得用!important覆盖(这是少数合理使用!important的场景)
字体、颜色、单位在打印中行为差异很大
打印机不渲染像素,也不忠实还原屏幕色域。16px 字体在 A4 上可能小得难以阅读;#333 在黑白打印机里就是浅灰,容易糊成一片;而 rem 依赖根字号,在打印上下文里可能因缩放失准。
- 字号推荐用
pt(如12pt)或cm/in,它们是物理尺寸单位,打印稳定 - 避免使用
rgba()或透明度——多数打印机只认rgb()或命名色,且强制转为灰度 - 超链接默认不显示下划线,且
color被忽略(打印始终为黑色),如需保留可加:a:link, a:visited { color: #000 !important; text-decoration: underline; } - 背景色(
background-color)默认不打印,即使设了-webkit-print-color-adjust: exact,也要用户在打印设置里勾选「背景图形」才生效,不能强求
分页控制要用 page-break 系列属性,但兼容性有限
想让表格不跨页断开、标题紧跟内容,得靠 page-break-inside: avoid 或 break-after: page。但注意:这些属性在不同浏览器中支持程度不一,且 Flex/Grid 容器内部基本无效。
-
page-break-inside: avoid对<table> 有效,但对 <code><div class="card"> 效果不稳定,建议改用语义化 <code><section></section>+break-inside: avoid(现代写法) -
break-before: always可能导致空页,尤其在内容刚好填满一页末尾时,建议配合orphans: 3; widows: 3控制段落断行 - 不要对
position: fixed元素设分页控制——它会被忽略,且可能重复出现在每页顶部 - 如果内容高度动态(比如用户自定义报表),纯 CSS 分页不可靠,需后端生成 PDF 或用 Puppeteer 截图
打印样式不是“写完就能用”,它依赖用户打印机驱动、系统 DPI 设置、浏览器版本,甚至纸张方向。最稳妥的验证方式:真机打印一张,而不是只信预览窗口。











