Я со­всем за­был про сти­ли для пе­ча­ти

Перевод «I totally forgot about print style sheets»

Перевод Никита Дубко

Редактура Вадим Макеев

Небольшая коллекция полезных CSS-техник и короткое напоминание, что стили для печати всё ещё актуальны.

Аарон Густафсон опубликовал твит про Indiegogo, в котором он указал на то, что их страницы с деталями заказа невозможно использовать в печатном виде.

Уважаемые @Indiegogo, пожалуйста, обратите внимание, как выглядит печатная версия вашей страницы с деталями заказа. Прямо сейчас она отстойная. Аарон Густафсон

Скриншот предпросмотра печати с огромными иконками.

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

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

Я давно отказался от домашних принтеров, потому что они постоянно ломаются после десяти минут использования. Но не все такие как я, … Хейдон Пикеринг (Инклюзивные дизайн-паттерны)

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

1. Подключение стилей для печатиСкопировать ссылку

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

body {
    font-size: 18px;
}

@media print {
    /* стили для печати */

    body {
        font-size: 28px;
    }
}

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

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

2. ТестированиеСкопировать ссылку

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

Обновление от 6 ноября 2019: Вот подробная статья Криса Койера о том, как эмулировать стили для печати в 2019 году.

Для отладки стилей для печати в Firefox откройте Developer Toolbar (Shift F2 или Tools > Web Developer > Developer Toolbar) и введите media emulate print в поле внизу окна браузера и нажмите Enter. Активная вкладка будет вести себя так, как будто для неё задан медиа-тип print, пока вы не закроете её или не обновите страницу.

Обновление от 20 октября 2018: начиная с Firefox 63+ этот способ не работает, так как Developer Toolbar был удалён.

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

В Chrome откройте инструменты разработчика (Cmd Opt I (macOS) или Ctrl Shift I (Windows) или View > Developer > Developer Tools, включите группу вкладок с консолью (Esc), откройте панель рендеринга, поставьте галочку возле Emulate CSS Media и выберите Print.

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

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-before на MDN.

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

page-break-after позволяет нам форсировать или избегать разрывов страницы после элемента.

h2 {
    page-break-after: always;
}

Свойство page-break-after на MDN.

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

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

ul {
    page-break-inside: avoid;
}

Свойство page-break-inside на MDN.

Вдовы и сиротыСкопировать ссылку

Иногда вы не хотите принудительно разрывать страницу, но, по крайней мере, хотите контролировать количество строк, отображаемых на текущей или следующей странице. Например, если последняя строка абзаца не помещается на текущей странице, последние две строки этого абзаца будут напечатаны на следующей странице, даже если не поместилась только последняя. Так происходит потому, что свойство, которое этим управляет, widows (англ. «вдова» — прим. редактора), имеет значение по умолчанию 2. Мы можем это изменить.

p {
    widows: 4;
}

Если всё наоборот и на текущей странице помещается только одна строка, весь абзац будет напечатан на следующей странице. За такое поведение отвечает свойство orphans (англ. «сирота» — прим. редактора), и его значение по умолчанию также равно 2.

p {
    orphans: 3;
}

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

Вот готовый CodePen с некоторыми примерами (дебаг-версия для более лёгкого тестирования).

Не все свойства и значения работают во всех браузерах, вам нужно проверять ваши стили для печати в разных браузерах.

6. Сброс стилейСкопировать ссылку

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

Вот отрывок из стилей для печати HTML5 Boilerplate:

*,
*::before,
*::after {
    color: #000000 !important;
    text-shadow: none !important;
    background: #ffffff !important;
    box-shadow: none !important;
}

Стили для печати — одно из немногих исключений, где нормально использовать !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 рядом с каждой ссылкой, у которой есть атрибут 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, а тип носителя — 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-кодыСкопировать ссылку

В этой статье на Smashing Magazine есть несколько хороших советов. Один из них — показывать QR-код на печатных страницах, чтобы пользователям не приходилось вводить полный адрес страницы для перехода к веб-версии.

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

Во время своего исследования я нашел отличный инструмент, который помогает печатать неоптимизированные страницы. С помощью Printliminator вы можете удалять элементы, просто кликая по ним.

Демо на YouTube и сам проект на Github.

Бонус 2: GutenbergСкопировать ссылку

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

Бонус 3: HartijaСкопировать ссылку

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

Вот и всё! Вот ссылка на мой CodePen (дебаг-версия), если вы хотите увидеть некоторые из этих вещей в действии. Надеюсь, вам понравилась эта статья.

P.S. Спасибо Еве за редактирование статьи и Марио за совет про Gutenberg.

ИсточникиСкопировать ссылку