```
### Avoid orphan / widow
```css
p {
orphans: 3; /* 페이지 끝 최소 3 line */
widows: 3; /* 페이지 시작 최소 3 line */
}
```
→ 한 줄 만 페이지 끝 / 시작 안 됨.
### Header / footer (running headers)
```css
@page {
@top-center { content: "My Document"; }
@bottom-center { content: counter(page) " / " counter(pages); }
@top-right { content: string(chapter-title); }
}
h1.chapter {
string-set: chapter-title content();
}
```
→ 매 page header 자동.
⚠️ Browser 지원 부분적. Paged.js / Prince XML 사용 가능.
### Counter (page number)
```css
@page {
@bottom-right {
content: counter(page) " / " counter(pages);
font-size: 9pt;
}
}
```
### Image / table breaks
```css
img, table, figure {
page-break-inside: avoid;
break-inside: avoid;
}
/* Heading 가 단독 페이지 끝 X */
h1, h2, h3 {
break-after: avoid;
page-break-after: avoid;
}
```
### Receipts / invoices
```css
@page {
size: 80mm auto; /* thermal printer */
margin: 0;
}
@media print {
body {
font-family: monospace;
font-size: 10pt;
margin: 0;
padding: 5mm;
}
.item-row {
display: flex;
justify-content: space-between;
}
.total {
font-weight: bold;
border-top: 1px dashed black;
padding-top: 5mm;
}
}
```
### 흑백 (cost saving)
```css
@media print {
* {
color: black !important;
background: white !important;
box-shadow: none !important;
}
/* 단 logo / chart 등 색 유지 */
.logo, .chart {
color: revert !important;
background: revert !important;
}
}
```
### 색 강제 (cost OK)
```css
@media print {
.alert {
-webkit-print-color-adjust: exact;
print-color-adjust: exact; /* Modern */
background: red !important;
color: white !important;
}
}
```
### Print button
```html
```
```ts
window.print(); // 인쇄 dialog 열기
window.addEventListener('beforeprint', () => {
// Modify before print
});
window.addEventListener('afterprint', () => {
// 후처리
});
```
### Print preview (dev)
```
Chrome: File → Print (Cmd+P) → "Save as PDF"
또는 DevTools → 3-dot → More tools → Rendering → Emulate CSS media → print
```
→ 인쇄 dialog 열어서 preview.
### Paged.js (advanced)
```bash
yarn add pagedjs
```
```ts
import { Previewer } from 'pagedjs';
const previewer = new Previewer();
previewer.preview();
```
→ Browser 의 paged media 부족 = polyfill. CSS 표준 paged feature 더 많이 지원.
### PDF generation (server)
```ts
// Puppeteer
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/report?id=42');
await page.emulateMediaType('print');
const pdf = await page.pdf({
format: 'A4',
printBackground: true,
margin: { top: '2cm', bottom: '2cm', left: '2cm', right: '2cm' },
displayHeaderFooter: true,
headerTemplate: '
My Report
',
footerTemplate: '
/
',
});
await browser.close();
fs.writeFileSync('report.pdf', pdf);
```
→ HTML + CSS print → PDF.
### Receipt 인쇄 (browser → POS printer)
```
대부분 = browser 의 일반 print dialog → 사용자가 thermal printer 선택.
또는 ESC/POS 직접 (Bluetooth / serial / USB).
```
### CSS 실험 — bookmarks (PDF 안)
```css
h1 {
bookmark-level: 1;
bookmark-label: content();
}
h2 {
bookmark-level: 2;
}
```
→ PDF 의 navigation pane.
### Page size 표준
```
A4: 210mm × 297mm (most international)
US Letter: 8.5in × 11in
Receipt: 80mm wide
Legal: 8.5in × 14in
A5: 148mm × 210mm
```
```css
@page { size: letter; }
@page { size: 80mm 200mm; } /* custom */
```
### Orientation
```css
@page { size: landscape; }
/* Specific page */
@page wide {
size: A3 landscape;
}
.wide-table { page: wide; }
```
### Test
```ts
test('print stylesheet hides nav', () => {
document.body.classList.add('print-preview'); // 또는 @media print 검증
// Puppeteer test
await page.emulateMediaType('print');
const navVisible = await page.evaluate(() => {
return getComputedStyle(document.querySelector('nav')).display !== 'none';
});
expect(navVisible).toBe(false);
});
```
### React component
```tsx
function ReportPage() {
return (
<>
{/* Print content */}
Report
...
>
);
}
```
```css
@media print {
.no-print { display: none; }
}
```
## 🤔 의사결정 기준
| 작업 | 추천 |
|---|---|
| 일반 web print | @media print + @page |
| PDF download | Puppeteer / Playwright server |
| Receipt | 80mm @page + monospace |
| Book / chapter | Paged.js / Prince XML |
| 단순 export | window.print() + CSS |
| Server batch PDF | Puppeteer + queue |
## ❌ 안티패턴
- **Print stylesheet 무**: 사용자 인쇄 시 깨짐.
- **`!important` 없는 background hide**: 옛 browser 가 무시.
- **`page-break-inside: auto` 큰 image**: 잘림.
- **Widows / orphans 무시**: 작은 element 1줄 단독.
- **Color 인쇄 강제 (사용자 흑백 원함)**: print-color-adjust: economy.
- **JS 가 print 시 작동 가정**: 일부 browser 에서 X.
- **Print preview 없이 prod**: 디자인 깨짐 모름.
## 🤖 LLM 활용 힌트
- @media print 항상 + .no-print class.
- Server PDF = Puppeteer.
- 책 / 복잡 = Paged.js.
- Print preview 가 진짜 test.
## 🔗 관련 문서
- [[Frontend_CSS_Modern_Features]]
- [[Frontend_A11y_Testing]]
- [[Frontend_Image_Optimization]]