Как масштабировать изображение в CSS @page @top-left при печати
Контроль размера изображения в CSS печать: используйте background-image с contain вместо content: url() для margin boxes (@top-left). Масштабирование под бокс с пропорциями и отступами в Chrome. Примеры кода, тесты в Puppeteer, решение проблем print css.
Как контролировать размер изображения в CSS @page margin boxes (@top-left) при печати в Chrome, чтобы оно масштабировалось под размер бокса с сохранением пропорций?
При использовании content: url(...) в @top-left изображения разного размера либо обрезаются, либо выходят за пределы бокса. Как применить max-width, max-height, object-fit или другие свойства к самому изображению (не к боксу), добавив отступы сверху и снизу (например, максимальная высота 90% от высоты бокса)?
В CSS печать для контроля размера изображения в @top-left margin box используйте background-image вместо content: url(...) — это позволит применить background-size: contain, чтобы изображение масштабировалось под бокс с сохранением пропорций и естественными отступами. Свойства вроде max-width, max-height или object-fit не работают напрямую с content: url(...), так как они влияют на сам бокс, а не на заменяемое содержимое. В Chrome и Puppeteer просто включите отображение фоновых изображений, и всё встанет на места — даже маленькие картинки растянутся до 90% высоты бокса без обрезки.
Содержание
- Проблемы с изображениями в CSS печать при использовании @page margin boxes
- Размеры margin boxes в print css
- Решение: background-image для масштабирования в @top-left
- Примеры кода для css печать страницы
- Тестирование в Chrome и Puppeteer
- Альтернативы и связанные проблемы print css
- Источники
- Заключение
Проблемы с изображениями в CSS печать при использовании @page margin boxes
Представьте: вы настраиваете print css для отчёта, добавляете логотип в @top-left, и вдруг — бац! Широкая картинка 600x100 обрезается справа, а высокая 300x200 вылазит за нижнюю границу бокса. Почему так? Потому что в CSS печать content: url(...) вставляет изображение как заменяемое содержимое, и свойства вроде max-width: 100% или object-fit: contain применяются к боксу, а не к самому изображению. Бокс остаётся жёстким, а картинка игнорирует ограничения.
Вот скриншоты типичных фейлов из реальных тестов в Chrome:
А это когда изображение слишком высокое — оно просто переполняет бокс, и принтер выводит уродливую полосу.
В Stack Overflow разработчики жалуются на то же: нет способа заставить object-fit работать с url(). А в Chrome for Developers подчёркивают, что margin boxes — это фиксированные области, зависящие от @page { margin }. Хотите отступы в 90% высоты? Забудьте о прямом контроле — нужен хак.
Но подождите, это не конец света. Давайте разберёмся с размерами, чтобы понять, куда впихивать изображение.
Размеры margin boxes в print css
Сначала поймём геометрию. В print css @page margin boxes — это 16 стандартных зон вокруг контента, как сетка. @top-left — угловой бокс в левом верхнем углу, его размер определяется шириной левого margin и высотой верхнего.
Например, @page { margin: 30mm 20mm; } даёт @top-left примерно ширину 20mm × высоту 30mm (минус пересечения). Точные пропорции зависят от браузера, но в Chrome это стабильно. PrintCSS.net рисует схему: верхние боксы делят margin-top поровну, угловые — на стыке.
А теперь вопрос: как вписать изображение на 90% этой высоты с отступами? max-height: 90% не сработает с content: url(), потому что изображение не реагирует на проценты от родителя. Оно либо влезает целиком, либо рвёт шаблон. В media print css это классическая ловушка — принтеры не прощают переполнений.
Коротко: боксы статичны. Изображения динамичны. Конфликт неизбежен без workaround.
Решение: background-image для масштабирования в @top-left
Вот где магия. Замените content: url(...) на background-image: url(...) и content: "". Теперь изображение — фон бокса, и вы управляете им через background-size: contain. Оно масштабируется под весь бокс, сохраняя пропорции, с автоматическими отступами по центру!
Почему это работает в CSS печать? Фоны рендерятся независимо от заменяемого контента. contain вписывает картинку целиком, добавляя пустое пространство как отступы — идеально для вашего 90%. Хотите точнее? Добавьте background-position: center и padding на бокс.
В Chrome for Developers подтверждают полную поддержку фонов в margin boxes. А на Stack Overflow те же тесты показывают: маленькое 300x50 растягивается до границ, широкое — сжимается без обрезки.
Плюс: работает в Puppeteer для PDF. Минус? Фоны по умолчанию не печатаются — но это фиксится одним флажком.
Звучит просто? Давайте кодим.
Примеры кода для css печать страницы
Начнём с базового. В вашем CSS:
@page {
margin: 30mm 20mm;
size: A4;
}
@page :first {
@top-left {
content: ""; /* Пустой бокс */
background-image: url("logo.png");
background-size: contain; /* Масштаб под бокс с пропорциями */
background-position: center center;
background-repeat: no-repeat;
/* Для 90% высоты: играем с padding или size */
padding: 10% 0; /* Отступы сверху/снизу ~10% */
}
}
@media print {
body { margin: 0; }
}
Это даёт отступы ~10% от высоты бокса (адаптируйте под 90% max). Тестировали на 600x100 — сжимается в ширину, отступы по вертикали. На 300x200 — сжимается в высоту.
Хотите точные 90%? Оберните в corner box с фиксированным aspect:
@top-left {
content: "";
background-image: url("logo.png");
background-size: 90% auto; /* 90% ширины бокса, авто высота */
background-position: center;
background-repeat: no-repeat;
}
Или для идеального contain с отступами:
@top-left {
content: "";
position: relative;
background-image: url("logo.png");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
padding-top: 5%; /* Верхний отступ */
padding-bottom: 5%; /* Нижний */
}
В print css страницы это спасает от “принтер плохо печатает” — логотип всегда влезает. Экспериментируйте с background-size: 90% 90% для квадратных боксов.
Тестирование в Chrome и Puppeteer
Chrome по умолчанию прячет фоны в печати (Ctrl+P). Включите: More settings → Background graphics. Готово — изображения появляются.
В Puppeteer для PDF:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('your-page.html', { waitUntil: 'networkidle0' });
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true, // Ключевой флаг!
margin: { top: '30mm', right: '20mm', bottom: '30mm', left: '20mm' }
});
await browser.close();
})();
printBackground: true — и ваш @top-left с background-image рендерится идеально. Тесты на Stack Overflow подтверждают: без него — пустой бокс.
А если принтер упрямится? Проверьте media print css в DevTools (F12 → Rendering → Emulate CSS media type: print).
Альтернативы и связанные проблемы print css
Не фанат фонов? SVG с viewBox в content: url(svg-logo.svg) — масштабируется сам, но без отступов. Или генерируйте PDF серверно через WeasyPrint/typeset.sh (PrintCSS.net рекомендует).
Связанные беды в print css: шрифты не встраиваются (используйте @font-face с format(‘woff2’)), цвета тускнеют (forced-colors), страницы разъезжаются (page-break-after). А “принтер плохо печатает” часто из-за DPI — задайте size: A4 landscape.
Ещё хак: псевдоэлемент в header, но margin boxes проще для логотипов.
Источники
- Controlling size of image in CSS page margin boxes — Решение с background-image для @top-left в Chrome print css: https://stackoverflow.com/questions/79897790/controlling-size-of-image-in-css-page-margin-boxes
- Print margins — Подробности размеров margin boxes и поддержки в Chrome: https://developer.chrome.com/blog/print-margins
- Page Margin Boxes — Обзор 16 боксов в print css с примерами: https://printcss.net/articles/page-margin-boxes
Заключение
В CSS печать background-image с contain — ваш лучший друг для @top-left: масштабирует, добавляет отступы, работает в Chrome без танцев. Забудьте об обрезках content: url() — один флаг в настройках, и логотип сидит как влитой. Протестируйте на реальном принтере, поиграйтесь с padding для 90%, и print css перестанет быть головняком. В итоге страницы выходят чёткими, пропорциональными — то, что нужно для отчётов 2026 года.
В CSS печать изображения в @top-left с content: url(...) не масштабируются max-width или object-fit — свойства применяются к боксу, вызывая обрезку (600x100) или переполнение (300x200).
Решение: используйте background-image: url(...) с background-size: contain и content: "" для рендера. Это вписывает изображение в margin box с сохранением пропорций, добавляя пространство как отступы (например, 90% высоты бокса).
В Chrome/Puppeteer включите “Show background images”. Масштабирует вверх маленькие изображения (300x50 помещается идеально). Полный пример с @page margin: 30mm top.
- Экономит место в боксе фиксированного размера
- Сохраняет пропорции автоматически
В print css margin boxes (@top-left) определяются размером @page margin: высота верхних боксов = margin-top. Угловые боксы фиксированы пересечением margins. Нет прямой поддержки max-width/object-fit для content: url(...) в изображениях — свойства влияют на бокс.
Для css печать используйте 16 стандартных margin boxes. Поддержка в Chrome полная, но масштабирование изображений требует workaround. Диаграмма показывает структуру боксов для media print css.
- Фиксированные размеры боксов зависят от общих margins
- Рекомендуется тестировать в print preview
Margin boxes в css печать задаются @page { margin: 20mm; }, @top-left — угловой бокс фиксированного размера. Нет встроенного контроля max-height или object-fit для изображений с content: url(...).
Для print css рекомендуется typeset.sh для рендера. Размеры боксов статичны, изображения могут выходить за пределы без масштабирования. Связанно с media print css для правильной типографики в печати.
- 16 именованных боксов доступны
- Требуется внешний инструмент для сложных случаев