print-css
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePrint CSS
打印样式表(Print CSS)
You are a print stylesheet specialist. You write styles that make web pages look intentional on paper -- not like someone hit Cmd+P on a web page.
@media print你是一位打印样式表专家。你编写的样式能让网页在纸上呈现出精心设计的效果——而不是像直接按下Cmd+P打印网页那样杂乱。
@media printWhen to Use This Skill
何时使用此技能
- User asks to "make this printable" or "add print styles"
- Building a page that will be printed (invitations, tickets, reports, invoices)
- Creating a "Save as PDF" version of a web page
- Fixing broken print layouts
- 用户要求“让页面可打印”或“添加打印样式”
- 构建需要打印的页面(邀请函、票据、报告、发票)
- 创建网页的“另存为PDF”版本
- 修复损坏的打印布局
Print Stylesheet Skeleton
打印样式表骨架
Every print stylesheet follows this structure, in order:
css
@media print {
/* 1. Page setup */
@page { size: letter; margin: 0.5in 0.6in; }
/* 2. Force color reproduction */
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
/* 3. Base typography */
body {
background: white !important;
color: #1a1a1a !important;
font-size: 10.5pt;
line-height: 1.6;
}
/* 4. Kill web-only elements */
nav, .no-print, footer, .cookie-banner { display: none !important; }
/* 5. Kill animations */
*, *::before, *::after {
animation: none !important;
transition: none !important;
}
/* 6. Flatten layouts */
/* ... framework-specific resets ... */
/* 7. Page break control */
h1, h2, h3 { page-break-after: avoid; break-after: avoid-page; }
tr, img, blockquote { page-break-inside: avoid; break-inside: avoid-page; }
p { orphans: 3; widows: 3; }
/* 8. Images */
img { max-width: 100%; max-height: 3in; }
/* 9. Links */
a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
a[href^="#"]::after { content: ""; }
/* 10. Tables */
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
}每个打印样式表都遵循以下结构顺序:
css
@media print {
/* 1. Page setup */
@page { size: letter; margin: 0.5in 0.6in; }
/* 2. Force color reproduction */
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
/* 3. Base typography */
body {
background: white !important;
color: #1a1a1a !important;
font-size: 10.5pt;
line-height: 1.6;
}
/* 4. Kill web-only elements */
nav, .no-print, footer, .cookie-banner { display: none !important; }
/* 5. Kill animations */
*, *::before, *::after {
animation: none !important;
transition: none !important;
}
/* 6. Flatten layouts */
/* ... framework-specific resets ... */
/* 7. Page break control */
h1, h2, h3 { page-break-after: avoid; break-after: avoid-page; }
tr, img, blockquote { page-break-inside: avoid; break-inside: avoid-page; }
p { orphans: 3; widows: 3; }
/* 8. Images */
img { max-width: 100%; max-height: 3in; }
/* 9. Links */
a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
a[href^="#"]::after { content: ""; }
/* 10. Tables */
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
}@page Rules
@page 规则
css
@page {
size: letter; /* or: A4, 210mm 297mm, landscape */
margin: 0.5in 0.6in; /* top/bottom left/right */
}
@page :first {
margin-top: 1in; /* extra space for cover page */
}Available sizes: (8.5x11in), (210x297mm), , , , or explicit dimensions.
letterA4A3A5legalGotchas:
- @page margin support is limited across browsers. Use padding on body/wrapper as fallback.
- DevTools print emulation does not show @page effects. Must check actual print preview (Cmd+P).
- Cannot set background-color at the page level reliably.
css
@page {
size: letter; /* or: A4, 210mm 297mm, landscape */
margin: 0.5in 0.6in; /* top/bottom left/right */
}
@page :first {
margin-top: 1in; /* extra space for cover page */
}可用尺寸: (8.5×11英寸)、(210×297毫米)、、、,或自定义尺寸。
letterA4A3A5legal注意事项:
- 不同浏览器对@page边距的支持有限。可在body或容器上使用padding作为备选方案。
- DevTools的打印模拟不会显示@page的效果,必须查看实际打印预览(Cmd+P)。
- 无法在页面级别可靠地设置background-color。
Page Break Control
分页控制
Use both legacy and modern properties for maximum browser support:
css
/* Prevent breaking inside an element */
.card, tr, figure {
page-break-inside: avoid;
break-inside: avoid-page;
}
/* Force a break before a section */
.chapter {
page-break-before: always;
break-before: page;
}
/* Prevent a break right after a heading */
h1, h2, h3 {
page-break-after: avoid;
break-after: avoid-page;
}同时使用旧版和新版属性以获得最佳浏览器兼容性:
css
/* Prevent breaking inside an element */
.card, tr, figure {
page-break-inside: avoid;
break-inside: avoid-page;
}
/* Force a break before a section */
.chapter {
page-break-before: always;
break-before: page;
}
/* Prevent a break right after a heading */
h1, h2, h3 {
page-break-after: avoid;
break-after: avoid-page;
}Orphans and Widows
孤行控制(Orphans and Widows)
Prevent stranded lines at page boundaries:
css
p {
orphans: 3; /* minimum lines at bottom of page */
widows: 3; /* minimum lines at top of next page */
}Gotchas:
- does not work reliably on flex or grid containers. Switch to
page-break-inside: avoidin print.display: block - Overusing can push content to the next page unpredictably.
break-inside: avoid - Test with actual content -- short paragraphs behave differently from long ones.
防止页面边界出现孤立的单行:
css
p {
orphans: 3; /* 页面底部最少保留的行数 */
widows: 3; /* 下一页顶部最少保留的行数 */
}注意事项:
- 在flex或grid容器上无法可靠工作。打印时需切换为
page-break-inside: avoid。display: block - 过度使用可能导致内容意外被推到下一页。
break-inside: avoid - 需使用实际内容测试——短段落和长段落的表现不同。
Visibility
可见性控制
Elements to always hide in print
打印时需隐藏的元素
css
@media print {
nav,
.sidebar,
.cookie-banner,
.social-share,
.comments,
.ads,
.chat-widget,
.search-bar,
.no-print {
display: none !important;
}
}css
@media print {
nav,
.sidebar,
.cookie-banner,
.social-share,
.comments,
.ads,
.chat-widget,
.search-bar,
.no-print {
display: none !important;
}
}Print-only elements
仅打印元素
css
.print-only {
display: none; /* hidden on screen */
}
@media print {
.print-only {
display: block; /* visible on paper */
}
}Use (not ) -- visibility preserves layout space and wastes paper.
display: none !importantvisibility: hiddencss
.print-only {
display: none; /* 屏幕上隐藏 */
}
@media print {
.print-only {
display: block; /* 打印时显示 */
}
}使用(而非)——visibility会保留布局空间,造成纸张浪费。
display: none !importantvisibility: hiddenColors and Backgrounds
色彩与背景
print-color-adjust
print-color-adjust
Controls whether the browser can optimize colors for print:
css
* {
-webkit-print-color-adjust: exact !important; /* Safari/older Chrome */
print-color-adjust: exact !important; /* standard */
}- -- preserves declared colors (even if ink-heavy)
exact - (default) -- browser may strip backgrounds, adjust colors
economy
控制浏览器是否可以优化打印颜色:
css
* {
-webkit-print-color-adjust: exact !important; /* Safari/旧版Chrome */
print-color-adjust: exact !important; /* 标准语法 */
}- ——保留声明的颜色(即使墨水消耗量大)
exact - (默认)——浏览器可能会去除背景、调整颜色
economy
Color remapping for print
打印颜色重映射
Remap web colors to print-friendly equivalents:
css
@media print {
body {
background: white !important;
color: #1a1a1a !important;
}
/* Vibrant accent becomes muted for paper */
.text-coral { color: #A03030 !important; }
/* Dark backgrounds become white with borders */
.dark-card {
background: white !important;
border: 1px solid #ccc !important;
}
}Rule of thumb: If it's readable on white paper at arm's length, it works.
将网页颜色重新映射为适合打印的等效颜色:
css
@media print {
body {
background: white !important;
color: #1a1a1a !important;
}
/* 鲜艳的强调色转为适合纸张的柔和色调 */
.text-coral { color: #A03030 !important; }
/* 深色背景转为白色并添加边框 */
.dark-card {
background: white !important;
border: 1px solid #ccc !important;
}
}经验法则: 在白纸上手臂长度距离能清晰阅读,即为有效。
Typography
排版
Use points, not pixels
使用磅值(points)而非像素
Points render consistently across browsers and printers:
css
@media print {
body {
font-size: 10.5pt;
line-height: 1.6;
}
h1 { font-size: 24pt; }
h2 { font-size: 18pt; }
h3 { font-size: 14pt; }
code { font-size: 9pt; }
}磅值在不同浏览器和打印机上的渲染效果一致:
css
@media print {
body {
font-size: 10.5pt;
line-height: 1.6;
}
h1 { font-size: 24pt; }
h2 { font-size: 18pt; }
h3 { font-size: 14pt; }
code { font-size: 9pt; }
}Font stack for print
打印字体栈
Serif fonts are more readable on paper:
css
@media print {
body { font-family: Georgia, 'Times New Roman', serif; }
code, pre { font-family: 'Courier New', monospace; }
}Gotchas:
- Custom web fonts may not load in print. Always have serif/sans-serif fallbacks.
- Remove light font weights (300, 200). Paper doesn't render thin strokes well.
- Remove text-shadow. It doesn't translate to print.
- Minimum legible body text: 9pt. Prefer 10-11pt.
衬线字体在纸张上更易阅读:
css
@media print {
body { font-family: Georgia, 'Times New Roman', serif; }
code, pre { font-family: 'Courier New', monospace; }
}注意事项:
- 自定义网页字体可能无法在打印中加载。务必提供衬线/无衬线备选字体。
- 移除轻量级字重(300、200)。纸张无法清晰呈现细线条。
- 移除文字阴影(text-shadow),它无法在打印中呈现。
- 最小可阅读正文字体:9pt。优先选择10-11pt。
Images
图片
css
@media print {
img {
max-width: 100%;
max-height: 3in; /* prevent full-page images */
}
/* Hide decorative images */
.hero-image,
.background-image,
.decorative {
display: none !important;
}
/* Remove gradient overlays that hide content */
[class*="bg-gradient"][class*="absolute"] {
display: none !important;
}
}Gotchas:
- Background images don't print by default. Use or move content to
print-color-adjust: exacttags.<img> - Responsive images with may not load correctly in print preview.
srcset - High-resolution images slow down PDF generation significantly.
css
@media print {
img {
max-width: 100%;
max-height: 3in; /* 防止图片占满整页 */
}
/* 隐藏装饰性图片 */
.hero-image,
.background-image,
.decorative {
display: none !important;
}
/* 移除遮挡内容的渐变覆盖层 */
[class*="bg-gradient"][class*="absolute"] {
display: none !important;
}
}注意事项:
- 背景图片默认不会打印。使用或将内容移至
print-color-adjust: exact标签。<img> - 使用的响应式图片在打印预览中可能无法正确加载。
srcset - 高分辨率图片会显著减慢PDF生成速度。
Links
链接
Show URLs on printed links
在打印的链接后显示URL
css
@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: #666;
}
/* Don't show URLs on anchor links */
a[href^="#"]::after { content: ""; }
/* Don't show URLs on links that already describe their destination */
a.no-print-url::after { content: ""; }
}Gotcha: shows the full URL, which can be very long. Consider truncating with and on the ::after pseudo-element, or use custom content for known links.
attr(href)max-widthoverflow: hiddencss
@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: #666;
}
/* 锚点链接不显示URL */
a[href^="#"]::after { content: ""; }
/* 已描述目标的链接不显示URL */
a.no-print-url::after { content: ""; }
}注意事项: 会显示完整URL,可能非常长。可以考虑在::after伪元素上使用和来截断,或为已知链接使用自定义内容。
attr(href)max-widthoverflow: hiddenTables
表格
css
@media print {
/* Repeat header on each page */
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
/* Prevent row splitting */
tr {
page-break-inside: avoid;
break-inside: avoid-page;
}
/* Ensure borders print */
table { border-collapse: collapse; width: 100%; }
th, td {
border: 1px solid #000;
padding: 4pt 6pt;
}
}css
@media print {
/* 每页重复表头 */
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
/* 防止行被拆分 */
tr {
page-break-inside: avoid;
break-inside: avoid-page;
}
/* 确保边框可打印 */
table { border-collapse: collapse; width: 100%; }
th, td {
border: 1px solid #000;
padding: 4pt 6pt;
}
}Framework Gotchas
框架注意事项
Next.js
Next.js
next/image with breaks in print:
fillcss
@media print {
/* next/image fill uses absolute positioning -- force to static */
[data-nimg="fill"],
img[style*="position: absolute"] {
position: static !important;
width: 100% !important;
height: auto !important;
}
/* Fix fill containers */
[style*="position: relative"] {
position: relative !important;
overflow: visible !important;
}
}Where to put print styles: Use in , not component-scoped styles. Print styles need global scope to override everything.
@media printglobals.cssDiscussion: vercel/next.js#23039
使用的next/image在打印中失效:
fillcss
@media print {
/* next/image的fill使用绝对定位——强制改为静态定位 */
[data-nimg="fill"],
img[style*="position: absolute"] {
position: static !important;
width: 100% !important;
height: auto !important;
}
/* 修复fill容器 */
[style*="position: relative"] {
position: relative !important;
overflow: visible !important;
}
}打印样式的放置位置: 在中使用,而非组件作用域样式。打印样式需要全局作用域才能覆盖所有样式。
globals.css@media print相关讨论: vercel/next.js#23039
React / CSS-in-JS
React / CSS-in-JS
- Print media queries must be included in component styles or a global stylesheet.
- Styled-components and Emotion support blocks normally.
@media print - Dynamic class names work fine -- print styles override by specificity.
- 打印媒体查询必须包含在组件样式或全局样式表中。
- Styled-components和Emotion正常支持块。
@media print - 动态类名可以正常工作——打印样式通过优先级覆盖原有样式。
Tailwind CSS
Tailwind CSS
css
@media print {
/* Kill viewport height constraints */
.min-h-screen, .min-h-svh, .h-screen { min-height: auto !important; height: auto !important; }
/* Dark mode on paper = unreadable */
.dark { background: white !important; color: #1a1a1a !important; }
/* Opacity renders poorly on paper */
[class*="opacity-"] { opacity: 1 !important; }
/* Fixed elements don't print */
.fixed { position: static !important; }
/* Overflow hidden clips content at page breaks */
.overflow-hidden { overflow: visible !important; }
}css
@media print {
/* 移除视口高度限制 */
.min-h-screen, .min-h-svh, .h-screen { min-height: auto !important; height: auto !important; }
/* 纸张上的暗色模式无法阅读 */
.dark { background: white !important; color: #1a1a1a !important; }
/* 透明度在纸张上渲染效果差 */
[class*="opacity-"] { opacity: 1 !important; }
/* 固定定位元素无法打印 */
.fixed { position: static !important; }
/* 溢出隐藏会在分页处裁剪内容 */
.overflow-hidden { overflow: visible !important; }
}Flexbox and Grid
Flexbox 和 Grid
Flex and grid containers do not handle page breaks correctly. Flatten them:
css
@media print {
.flex, .grid { display: block !important; }
/* Or selectively: keep horizontal flex but allow breaking */
.flex-col { display: block !important; }
}Exception: Short flex rows (nav items, button groups) can remain flex if they fit on one line and you use .
page-break-inside: avoidFlex和Grid容器无法正确处理分页。需将其扁平化:
css
@media print {
.flex, .grid { display: block !important; }
/* 或选择性处理:保留水平flex但允许分页 */
.flex-col { display: block !important; }
}例外情况: 短flex行(导航项、按钮组)如果能在一行显示,且使用,则可以保持flex布局。
page-break-inside: avoidTesting
测试
DevTools emulation (quick iteration)
DevTools模拟(快速迭代)
- Open DevTools (F12)
- Three-dot menu -> More tools -> Rendering
- "Emulate CSS media type" -> print
- Styles update in real-time
Limitations: Does not show page breaks, @page rules, or PDF headers/footers.
- 打开DevTools(F12)
- 三点菜单 -> 更多工具 -> 渲染
- “模拟CSS媒体类型” -> print
- 样式实时更新
局限性: 不显示分页、@page规则或PDF页眉/页脚。
Actual print preview (final check)
实际打印预览(最终检查)
- Cmd+P (Mac) / Ctrl+P (Windows)
- Check "Background graphics" to see colors/images
- Review page breaks, margins, and layout
- Cmd+P(Mac)/ Ctrl+P(Windows)
- 勾选“背景图形”以查看颜色/图片
- 检查分页、边距和布局
Checklist
检查清单
Before declaring print styles complete:
- Web-only elements (nav, ads, widgets) are hidden
- Page breaks don't split mid-card, mid-table-row, or mid-image
- No orphaned single lines at top/bottom of pages
- All text is legible (minimum 9pt, dark on white)
- Images don't overflow onto the next page
- Links show URLs (or are clearly styled as text)
- Table headers repeat on each page
- Backgrounds are either hidden or forced with print-color-adjust
- No animations or transitions remain
- Flexbox/grid layouts don't cause blank pages
- min-height: 100vh constraints are removed
- Fixed positioning is converted to static
- Tested in actual print preview, not just DevTools emulation
在完成打印样式前需确认:
- 仅网页元素(导航、广告、小部件)已隐藏
- 分页不会在卡片、表格行或图片中间拆分
- 页面顶部/底部没有孤立的单行
- 所有文本清晰可读(最小9pt,白底深色字)
- 图片不会溢出到下一页
- 链接显示URL(或清晰地设置为文本样式)
- 表格表头在每页重复显示
- 背景已隐藏或通过print-color-adjust强制显示
- 没有残留的动画或过渡效果
- Flexbox/Grid布局不会导致空白页
- 已移除min-height: 100vh限制
- 固定定位已转为静态定位
- 已在实际打印预览中测试,而非仅DevTools模拟
Agentic Workflow & Vibe Coding
智能工作流与氛围编码
- Iterative Styling: Do not expect perfect print layouts on the first try, as print rendering engines are finicky. Draft a V1 stylesheet, preview the result, isolate specific breaks or visibility issues, adjust exactly ONE CSS rule at a time, and re-test until the layout is solid.
- Vibe Coding: Commit your working CSS changes locally before tackling complex grid/flexbox flattening or cross-browser print quirks.
- 迭代式样式编写: 不要期望第一次就能得到完美的打印布局,因为打印渲染引擎非常挑剔。先编写V1版本的样式表,预览结果,定位特定的分页或可见性问题,每次只调整一个CSS规则,重新测试直到布局稳定。
- 氛围编码: 在处理复杂的grid/flexbox扁平化或跨浏览器打印 quirks之前,先在本地提交有效的CSS更改。
Utility Classes
工具类
Add these to your project for print control:
css
.no-print { } /* hidden in print via @media print */
.print-only { display: none; } /* hidden on screen, shown in print */
.print-break-before { } /* page break before this element */
.print-break-after { } /* page break after this element */
.no-print-url { } /* suppress URL display on this link */
@media print {
.no-print { display: none !important; }
.print-only { display: block !important; }
.print-break-before { page-break-before: always !important; break-before: page !important; }
.print-break-after { page-break-after: always !important; break-after: page !important; }
}将以下工具类添加到项目中以控制打印:
css
.no-print { } /* 通过@media print在打印中隐藏 */
.print-only { display: none; } /* 屏幕上隐藏,打印时显示 */
.print-break-before { } /* 在此元素前分页 */
.print-break-after { } /* 在此元素后分页 */
.no-print-url { } /* 隐藏此链接的URL显示 */
@media print {
.no-print { display: none !important; }
.print-only { display: block !important; }
.print-break-before { page-break-before: always !important; break-before: page !important; }
.print-break-after { page-break-after: always !important; break-after: page !important; }
}