使用 Tailwind CSS + 原生 CSS Print 实现完美的网页打印与 PDF 导出
在前端开发中,经常会遇到需要将网页(特别是简历、报告、发票等)导出为 PDF 的需求。比起引入庞大的第三方截图或 PDF 生成库,利用浏览器原生的 `window.print()` 结合 CSS Print 媒体查询,是性能最好、代码最优雅的方案。 但在实际操作中,原生打印常常会遇到**背景色丢失**、**内容被拦腰截断**、**浏览器自带页眉页脚干扰**以及**响应式排版变形**等四大痛点。 本篇笔记总结了如何利用 **Tailwind CSS + 原生 CSS `@media print`** 优雅地解决这些问题,实现 1:1 像素级完美的打印排版。
[!info] related notes
使用 Tailwind CSS + 原生 CSS Print 实现完美的网页打印与 PDF 导出
在前端开发中,经常会遇到需要将网页(特别是简历、报告、发票等)导出为 PDF 的需求。比起引入庞大的第三方截图或 PDF 生成库,利用浏览器原生的 window.print() 结合 CSS Print 媒体查询,是性能最好、代码最优雅的方案。
但在实际操作中,原生打印常常会遇到背景色丢失、内容被拦腰截断、浏览器自带页眉页脚干扰以及响应式排版变形等四大痛点。
本篇笔记总结了如何利用 Tailwind CSS + 原生 CSS @media print 优雅地解决这些问题,实现 1:1 像素级完美的打印排版。
💡 核心优化流程与原理
1. 掌控物理纸张:@page 规则
千万不要试图用外层容器的 margin 或绝对定位来模拟打印边距,这极易导致内容错位和滚动条失灵。正确的做法是将边距管理权还给打印机本身:
@media print {
@page {
/* 定义纸张尺寸和方向 */
size: A4 portrait;
/* 定义黄金打印留白:上下 8mm,左右 15mm */
margin: 8mm 15mm;
}
}
2. 色彩保卫战:强制渲染背景色
为了省墨,浏览器默认会清除网页的所有背景色。即使使用 Tailwind 的 print:bg-gray-100 也可能会失效。必须在全局样式中强制开启色彩调整:
@media print {
html, body {
/* 强制浏览器打印背景颜色和图形 */
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
/* 建议同时重置 body 的底色为纯白 */
background: white !important;
color: black !important;
}
}
💡 提示:对于极为顽固的背景条(例如简历中的小标题背景),建议在 CSS 中显式写入 background-color: #xxx !important; 暴力注入。
3. 丝滑的分页控制:防截断魔法
打印多页内容时,最尴尬的就是一个完整的段落或列表被硬生生切成两半,一半在上一页,一半在下一页。
我们可以使用 break-inside: avoid 来保护最小颗粒度的元素:
@media print {
/* 保证段落、列表项或自定义的容器不被从中间截断 */
p, li, .keep-together {
page-break-inside: avoid;
break-inside: avoid;
}
/* 保证标题不会变成页面底部的孤儿(即标题在上一页,正文在下一页) */
h2, h3 {
page-break-after: avoid;
break-after: avoid;
}
}
4. 元素断舍离:隐藏无关 UI
网页上的导航栏、返回按钮、甚至是“打印”按钮本身,都不应该出现在最终的 PDF 中。
@media print {
/* 隐藏所有非打印区域 */
header, footer, nav, aside, .print-hidden {
display: none !important;
}
/* 去除超链接的下划线和默认蓝色,保持纸质质感 */
a {
text-decoration: none !important;
color: black !important;
}
}
5. 排版降维打击:放弃响应式,拥抱绝对单位
在屏幕上,我们习惯用 text-sm、p-4、sm:flex-row。但在打印尺寸(A4)固定的情况下,响应式类名极易引发排版灾难。
最佳实践:
- 字号锁定:针对高密度信息的简历,放弃
text-sm,直接使用具体像素值如text-[12.5px]。 - 行高锁定:使用
leading-[1.6]或类似比例,确保多行文本紧凑。 - 间距锁定:使用微小的固定间距(如
gap-1.5,mb-2)替代大间距,提升空间利用率。
🚀 终极万能模板 (Global CSS)
将以下代码放入全局样式(如 Astro 的 <style is:global> 或 Next.js 的 globals.css)中,即可为页面赋予完美的打印能力:
CSS
@media print {
/* 1. 物理尺寸与边距 */
@page {
size: A4 portrait;
margin: 8mm 15mm;
}
/* 2. 基础重置与色彩保留 */
html, body {
background: white !important;
color: black !important;
margin: 0 !important;
padding: 0 !important;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
/* 3. 隐藏不需要打印的网页元素 */
.no-print, header, footer, nav {
display: none !important;
}
/* 4. 解除页面主容器的宽度限制,让其充满纸张 */
#resume-wrapper {
width: 100% !important;
max-width: none !important;
margin: 0 !important;
padding: 0 !important;
box-shadow: none !important;
}
/* 5. 智能分页防截断 */
p, li, .keep-together {
page-break-inside: avoid;
break-inside: avoid;
}
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
break-after: avoid;
}
/* 6. 链接静默化 */
a {
text-decoration: none !important;
color: inherit !important;
}
}
⚠️ 最终用户操作指南(至关重要)
即使代码写得再完美,如果用户在浏览器的打印弹窗中设置错误,依然会翻车。请确保在调用 window.print() 时,提示用户完成以下设置(以 Chrome/Edge 为例):
- 展开 更多设置 (More settings)。
- 🚫 取消勾选 “页眉和页脚” (Headers and footers) —— 这是去掉顶部丑陋网址和底部页码的唯一方法!
- ✅ 勾选 “背景图形” (Background graphics) —— 确保色块和进度条等元素正常显示。