Печатная версия страницы: короткое руководство по CSS для печати
Как за час сделать страницу пригодной для печати: убрать меню, развернуть скрытый текст, управлять разрывами и не потерять URL ссылок. Разбираем @media print и свойства печати.

Пользователь жмёт Ctrl+P, а на бумагу лезет шапка сайта, боковое меню, футер с иконками соцсетей и половина текста уходит за край листа. Это не гипотетическая проблема: любая страница без стилей печати печатается так, как её видит браузер, только без интерактива. За час можно сделать нормальную печатную версию только средствами CSS — без отдельной страницы /print и без библиотек. В конце у вас будет таблица стилей, которая подключается автоматически при печати и в предпросмотре, а на бумаге останется только контент.
Что нужно до начала
Понадобится доступ к CSS проекта и браузер для проверки. Проверять удобнее всего через предпросмотр печати: в Chrome и Firefox это Ctrl+P (или Cmd+P на macOS), окно предпросмотра показывает результат печатных стилей в реальном времени. Отдельного принтера не нужно — печать в PDF работает так же.
Печатные стили описаны в спецификации CSS, актуальный модуль — CSS Paged Media Module Level 3. Базовые вещи (@media print, разрывы страниц) поддерживаются всеми браузерами много лет; более тонкие свойства вроде @page с полями поддержаны неравномерно — об этом ниже.
Шаг 1. Подключить стили печати
Есть два способа. Отдельный файл, который браузер грузит только при печати:
<link rel="stylesheet" href="print.css" media="print">
Или блок прямо в основном CSS через медиазапрос:
@media print {
/* правила только для печати */
}
Для короткого руководства удобнее второй вариант: всё в одном файле, ничего не забудете подключить. Как понять, что подключилось: добавьте временно внутрь body { background: pink; } и откройте предпросмотр печати — фон в предпросмотре станет розовым (браузеры по умолчанию не печатают фон, но в предпросмотре видно). Потом уберите.
Шаг 2. Спрятать лишнее
Навигация, футер, кнопки, баннеры, поиск — всё это на бумаге не нужно. Скрываем через display: none. Опирайтесь на реальные селекторы вашей вёрстки, не копируйте имена вслепую:
@media print {
header,
nav,
footer,
.sidebar,
.cookie-banner,
.share-buttons,
.comments {
display: none;
}
}
Как проверить: в предпросмотре печати на листе должен остаться только основной контент. Если что-то лишнее осталось — откройте DevTools, найдите элемент, возьмите его селектор и добавьте в список.
Правило простое: печатная версия — это не «страница без цвета», а страница без всего, что нельзя нажать на бумаге. Меню, к которому нельзя прикоснуться, — мусор на листе.
Шаг 3. Развернуть контент на всю ширину
После того как убрали боковое меню, основной блок часто остаётся зажатым в свою колонку. Растягиваем его и убираем ограничения по ширине:
@media print {
.content,
main {
width: 100%;
max-width: none;
margin: 0;
padding: 0;
float: none;
}
}
Проверка: текст занимает всю ширину листа с учётом полей, ничего не обрезано справа.
Шаг 4. Разобраться с цветом и фоном
По умолчанию браузеры не печатают фоновые цвета и картинки — экономят краску. Если у вас светлый текст на тёмном фоне, на бумаге он станет чёрным по белому и, скорее всего, нечитаемым. Задайте явно:
@media print {
body {
color: #000;
background: #fff;
}
a {
color: #000;
text-decoration: underline;
}
}
Если фон печатать всё же нужно (например, цветные ячейки таблицы несут смысл), есть свойство print-color-adjust: exact (в WebKit — с префиксом -webkit-print-color-adjust). Но пользователь всё равно может отключить печать фона в настройках диалога, так что не полагайтесь на цвет как на единственный носитель смысла.
Шаг 5. Показать адреса ссылок
На бумаге ссылка «читайте здесь» бесполезна — куда ведёт «здесь», непонятно. Выведите URL рядом с текстом ссылки через ::after и функцию attr():
@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.85em;
color: #555;
}
}
Здесь мы берём только внешние ссылки (начинающиеся с http), чтобы не засорять текст якорями вида #section и внутренними относительными путями. Проверка: в предпросмотре после текста ссылки в скобках появился её адрес.
Шаг 6. Управлять разрывами страниц
Самая частая жалоба к печати — заголовок остался внизу листа, а текст под ним уехал на следующий; таблица разорвана посередине строки. За это отвечают свойства разрыва. Современные имена — break-inside, break-before, break-after; старые аналоги — page-break-inside и родственные, их до сих пор понимают все браузеры и часто пишут оба варианта для совместимости.
@media print {
/* не разрывать элемент между страницами */
table,
figure,
blockquote,
pre {
break-inside: avoid;
page-break-inside: avoid;
}
/* заголовок не должен висеть внизу листа один */
h2, h3, h4 {
break-after: avoid;
page-break-after: avoid;
}
/* принудительно начать раздел с новой страницы */
.new-page {
break-before: page;
page-break-before: always;
}
}
Проверка: пролистайте предпросмотр по страницам. Заголовки должны сидеть на одном листе со своим текстом, таблицы — не рваться посреди строки. Стопроцентной гарантии тут нет: если элемент выше листа целиком, браузер всё равно его разорвёт.
Шаг 7. Поля страницы
Отступы от края листа задаются через правило @page:
@page {
margin: 2cm;
}
Здесь единицы измерения физические — cm, mm, in, а не пиксели. Учтите: пользователь может переопределить поля в диалоге печати, а поддержка более сложных правил @page (колонтитулы через @top-center и подобные) в браузерах ограничена — рассчитывать на них в вебе пока рано.
Если не получилось
- В предпросмотре видно скрытое меню. Селектор не совпал с реальной вёрсткой или перекрыт более специфичным правилом. Проверьте в DevTools точное имя класса и, если нужно, повысьте специфичность, но не через
!importantвслепую — сначала уточните селектор. - URL ссылок не появляются. Псевдоэлементы
::beforeи::afterне работают на замещаемых элементах и на тех, у когоdisplay: none. Убедитесь, что ссылка видима и это именно<a>с атрибутомhref. - Фон не печатается, хотя добавили
print-color-adjust. Пользователь отключил печать фона в диалоге, либо свойство применено не к тому элементу. Проверьте, что оно стоит на самом элементе с фоном, а не на его родителе. - Изменения не видны в предпросмотре. Стили закешированы. Обновите страницу с очисткой кеша (Ctrl+Shift+R) и снова откройте диалог печати.
- Разрывы страниц игнорируются.
break-inside: avoidработает как рекомендация, а не приказ. Если блок выше страницы, браузер разорвёт его в любом случае — разбейте контент на более мелкие блоки.
Что делать дальше
Проверьте результат в двух браузерах: рендеринг печати у Chrome (движок Blink) и Firefox (Gecko) отличается сильнее, чем экранный. Отдельно прогоните печать в PDF — это самый частый реальный сценарий, люди сохраняют страницу, а не несут к принтеру. Если на сайте есть страницы разных типов (статья, карточка товара, чек), сделайте для каждой свой набор скрытий: универсальный список селекторов быстро устареет. Инвалидация и версионирование самого CSS-файла — отдельная тема, здесь мы разобрали только правила печати.
Инфографика для маркетплейса: Три главных преимущества товара короткими фразами, выноски в безопасной зоне превью, точный размер площадки.
Спросить за 60 ₽Источники: MDN — CSS @media print и печатные стили, CSS Paged Media Module Level 3 (W3C)
Частые вопросы
А если мне нужны отдельные колонтитулы с номерами страниц?
Стоит ли делать отдельную страницу /print вместо стилей печати?
Почему фон не печатается, хотя на экране он есть?
Работают ли page-break-* или их уже надо менять на break-*?
Как быстро проверить печать без принтера?
Почему мои разрывы страниц иногда срабатывают, а иногда нет?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.