Реалізація друку вебсторінок (Print CSS)
Сторінка виглядає гарно на екрані і жахливо при друці — типова ситуація. Навігація, рекламні банери, чат-віджети, sticky-хедери та фонові зображення перетворюють друк на сміття. Це вирішується окремим набором CSS-правил та мінімальним JavaScript.
Базова структура print media query
/* Основний файл стилів */
@media print {
/* Приховуємо все зайве */
header,
footer,
nav,
aside,
.sidebar,
.cookie-banner,
.chat-widget,
.share-buttons,
.advertisement,
.back-to-top,
[data-noprint],
.no-print {
display: none !important;
}
/* Контент на всю ширину */
.container,
.wrapper,
main,
article {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
float: none !important;
}
/* Видаляємо тені та закруглення */
* {
box-shadow: none !important;
text-shadow: none !important;
border-radius: 0 !important;
}
}
Типографіка для друку
Екранні шрифти та шрифти для друку — різні речі. Для паперу переважні serif-шрифти:
@media print {
body {
font-family: Georgia, 'Times New Roman', serif;
font-size: 12pt;
line-height: 1.5;
color: #000;
background: #fff;
}
h1 { font-size: 24pt; margin-bottom: 12pt; }
h2 { font-size: 18pt; margin-bottom: 8pt; }
h3 { font-size: 14pt; margin-bottom: 6pt; }
p, li {
font-size: 12pt;
orphans: 3; /* мінімум 3 рядки перед розривом сторінки */
widows: 3; /* мінімум 3 рядки після розриву */
}
/* Посилання: показуємо URL */
a[href]:after {
content: ' (' attr(href) ')';
font-size: 10pt;
color: #555;
}
/* Не показуємо URL для якорів та javascript: */
a[href^='#']:after,
a[href^='javascript:']:after {
content: '';
}
/* Зображення */
img {
max-width: 100% !important;
page-break-inside: avoid;
}
}
Управління розривами сторінок
@media print {
/* Заголовки не відокремлюються від наступного абзацу */
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
break-after: avoid;
}
/* Елементи, які повинні бути на одній сторінці */
.no-break,
table,
figure,
blockquote {
page-break-inside: avoid;
break-inside: avoid;
}
/* Примусовий розрив перед розділом */
.page-break-before,
section.chapter {
page-break-before: always;
break-before: page;
}
/* Примусовий розрив після */
.page-break-after {
page-break-after: always;
break-after: page;
}
}
Параметри сторінки через @page
@page {
size: A4 portrait;
margin: 2cm 2.5cm 2cm 2.5cm;
}
@page :first {
margin-top: 3cm; /* більше місця на першій сторінці */
}
@page :left {
margin-left: 3cm; /* для двостороннього друку: переплет зліва */
}
@page :right {
margin-right: 3cm;
}
/* Колонтитули через @page (підтримується у Chrome/Edge) */
@page {
@top-right {
content: 'ООО «Компанія» — конфіденційно';
font-size: 9pt;
color: #999;
}
@bottom-center {
content: 'Стр. ' counter(page) ' з ' counter(pages);
font-size: 9pt;
}
}
Таблиці: повторюваний заголовок
@media print {
thead {
display: table-header-group; /* повторюємо шапку на кожній сторінці */
}
tfoot {
display: table-footer-group;
}
tr {
page-break-inside: avoid;
}
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #999;
padding: 4pt 6pt;
text-align: left;
}
th {
background: #eee !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
Фонові кольори та зображення
За замовчуванням браузери не друкують фони. Для брендованих документів:
@media print {
.brand-block {
background-color: #1e40af !important;
color: #fff !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact; /* стандартна властивість */
}
/* Логотип через img, не через background-image */
.logo-bg {
background-image: none !important;
}
.logo-bg::before {
content: '';
display: block;
background-image: url('/logo-print.png');
background-size: contain;
background-repeat: no-repeat;
width: 120px;
height: 40px;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
JavaScript: кнопка друку та підготовка
function printPage(selector?: string) {
if (selector) {
// Друкуємо тільки вибрану область
const content = document.querySelector(selector)
if (!content) return
const printWindow = window.open('', '_blank')
if (!printWindow) return
printWindow.document.write(`
<!DOCTYPE html>
<html>
<head>
<title>${document.title}</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body class="print-only">
${content.innerHTML}
</body>
</html>
`)
printWindow.document.close()
printWindow.focus()
printWindow.onload = () => {
printWindow.print()
printWindow.close()
}
return
}
window.print()
}
// Кнопка друку тільки в браузері, не для скринридерів
document.querySelectorAll('[data-print-btn]').forEach(btn => {
const selector = btn.getAttribute('data-print-target')
btn.addEventListener('click', () => printPage(selector ?? undefined))
})
Evento beforeprint та afterprint
window.addEventListener('beforeprint', () => {
// Розгортаємо всі аккордеони — схований контент не друкується
document.querySelectorAll('.accordion-content[hidden]').forEach(el => {
el.removeAttribute('hidden')
el.setAttribute('data-was-hidden', 'true')
})
// Форсуємо завантаження lazy-зображень
document.querySelectorAll('img[loading="lazy"]').forEach(img => {
const image = img as HTMLImageElement
if (image.dataset.src) {
image.src = image.dataset.src
}
})
})
window.addEventListener('afterprint', () => {
// Повертаємо стан
document.querySelectorAll('[data-was-hidden]').forEach(el => {
el.setAttribute('hidden', '')
el.removeAttribute('data-was-hidden')
})
})
Чеклист перед здачею
Обов'язково перевірити в Chrome → Ctrl+P: навігація прихована, URL посилань відображаються, таблиці не розриваються посередині рядка, зображення не виходять за поля, немає пустих перших сторінок через margin-top на body, шрифт читаємий (не менше 10pt).
Терміни
Базовий print.css для лендинга або блогу — 2–4 години. Для складної сторінки з таблицями, умовною видимістю блоків та брендованими кольорами — 1 день.







