Инструкция: CSS-оптимизация веб-страницы для печати

Подборка полезных CSS-техник от фронтенд-разработчика Мануэля Матузовича.

Мануэль Матузович
Мануэль Матузович

Бывший менеджер Microsoft Аарон Густафсон в октябре 2016 года написал в Twitter обращение к Indiegogo, где обратил внимание компании на то, что страницы с деталями заказа невозможно распечатать.

Когда я увидел этот твит, меня словно током прошибло, потому что я уже очень давно не только не оптимизировал страницу для печати, я даже ни секунды не думал об этом. Может быть дело в том, что я постоянно решаю вопросы, связанные с изменением размеров браузеров, и проверяю, чтобы страницы наших сайтов идеально работали в любом размере и любой форме, а может быть потому, что сам почти никогда не печатаю страницы. Как бы то ни было, я совсем забыл о стилях для печати, и это плохо.

Оптимизация интернет-страниц для печати очень важна, потому что в наших же интересах, чтобы сайты были максимально доступны пользователям, вне зависимости от того, в каком виде. Не нужно предполагать, какими являются пользователи и каким будет их поведение: люди все еще печатают страницы сайтов. Только подумайте о всех этих статьях или блогах, рецептах, контактной информации, страницах «как добраться» или сайтах с недвижимостью. Однажды кто-то где-то обязательно попробует распечатать одну из созданных вами страниц.

Я давно перестал пользоваться принтером дома, потому что он ломался каждые 10 минут. Но не все такие как я.

— Гейдон Пикеринг, Inclusive Design Patterns

Если вы обнаружите ту же самую проблему, что и у меня, то надеюсь, что эта статья быстро освежит ваши знания. Если вы еще не оптимизировали свои страницы с помощью CSS, следующие советы помогут вам начать это делать.

1. Встраиваем стили для печати

Лучший способ встроить стили для печати — описать директиву @media в своем CSS.

body { font-size: 18px;}@media print { /* print styles go here */ body { font-size: 28px; }}

Также вы можете встроить стили для печати в HTML, но для этого потребуется дополнительный запрос.

<link media="print" href="print.css" />

2. Тестирование

Не нужно печатать страницу каждый раз, когда вы вносите небольшое изменение. В зависимости от браузера можно экспортировать страницу как файл PDF, сделать предпросмотр страницы или даже вносить корректировки в самом браузере.

Чтобы откорректировать стили для печати в Firefox, откройте Панель разработчика (Shift + F2 или Разработка → Веб-разработка → Панель разработчика), введите media emulate print в строчке ввода внизу окна браузера и нажмите Enter. Активная вкладка будет вести себя, как если бы тип медиа был print до тех пор, пока вы не закроете или не обновите страницу.

Эмуляция стиля печати в Firefox
Эмуляция стиля печати в Firefox

В браузере Chrome откройте Инструменты разработчика (CMD + Opt + I (для macOS) или Ctrl + Shift + I (для Windows) или View → Developer → Developer Tools), отразите Console drawer (Esc), откройте панель Rendering, поставьте галочку в пункте Emulate CSS Media и выберите Print.

Эмуляция стиля печати в Chrome
Эмуляция стиля печати в Chrome

3. Абсолютные единицы

Абсолютные единицы не годятся для экранов, но хорошо работают для печати. В стилях для печати совершенно безопасно и даже рекомендуется использование таких абсолютных единиц как cm, mm, in, pt или pc.

section { margin-bottom: 2cm;}

4. Отдельные правила для страницы

Можно также определить параметры, действующие на этой странице: размеры, ориентация и поля, — с помощью директивы @page. Это очень удобно, если вы хотите, чтобы у всех страниц были определенные поля.

@media print { @page { margin: 1cm; }}

Директива @page — это часть модуля Paged Media, в которой есть много всего нужного, например, можно выбрать первую страницу печати или пустые страницы, позиционировать элементы в углах страницы и другое. Вы можете даже пользоваться ей для создания книг.

5. Управление разрывами страниц

Так как печатные страницы, в отличие от интернет-страниц, не могут быть бесконечными, в конце концов, контент прервется на одной странице и продолжится на следующей. В таком случае, есть пять свойств, которые нужно проконтролировать.

Разрыв страницы перед элементом

Чтобы элемент всегда был в начале страницы, можно принудительно разрывать страницу с помощью правила page-break-before.

section { page-break-before: always;}

Правило page-break-before на портале Mozilla Developer Network.

Разрыв страницы после элемента

С помощью правила page-break-after можно принудительно разорвать или, наоборот, избежать разрыва страницы после элемента.

h2 { page-break-after: always;}

Правило page-break-after на портале Mozilla Developer Network.

Разрыв страницы внутри элемента

Это правило поможет избежать разделения элемента на две страницы.

ul { page-break-inside: avoid;}​

Правило page-break-inside на портале Mozilla Developer Network.

Вдовы и сироты

Иногда не нужно принудительно разрывать страницу, но нужно проконтролировать, сколько строчек отражается на текущей или следующей странице. Например, если последняя строчка целого параграфа не помещается на текущей странице, то на следующей странице напечатаются две последние строчки из параграфа, даже несмотря на то, что не вошла только одна строчка. Так происходит потому, что свойство, ответственное за подобные ситуации, — widows — по умолчанию настроено на два. Это можно поменять.

p { widows: 4;}

Если ситуация противоположна, и из всего параграфа только первая строка помещается на странице, остальная часть параграфа будет напечатана на следующей странице. Свойство, ответственное за это поведение, — orphans, и его значение по умолчанию также равняется двум.

p { orphans: 3;}

Код выше показывает, что по крайней мере три строчки должны поместиться на текущей странице, иначе весь параграф будет перенесен на следующую страницу. На CodePen есть несколько примеров. А здесь — отладочная версия, чтобы было легче протестировать. Не все свойства и значения работают во всех браузерах одинаково, стили для печати надо проверять в каждом браузере.

6. Сброс стилей

Стоит сбросить некоторые стили для печати, например background-color, box-shadow или color.

Вот фрагмент стандартной заготовки стилей для печати для HTML5:

*,*:before,*:after,*:first-letter,p:first-line,div:first-line,blockquote:first-line,li:first-line { background: transparent !important; color: #000 !important; box-shadow: none !important; text-shadow: none !important;}

Стили для печати являются исключением из правил, в них можно использовать ключевое слово !important.

7. Удаление ненужного контента

Чтобы чернила не тратились зря, лучше удалить ненужный материал, например, presentational content, рекламу, навигацию и прочие с помощью свойства display: none.

Возможно, будет лучше вообще показать только основной контент, а все остальное спрятать.

body > *:not(main) { display: none;}

8. Отражение URL в ссылках

Печать ссылок совершенно бесполезна, если не известно, куда они ведут.

Можно легко сделать так, чтобы цель ссылки отражалась рядом с ее текстом.

a[href]:after { content: " (" attr(href) ")";}

Предыдущая команда отразит и относительные, и абсолютные ссылки на ваш сайт, якоря и многое другое. А вот эта команда может быть лучше:

a[href^="http"]:not([href*="mywebsite.com"]):after { content: " (" attr(href) ")";}

Выглядит безумно, я знаю. Эти строчки означают следующее: отразить значение атрибута hrefattribute рядом с каждой ссылкой, у которой есть атрибут href, который начинается с http, но в значении которого не стоит mywebsite.com.

9. Отражение расшифровок абревиатур

Аббревиатура должна заключаться в элементы <abbr>, а её расшифровка включается в атрибут title. Вполне логично выводить их на печать.

abbr[title]:after { content: " (" attr(title) ")";}

10. Принудительная печать фона

По умолчанию браузеры не печатают цвет фона и фоновые изображения, но иногда их можно пустить на печать принудительно. Нестандартизированное свойство print-color-adjust позволит переписать настройки по умолчанию в некоторых браузерах.

header { -webkit-print-color-adjust: exact; print-color-adjust: exact;}

11. Мультимедийный запрос

Если вы пишете свои мультимедийные запросы как в приведенном ниже примере, следует помнить, что правила CSS в этом запросе не будут применяться к стилям для печати.

@media screen and (min-width: 48em) { /* screen only */ }

Почему? Потому что правила CSS применяются только в случае, если параметр min-width равняется 48em, а тип медиа — screen. Если избавиться от ключевого слова screen, то мультимедийный запрос будет ограничиваться только параметром min-width.

@media (min-width: 48em) { /* all media types */ }

12. Печать карт

Текущие версии Firefox и Chrome могут печатать карты, но, например, Safari — не может. В таком случае можно воспользоваться статическими картами, которые предоставляются некоторыми сервисами.

.map { width: 400px; height: 300px; background-image: url('http://maps.googleapis.com/maps/api/staticmap?center=Wien+Floridsdorf&zoom=13 &scale=false&size=400x300&maptype=roadmap&format =png&visual_refresh=true'); -webkit-print-color-adjust: exact; print-color-adjust: exact;}

13. QR-коды

Некоторые советы вы найдете в статье журнала Smashing Magazine. Один из них заключается в том, что в страницах для печати лучше размещать QR-коды, чтобы пользователю не пришлось печатать URL полностью для перехода на актуальную страницу сайта.

Бонус: печать неоптимизированных страниц

Проводя исследование, я обнаружил инструмент, который поможет печатать неоптимизированные страницы. С помощью инструмента Printliminator можно удалять элементы просто кликнув на них. Можно посмотреть демо на Youtube и прочитать о проекте на Github.

Второй бонус: Gutenberg

Если вы ищете фреймворк, присмотритесь к инструменту Gutenberg. С ним оптимизация страниц для печати становится немного легче.

Третий бонус: Hartija

Есть еще один фреймворк, который называется Hartija. Его автор Владимир Каррер.

6 комментариев

страницы с деталями заказа невозможно распечататьЭто действительно актуальная проблема? Если сайт попытаться сохранить из браузера тоже так себе выйдет - но актуально ли это для кого-либо?
Люблю таких людей "а вдруг человек зайдет с IE 5?". А вдруг в кулере кому-то понадобится тёплая вода, а не горячая или холодная?

2

непонятно, зачем это тут?

я бы еще понял если бы рассказали как css принес over 9k бабла, но это не оно. В итоге, зачем?

1

Статья рассказывающая как вставить CSS media=print ? Серьезно? :)

А если какой-нибудь новичек наткнется и "удалит ненужный контент" не задумываясь о селекторах? Хоть бы пояснили что как работает на всякий случай.

нормальная статья

Фреймворк для того что бы сделать версию странички для печати. Ох.