@media print 不生效主因是层叠顺序靠前或选择器权重不足,需确保其定义在通用样式之后、用更具体选择器;chrome 默认禁用背景图形,须手动开启;推荐用scss变量+混合宏控制打印开关,并避免display:none导致dom失效。

为什么直接写 @media print 有时不生效?
SCSS 本身不改变 CSS 媒体查询的行为,但开发者常忽略两个关键点:层叠顺序和选择器权重。浏览器打印预览时,会应用所有匹配的 @media print 规则,但如果页面已有高权重的通用样式(比如 !important 的 color 或内联 style),它们可能覆盖打印样式。
- 确保
@media print块写在主样式之后(SCSS 中靠后@import或靠后定义) - 避免依赖
!important解决问题;优先用更具体的选择器,例如从.header改为body.print-mode .header配合 JS 切换类 - Chrome 打印预览默认禁用背景图和颜色——需手动勾选「背景图形」才能看到
background-color和background-image效果
用 SCSS 变量统一控制打印样式开关
硬编码多处 display: none 容易漏改、难维护。推荐定义一个布尔变量 + 混合宏,让「是否启用该组件打印」变成配置项:
$print-enable-sidebar: false !default;
$print-enable-header-logo: true !default;
<p>@mixin print-only {
@media print {
@content;
}
}</p><p>.sidebar {
@include print-only {
display: #{$print-enable-sidebar ? 'block' : 'none'};
}
}</p><p>.header-logo {
@include print-only {
display: #{$print-enable-header-logo ? 'inline-block' : 'none'};
}
}</p>
这样后期只需改变量值,无需逐个找选择器。注意:变量必须带 !default,否则被其他文件覆盖时会报错。
避免 display: none 导致内容丢失的替代方案
直接对整个区域设 display: none 在打印时确实干净,但有个隐藏问题:如果该区域含表单控件或动态插入的内容(如 JS 渲染的二维码),display: none 会让它彻底不可见且无法通过 JS 操作 —— 即使你后续想用 window.print() 前临时 show,也因 DOM 流已断开而失效。
更稳妥的做法是视觉隐藏但保留布局占位与可访问性:
- 用
visibility: hidden+position: absolute移出可视区(仍可被屏幕阅读器读取) - 或加一层透明遮罩:
opacity: 0; pointer-events: none; - 对纯装饰性元素(图标、分隔线)才用
display: none
字体、尺寸与分页的常见坑
打印样式不是「缩小版网页」,物理纸张有明确边界和 DPI。以下三点最常被忽略:
- 不要用
rem或em控制字号,改用绝对单位:pt(12pt ≈ 16px 屏幕显示,但更符合打印习惯)或cm/mm - 避免
float布局,打印引擎对浮动支持极差;改用display: table-cell或 Flex(仅较新浏览器支持) - 分页控制要主动干预:
page-break-inside: avoid对卡片类容器很有效,但对table无效——得用page-break-after: always加在tr:last-child上
真正麻烦的是跨页表格和长图截断,这些没法靠纯 CSS 完美解决,得结合服务端生成 PDF 或前端库(如 jsPDF + html2canvas)兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











