Аарон Густафсон недавно отправил твит Indiegogo, в котором было сказано, что при распечатке их страниц с информацией о заказе получается нечто совершенно неприличное. И понеслооось.
Меня этот твит зацепил. Я вдруг понял, что уже и не вспомню, когда оптимизировал веб-страницы для печати или хотя бы проверял то, как они выводятся на принтер.
Основное внимание в ходе веб-разработки приковано к электронным версиям сайтов. Страницы приходится проверять во множестве браузеров, испытывать на разных размерах окон… До принтеров ли тут. А может, я забыл о стилях для печати потому что сам редко делаю бумажные копии страниц. Как бы там ни было, я почувствовал, что ситуацию надо срочно исправлять.
Печатный вариант веб-страницы имеет такое же право на существование, как и электронный. И, если мы стремимся к тому, чтобы сделать наши материалы как можно доступнее, не стоит пренебрегать бумажными носителями информации. Кроме того, не следует делать предположений о пользователях и об их поведении. Люди всё ещё распечатывают веб-страницы на принтерах. Просто представьте себе статьи или посты в блогах, страницы с рецептами, контактными сведениями, схемами проезда или со списками объявлений. Рано или поздно кто-нибудь непременно попытается распечатать что-то из того, что вы разместили в интернете.
Вот что говорит по этому поводу Хейдон Пикеринг, автор книги «Inclusive Design Patterns»: «Я уже давно не пользуюсь домашними принтерами. Дело тут в том, что у меня возникает ощущение, будто они ломаются минут через десять после того, как запустишь печать. Но я – не все».
Если сейчас вы поняли, что, как и я, не уделяли должного внимания стилям для печати, надеюсь, мой рассказ сослужит вам хорошую службу и поможет быстро освежить память. А если вы вообще никогда не оптимизировали веб-страницы для принтеров, моя небольшая коллекция полезных CSS-приёмов позволит вам к такой оптимизации приступить.
1. Использование CSS-стилей для печати
Лучший способ подключить к странице стили для печати – это объявить правило
@media
в вашем основном CSS-файле.body {
font-size: 18px;
}
@media print {
/* здесь будут стили для печати */
body {
font-size: 28px;
}
}
Как вариант, можно вынести стили для печати в самостоятельный файл и подключить его в HTML, но при таком подходе понадобится дополнительный запрос при загрузке страницы.
<link media="print" href="print.css" />
2. Тестирование
Как оценить внешний вид веб-страницы, подготовленной для печати? Любому ясно, что выводить её на бумагу после каждого изменения стиля – не лучшее решение. К счастью, возможностей браузеров вполне достаточно для «безбумажной» проверки печатных вариантов страниц.
В зависимости от браузера, можно экспортировать страницу в PDF, воспользоваться функцией предварительного просмотра или даже отлаживать страницу прямо в веб-обозревателе.
Для отладки стилей печати в Firefox, откройте Панель разработчика, воспользовавшись комбинацией клавиш Shift + F2 или выполнив команду меню Разработка → Панель разработки. Введите в командной строке, расположенной в нижней части окна, следующее:
media emulate print
, завершив ввод нажатием Enter. Активная вкладка будет действовать так, если бы для неё media type было бы print, до тех пор, пока вы не закроете или не обновите страницу.Эмуляция печати в Firefox
В Chrome тоже имеется подобная возможность. Откройте Инструменты разработчика, для чего, в MacOS, можно воспользоваться комбинацией клавиш CMD + Opt + I, в Windows – Ctrl + Shift + I, или выполните команду меню Дополнительные инструменты → Инструменты разработчика. После этого откройте панель рендеринга. Один из способов сделать это заключается в том, чтобы, нажав на клавишу Esc, вывести панель Console, а затем, через меню, открыть панель Rendering. В панели рендеринга установите флаг Emulate CSS Media и выберите Print.
Эмуляция печати в Chrome
Ещё о тестировании печатных версий веб-страниц можно почитать на StackOverflow.
3. Абсолютные единицы измерения
Абсолютные единицы измерения не очень подходят для экранных вариантов страниц, но для печати они – это как раз то, что нужно. В стилях для печати совершенно безопасно, более того – рекомендовано использовать абсолютные единицы измерения, наподобие
cm
, mm
, in
, pt
, или pc
.section {
margin-bottom: 2cm;
}
4. Свойства страниц
Для управления свойствами страниц, вроде их размеров, ориентации и полей, можно использовать правило
@page
. Это оказывается очень кстати, скажем, когда надо, чтобы у всех печатных страниц были одинаковые поля.@media print {
@page {
margin: 1cm;
}
}
Правило
@page
– это часть стандарта Paged Media Module, который предлагает множество замечательных вещей, вроде выбора первой страницы для печати, настройки пустых страниц, позиционирования элементов в углах страницы и так далее. Его можно использовать даже для того, чтобы готовить к печати книги.5. Управление разрывами страниц
Так как печатные листы, в отличие от веб-страниц, не бесконечны, содержимое веб-страниц рано или поздно обрывается на одном листе бумаги и продолжается на следующем. Для управления разрывами страниц имеется пять свойств.
▍Разрыв страницы перед элементом
Если нужно, чтобы некий элемент всегда находился в начале страницы, можно поставить перед ним принудительный разрыв страницы с помощью свойства
page-break-before
.section {
page-break-before: always;
}
▍Разрыв страницы после элемента
Свойство
page-break-after
позволяет задать принудительный разрыв страницы после элемента. С помощью этого свойства можно и запретить разрыв.h2 {
page-break-after: always;
}
▍Разрыв страницы внутри элемента
Свойство
page-break-inside
окажется очень кстати, если нужно избежать разделения некоего элемента между двумя страницами.ul {
page-break-inside: avoid;
}
▍Верхние и нижние висячие строки
Иногда в принудительном разрыве страниц нет нужды, но требуется управлять выводом абзацев на границах страниц.
Например, если последняя строка абзаца на текущей странице не помещается, на следующей странице будут напечатаны последние две строки этого абзаца. Это происходит из-за того, что свойство, которое это контролирует (
widows
, то есть – «верхние висячие строки») по умолчанию установлено в значение 2. Это можно изменить.p {
widows: 4;
}
Если возникла другая ситуация и лишь одна строка абзаца помещается на текущей странице, весь абзац будет напечатан на следующей странице. Свойство, ответственное за нижние висячие строки (
orphans
), по умолчанию так же установлено в 2.p {
orphans: 3;
}
Смысл вышеприведённого кода заключается в том, что для того, чтобы абзац не переносился целиком на следующую страницу, как минимум три строки должны поместиться на текущей странице.
Для того, чтобы лучше в этом разобраться, взгляните на пример, подготовленный с помощью CodePen. А вот – отладочная версия того же примера, её удобнее тестировать.
Надо отметить, что не все свойства и их значения универсальны, поэтому CSS-стили для печати стоит проверять в разных браузерах.
6. Сброс стилей
Готовя веб-страницу к печати, имеет смысл сбросить некоторые стили, например –
background-color
, box-shadow
, color
.Вот фрагмент из HTML5 Boilerplate print style sheet:
*,
*: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;
}
Кстати, CSS-стили для печати – одно из немногих исключений, где директива
!important
– это абсолютно нормально ;)7. Удаление ненужного контента
Для того, чтобы впустую не тратить чернила, следует убирать из печатного варианта страницы всё ненужное, вроде огромных красивых слайдов, рекламы, средств навигации по сайту и прочего подобного. Сделать это можно с помощью установки свойства
display
в значение none
у ненужных элементов. Вполне возможно, что вы сочтёте правильным показать лишь основное содержимое страницы, а всё остальное – скрыть:body > *:not(main) {
display: none;
}
8. Вывод адресов ссылок
Ссылки, в том виде, в котором они обычно присутствуют на веб-страницах, при печати совершенно бесполезны, если только читателю бумажной версии документа не известно, куда они ведут.
Для того, чтобы вывести адреса ссылок после их текстовых представлений, достаточно воспользоваться следующим стилем:
a[href]:after {
content: " (" attr(href) ")";
}
Конечно, при таком подходе «расшифровано» будет много лишнего. Например, относительные ссылки, абсолютные ссылки на том же сайте, где размещена печатаемая страница, ссылки с якорями и так далее. Для того, чтобы не засорять печатную страницу, лучше будет использовать примерно такую конструкцию:
a[href^="http"]:not([href*="mywebsite.com"]):after {
content: " (" attr(href) ")";
}
Выглядит это, конечно, безумно. Поэтому объясню смысл данного правила обычным языком: «Отобразить значение атрибута
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) {
/* только для экрана */
}
Почему это так? Всё дело в том, что CSS-правила применяются только в том случае, если значение
min-width
равно 48em
, и если media-type
– это screen
. Если избавиться в этом медиа-запросе от ключевого слова screen
, то он окажется ограниченным лишь значением min-width
.@media (min-width: 48em) {
/* все типы средств отображения информации */
}
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-коды
Вывод на печать QR-кодов, содержащих важные ссылки, может значительно повысить удобство работы с бумажными версиями веб-страниц. Вот материал в The Smashing Magazine, где можно найти полезные советы на эту тему. Один из них заключается в том, чтобы включать в печатные страницы их адреса в виде QR-кодов. В результате пользователю, для того чтобы открыть в браузере страницу, с которой была сделана распечатка, не придётся набирать на клавиатуре её полный адрес.
14. О печати неоптимизированных страниц
Занимаясь темой печати веб-страниц, я обнаружил отличный инструмент, который позволяет удобно готовить к выводу на принтер неоптимизированные страницы. С помощью Printliminator можно убрать со страницы ненужные элементы, просто щёлкая по ним. Вот демонстрация работы с этим инструментом на YouTube, а вот – страница проекта на Github.
15. Gutenberg
Если вам нравятся фреймворки, вам может приглянуться Gutenberg, который немного упрощает подготовку веб-страниц к печати.
16. Hartija
А вот ещё один CSS-фреймворк для печати. Называется он Hartija, создал его Vladimir Carrer.
Итоги
Если вы хотите увидеть в деле кое-что из того, о чём мы говорили, вот ссылка на проект в CodePen с примерами (а вот – его отладочная версия).
Оптимизировать веб-страницы для печати не так уж и сложно. Пожалуй, самое главное – не забывать об этом. Надеюсь, теперь сайтов, которые дружат с принтерами, станет немного больше.