Руководство по состоянию таблиц стилей печати в 2018 году
Опубликовано: 2022-03-10Сегодня я хотел бы вернуться к теме, которая уже освещалась в журнале Smashing Magazine в прошлом — к теме таблицы стилей для печати. В данном случае я говорю о печати страниц прямо из браузера. Это опыт, который может привести к разочарованию распечаткой огромных изображений (и даже рекламы). Однако лишь иногда добавляет немного удовольствия, когда из принтера выходит красиво оптимизированная страница с использованием минимума чернил и бумаги и гарантией того, что все легко читается.
В этой статье мы рассмотрим, как лучше всего создать этот второй опыт. Мы рассмотрим, как мы должны включать стили печати в наши веб-страницы, и посмотрим на спецификации, которые действительно вступают в свои права после печати. Мы узнаем о состоянии поддержки браузеров и о том, как лучше всего тестировать наши стили печати. Затем я дам вам несколько советов о том, что делать, когда таблицы стилей печати недостаточно для ваших нужд печати.
Ключевые места для поддержки печати
Если вы до сих пор не внедрили какие-либо стили печати на свой сайт, есть несколько ключевых мест, где надежная печать будет полезна вашим пользователям. Например, многие пользователи захотят распечатать страницу подтверждения транзакции после совершения покупки или бронирования, даже если вы отправите подробности по электронной почте.
Любая информация, которую ваш посетитель может захотеть использовать, находясь вдали от своего компьютера, также является хорошим кандидатом для таблицы стилей печати. Чаще всего я печатаю рецепты. Я мог бы загрузить их на свой iPad, но часто бывает удобнее просто распечатать рецепт, чтобы положить его на дверцу холодильника, пока я готовлю. Другими такими примерами могут быть направления или информация о путешествии. Когда вы путешествуете за границу и не всегда имеете доступ к данным, эти распечатки могут быть неоценимы.
Справочные материалы любого рода также часто печатаются. Для многих людей возможность делать заметки на бумажных копиях — лучший способ обучения. Опять же, это означает, что информация доступна в автономном формате. Нам легко задаться вопросом, почему люди хотят печатать веб-страницы, однако наша работа часто состоит в том, чтобы сделать контент доступным — в лучшем формате для наших посетителей. Если этот лучший формат печатается на бумаге, то кто мы такие, чтобы спорить?
Почему эта страница будет напечатана?
Хороший вопрос, который следует задать при принятии решения о включении или скрытии контента в таблице стилей печати: «Почему пользователь печатает эту страницу?» Что ж, может быть, есть рецепт, которому они хотели бы следовать, готовя на кухне, или взять с собой в магазин, чтобы купить ингредиенты. Или они хотели бы распечатать страницу подтверждения после покупки билета в качестве доказательства бронирования. Или, возможно, они хотели бы, чтобы квитанция или счет-фактура были распечатаны (или распечатаны в формате PDF), чтобы хранить их в учетных записях в бумажном или электронном виде.
Рассмотрение возможности использования печатного документа может помочь вам создать печатную версию вашего контента, наиболее полезную в контексте, в котором находится пользователь, обращаясь к этой распечатке.
Рабочий процесс
После того, как мы решили включить стили печати в наш CSS, нам нужно добавить их в наш рабочий процесс, чтобы гарантировать, что когда мы вносим изменения в макет, мы также включаем эти изменения в версию для печати.
Добавление стилей печати на страницу
Чтобы включить «таблицу стилей печати», мы сообщаем браузеру, для чего нужны эти правила CSS, когда документ печатается. Один из способов сделать это — связать дополнительную таблицу стилей с помощью элемента <link>
.
<link rel="stylesheet" media="print" href="print.css">
Этот метод отделяет ваши стили печати от всего остального, что вы можете считать более аккуратным, однако у этого есть недостатки.
Связанная таблица стилей создает дополнительный запрос к серверу. Кроме того, это красивое и аккуратное отделение стилей печати от других стилей может иметь и обратную сторону. Хотя вы можете позаботиться об обновлении отдельных стилей перед запуском, таблица стилей может пострадать из-за того, что она находится вне поля зрения и, следовательно, вне поля зрения — в конечном итоге она становится бесполезной, поскольку функции добавляются на сайт, но не отображаются в стилях печати.
Альтернативный метод включения стилей печати — использовать @media
так же, как вы включаете CSS для определенных точек останова в адаптивном дизайне. Этот метод объединяет весь CSS для функции. Стили для узких и широких точек останова и стили для печати. Наряду с запросами функций с @supports
это поощряет способ разработки, который гарантирует, что весь CSS для функции дизайна хранится и поддерживается вместе.
@media print { }
Перезапись CSS экрана или создание отдельных правил
Большую часть времени вы, вероятно, обнаружите, что CSS, который вы используете для отображения на экране, работает для печати с несколькими небольшими настройками. Поэтому вам нужно только написать CSS для печати, чтобы внести изменения в этот базовый CSS. Вы можете перезаписать размер шрифта или семейство, но оставить другие элементы в CSS в покое.
Если вы действительно хотите иметь полностью отдельные стили для печати и начать с чистого листа, вам нужно будет обернуть остальные стили вашего сайта в Media Query с ключевым словом screen.
@media screen { }
Кстати, если вы используете медиазапросы для адаптивного дизайна, возможно, вы написали их для экрана.
@media screen and (min-width: 500px) { }
Если вы хотите, чтобы эти стили использовались при печати, вам следует удалить ключевое слово screen
. На практике, однако, я часто обнаруживаю, что если я работаю «сначала с мобильных устройств», мобильный макет с одной колонкой является действительно хорошей отправной точкой для моего макета для печати. Имея медиа-запросы, которые вводят более сложные макеты только для экрана, мне приходится гораздо меньше перезаписывать стили для печати.
Добавьте свои стили печати в свои библиотеки шаблонов и руководства по стилю
Чтобы ваши стили печати воспринимались как неотъемлемая часть дизайна сайта, добавьте их в руководство по стилю или библиотеку шаблонов для сайта, если она у вас есть. Таким образом, всегда будет напоминание о том, что стили печати существуют, и что любой новый созданный шаблон должен иметь эквивалентную версию для печати. Таким образом, вы придаете стилю печати видимость как первоклассному гражданину вашей дизайн-системы.
Основы CSS для печати
Когда дело доходит до создания CSS для печати, вам, скорее всего, придется делать три вещи. Вы захотите скрыть, а не отображать контент, который не имеет значения при печати. Вы также можете добавить контент, чтобы сделать печатную версию более полезной. Вы также можете настроить шрифты или другие элементы страницы, чтобы оптимизировать их для печати. Давайте посмотрим на эти техники.
Скрытие содержимого
В CSS способ скрыть содержимое, а также предотвратить создание блоков, заключается в использовании свойства display со значением none
.
.box { display: none; }
Использование display: none
свернет элемент и все его дочерние элементы. Поэтому, если у вас есть галерея изображений, размеченная в виде списка, все, что вам нужно сделать, чтобы скрыть это при печати, — это установить display: none
в поле ul
.
Вещи, которые вы, возможно, захотите скрыть, это изображения, которые не нужны при печати, навигация, рекламные панели и области страницы, которые отображают ссылки на соответствующий контент и так далее. Обращение к тому, почему пользователь может распечатать страницу, может помочь вам решить, что удалить.
Вставка содержимого
Может быть некоторый контент, который имеет смысл отображать при печати страницы. Вы можете настроить некоторый контент для display: none
в таблице стилей экрана и показать его в таблице стилей печати. Кроме того, вы можете использовать CSS для отображения контента, который обычно не выводится на экран. Хорошим примером этого может быть URL-адрес ссылки в документе. В вашем экранном документе ссылка обычно показывает текст ссылки, по которой затем можно щелкнуть, чтобы перейти на эту новую страницу или внешний веб-сайт. Однако, когда печатные ссылки не могут быть пройдены, было бы полезно, если бы читатель мог видеть URL-адрес на случай, если он захочет перейти по ссылке позже.
Мы достигаем этого с помощью CSS-содержимого. Сгенерированный контент дает вам возможность вставлять контент в документ с помощью CSS. При печати это становится очень полезным.
В документ можно вставить простую текстовую строку. Следующий пример нацелен на элемент с классом wrapper
и вставляет перед ним строку «Пожалуйста, посетите www.mysite.com для получения последней версии этой информации».
.wrapper::after { content: "Please see www.mysite.com for the latest version of this information."; }
Однако вы можете вставлять элементы, которые уже существуют в документе, например, содержимое ссылки href
. Мы добавляем сгенерированный контент после каждого экземпляра a
с атрибутом href
, а вставляемый контент является значением атрибута href
, который будет ссылкой.
a[href]:after { content: " (" attr(href) ")"; }
Вы можете использовать более новый селектор CSS :not
, чтобы исключить внутренние ссылки, если хотите.
a[href^="http"]:not([href*="example.com"]):after { content: " (" attr(href) ")"; }
Есть еще несколько полезных советов, подобных этому, в статье «Я полностью забыл о таблицах стилей для печати», написанной Мануэлем Матузовичем.
Расширенный стиль печати
Если ваша печатная версия аккуратно умещается на одной странице, вы сможете относительно просто создать таблицу стилей для печати, используя приемы, описанные в последнем разделе. Однако если у вас есть что-то, что печатается на нескольких страницах (и особенно если оно содержит такие элементы, как таблицы или рисунки), вы можете обнаружить, что элементы переносятся на новые страницы неоптимальным образом. Вы также можете контролировать параметры самой страницы, например, изменять размер полей.
У CSS есть способ сделать это, однако, как мы увидим, поддержка браузерами неоднородна.
Постраничные медиа
Спецификация CSS Paged Media начинается со следующего описания его роли.
«Этот модуль CSS определяет, как страницы создаются и размещаются для хранения фрагментированного контента в постраничной презентации. Он добавляет функциональные возможности для управления полями страницы, размером и ориентацией страницы, а также верхними и нижними колонтитулами, а также расширяет сгенерированный контент, чтобы включить нумерацию страниц и запуск верхних и нижних колонтитулов».
Экран сплошной носитель ; если есть больше контента, мы прокручиваем, чтобы увидеть его. Нет понятия, что он разбит на отдельные страницы. Как только мы печатаем, мы выводим на страницу фиксированного размера, описанную в спецификации как постраничный носитель . Спецификация Paged Media не касается того, как контент фрагментируется между страницами, мы вернемся к этому позже. Вместо этого он смотрит на особенности самих страниц.
Нам нужен способ настроить таргетинг на отдельную страницу, и мы делаем это с помощью правила @page
. Он используется так же, как обычный селектор, в том смысле, что мы нацеливаем @page
а затем пишем CSS, который будет использоваться страницей. Простым примером может быть изменение поля на всех страницах, созданных при печати документа.
@page { margin: 20px; }
Вы можете настроить таргетинг на определенные страницы с помощью селекторов псевдоклассов распространения :left
и :right
. Первая страница может быть выбрана с помощью селектора псевдокласса :first
, а пустые страницы, вызванные разрывами страниц, могут быть выбраны с помощью :blank
. Например, чтобы установить верхнее поле только на первой странице:
@page :first { margin-top: 250pt; }
Чтобы установить большее поле справа на левой странице и слева на правой странице:
@page :left { margin-right: 200pt; } @page :right { margin-left: 200pt; }
Спецификация определяет возможность вставки содержимого в созданные поля, однако ни один браузер не поддерживает эту функцию. Я описываю это в своей статье о создании таблиц стилей для использования с пользовательскими агентами, специфичными для печати, Designing For Print With CSS.
Фрагментация CSS
В то время как модуль Paged Media имеет дело с самими блоками страниц, модуль CSS Fragmentation описывает, как содержимое разбивается между фрагментаторами . Фрагментатор (или фрагментный контейнер ) — это контейнер, который содержит часть фрагментированного потока. Это поток, который, достигнув точки, в которой он мог бы переполниться, разбивается на новый контейнер.
Контексты, в которых вы столкнетесь с фрагментацией, в настоящее время относятся к постраничным носителям, поэтому при печати, а также при использовании макета с несколькими столбцами, когда ваш контент разрывается между блоками столбцов. Спецификация фрагментации определяет различные правила для разбиения, свойства CSS, которые дают вам некоторый контроль над тем, как контент разбивается на новые фрагменты в этих контекстах. Он также определяет, как содержимое разбивается в спецификации CSS Regions, хотя сейчас это не является чем-то пригодным для использования в разных браузерах.
И, если говорить о браузерах, фрагментация в плане поддержки на данный момент — это какой-то беспорядок. Таблицы совместимости браузеров для каждого свойства на MDN кажутся точными в отношении поддержки, однако потребуется тщательное тестирование использования этих свойств.
Старые свойства из CSS2
В дополнение к свойствам break-*
из уровня фрагментации CSS 3 у нас есть свойства page-break-*
из CSS2. С точки зрения спецификации, они были заменены более новыми свойствами break-*
, поскольку они являются более общими и могут использоваться в различных контекстах, в которых происходит взлом. Между страницей и многоколоночным разрывом нет большой разницы. Однако с точки зрения поддержки браузерами более старые свойства поддерживаются браузерами лучше. Это означает, что вам, возможно, придется использовать их в настоящее время, чтобы контролировать взлом. Браузеры, которые реализуют более новые свойства, должны использовать псевдонимы для более старых, а не отбрасывать их.
В следующих примерах я покажу как новое свойство, так и старое, где оно существует.
break-before
и break-after
Эти свойства имеют дело с разрывами между блоками и принимают следующие значения, причем начальным значением является auto. Последние четыре значения не применяются к выгружаемым носителям, а относятся к многоцветным и областям.
-
auto
-
avoid
-
avoid-page
-
page
-
left
-
right
-
recto
-
verso
-
avoid-column
-
column
-
avoid-region
-
region
Более старые свойства page-break-before
и page-break-after
принимают меньший диапазон значений.
-
auto
-
always
-
avoid
-
left
-
right
-
inherit
Чтобы всегда вызывать разрыв страницы перед элементом h2
, вы должны использовать следующее:
h2 { break-before: page; }
Чтобы абзац не отделялся от заголовка, непосредственно предшествующего ему:
h2, h3 { break-after: avoid-page; }
Старое свойство page-break-*
всегда вызывало разрыв страницы перед h2
:
h2 { page-break-before: always; }
Чтобы абзац не отделялся от заголовка, непосредственно предшествующего ему:
h2, h3{ page-break-after: avoid; }
В MDN найдите информацию и примеры использования свойств:
- перерыв перед
- перерыв после
- разрыв страницы до
- разрыв страницы после
break-inside
Это свойство управляет разрывами внутри блоков и принимает следующие значения:
-
auto
-
avoid
-
avoid-page
-
avoid-column
-
avoid-region
Как и в случае с предыдущими двумя свойствами, существует свойство page-break-inside
с псевдонимом из CSS2, которое принимает значения:
-
auto
-
avoid
-
inherit
Например, возможно, у вас есть figure
или table
, и вы не хотите, чтобы половина ее оказалась на одной странице, а другая половина — на другой странице.
figure { break-inside: avoid; }
И при использовании более старого свойства:
figure { page-break-inside: avoid; }
На МДН:
- взлом
- разрыв страницы внутри
Сироты и вдовы
Спецификация фрагментации также определяет свойства orphans
и widows
. Свойство orphans
определяет, сколько строк может оставаться внизу первой страницы, когда содержимое, такое как абзац, разрывается между двумя страницами. Свойство widows
определяет, сколько строк может оставаться в верхней части второй страницы.
Поэтому, чтобы предотвратить появление одной строки в конце страницы и одной строки вверху следующей страницы, вы можете использовать следующее:
p { orphans: 2; widows: 2; }
Свойства widows
и orphans
хорошо поддерживаются (отсутствующей реализацией браузера является Firefox).
На МДН:
- вдовы
- дети сироты
box-decoration-break
Последним свойством, определенным в модуле Fragmentation, является box-decoration-break
. Это свойство определяет, будут ли границы, поля и отступы разрывать или оборачивать содержимое. Принимаемые значения:
-
slice
-
clone
Например, если моя область содержимого имеет 10-пиксельную серую рамку, и я печатаю содержимое, то по умолчанию это будет печататься так, что граница будет продолжаться на каждой странице, однако она будет переноситься только в конце содержимого. . Таким образом, у нас есть перерыв, прежде чем перейти к следующей странице и продолжить.
Если я использую box-decoration-break: clone
, граница и любые отступы и поля будут завершены на каждой странице, что даст каждой странице серую рамку.
В настоящее время это работает только для Paged Media в Firefox, и вы можете узнать больше о box-decoration-break на MDN.
Поддержка браузера
Как уже упоминалось, браузерная поддержка неоднородна для Paged Media и Fragmentation. Что касается фрагментации, дополнительная проблема заключается в том, что разрыв должен быть указан и реализован для каждого метода компоновки. Если вы надеялись использовать Flexbox или CSS Grid в таблицах стилей для печати, вы, вероятно, будете разочарованы. Вы можете проверить ошибки Chrome для Flexbox и для Grid.
Лучшее предложение, которое я могу дать прямо сейчас, — сделать ваши таблицы стилей для печати достаточно простыми. Добавьте свойства фрагментации, в том числе как старые свойства page-break-*
, так и новые свойства. Однако примите во внимание, что они могут работать не во всех браузерах. И, если вас разочаровывает отсутствие поддержки браузера, поднимите эти проблемы с браузерами или проголосуйте за уже поднятые проблемы. Фрагментацию, в частности, следует рассматривать как предложение, а не команду, даже если она поддерживается. Можно было бы настолько точно указать, где и когда вы хотите, чтобы что-то ломалось, что было бы почти невозможно выложить страницы. Вы должны предполагать, что иногда вы можете получить неоптимальный взлом.
Тестирование таблиц стилей печати
Тестирование таблиц стилей печати может быть чем-то утомительным, обычно требуя использования предварительного просмотра печати или многократной печати в PDF. Однако браузерные DevTools немного упростили нам эту задачу. И в Chrome, и в Firefox есть возможность просматривать только стили печати.
Fire Fox
Откройте панель инструментов разработчика, затем введите media emulate print
в командной строке.
Хром
Откройте DevTools, щелкните значок с тремя точками, а затем выберите «Дополнительные инструменты» и «Рендеринг». Затем вы можете выбрать печать в разделе «Эмуляция CSS Media».
Это будет полезно только при тестировании изменений в макете CSS, скрытом или сгенерированном контенте. Он не может помочь вам с фрагментацией — вам нужно будет распечатать или распечатать в PDF для этого. Тем не менее, это сэкономит вам несколько походов к принтеру и может помочь вам проверить, когда вы разрабатываете новые части сайта, которые вы все еще скрываете и показываете правильные вещи.
Что делать, если таблицы стилей печати недостаточно
В идеальном мире браузеры реализовали бы больше спецификаций Paged Media при печати напрямую из браузера, а фрагментация была бы реализована более тщательно и последовательно. Конечно, стоит упомянуть об ошибках, которые вы обнаружите при печати из браузера с соответствующими браузерами. Если мы не попросим исправить эти вещи, они останутся с низким приоритетом для исправления.
Если вам нужен высокий уровень поддержки печати и вы хотите использовать CSS, то в настоящее время вам необходимо использовать специальный пользовательский агент для печати, например Prince. Я подробно описал, как вы можете использовать CSS для форматирования книг при выводе в Prince, в моей статье «Проектирование для печати с помощью CSS».
Prince также доступен для установки на ваш сервер, чтобы генерировать красиво распечатанные документы с использованием CSS в Интернете, однако он стоит дорого. Альтернативой является сервер, такой как DocRaptor, который предлагает API поверх механизма рендеринга Prince.
Существуют генераторы HTML- и CSS-to-PDF с открытым исходным кодом, такие как wkhtmltopdf, но большинство из них используют механизмы рендеринга браузера для создания вывода на печать и поэтому имеют те же ограничения, что и браузеры, когда дело доходит до реализации спецификаций Paged Media и Fragmentation. Исключением является WeasyPrint, который, кажется, имеет свою собственную реализацию и поддерживает немного другие функции, хотя и не так полнофункционален, как что-то вроде Prince.
Дополнительную информацию о пользовательских агентах для печати можно найти на сайте print-css.rocks.
Другие источники
Из-за того, что за последние несколько лет печать из CSS практически не изменилась, многие старые ресурсы в Smashing Magazine и других источниках по-прежнему актуальны. Некоторые дополнительные советы и рекомендации можно найти в следующих ресурсах. Если вы обнаружили полезный рабочий процесс печати или технический совет, добавьте его в комментарии ниже.
- «Я совсем забыл о таблицах стилей для печати», — Мануэль Матузович, UX Collective.
- «Подходы к таблицам стилей печати: черный список против белого списка», Крис Койер, CSS-Tricks
- «Таблица стилей для идеальной печати», Андреас Хехт, Noupe
- «Как настроить таблицу стилей для печати», Кристиан Краммер, Smashing Magazine
- «5 мощных советов и приемов для таблиц стилей печати», Дадли Стори, Smashing Magazine