CSS で印刷用のスタイルを設定できる
大抵のブラウザでは Web ページを印刷することができます。
しかし Web ページをそのまま印刷しようとすると改ページがおかしくなったりレイアウトがおかしくなってしまうことがあるでしょう。そもそも Web ページはディスプレイで表示することを目的としているので印刷には不向きなものです。
とはいえ Web ページを印刷したいというニーズは少なからずあることでしょう。そのような場合には @media print のような印刷用の CSS を利用することで見た目を整えることができます。
@media print のサンプル
早速ですが @media print を使用した例を見てみましょう。下記のようにシンプルな Web サイトを用意しました。

コードは以下の通りです。
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>CSS 印刷テスト</title>
  <style>
    @media print {
      .no-print {
        display: none;
      }
    }
  </style>
</head>
<body>
  <h1>CSS 印刷テスト</h1>
  <p>ここは常に表示されます。</p>
  <p class="no-print" style="color: red;">ここは印刷時に非表示になります。</p>
</body>
</html>
クラス .no-print はメディアクエリ print の中で指定されています。このスタイルはプリント時のみに適用されます。赤文字で表示されている箇所にはクラス .no-print を指定しているので印刷のプレビュー時だけこの文字は表示されなくなります。
実際に表示を確認してみましょう。Google Chrome において印刷プレビューを表示するには[ファイル] > [印刷] をクリックするか、次のキーボード ショートカットを使用します。
- Windows と Linux の場合: Ctrl+P
- Mac の場合: ⌘+P

確かに、印刷プレビュー画面では赤文字は表示されていません。
その他の指定方法
大抵の場合には @mdia print で指定するのでこと足りると思いますがその他の指定方法でも印刷時にのみに適応するスタイルを指定できます。
link/style media="print"
<link> で CSS ファイルを読み込み時や <style> タグ内に CSS を記述する際に media 属性を指定できます。
<style media="print">
  .no-print {
    display: none;
  }
</style>
@import print
@import を使用して CSS ファイルを読み込む際に print を付与すると読み込んだ CSS ファイルは印刷時にのみ適用するようになります。
- index.html
<head>
  <title>CSS 印刷テスト</title>
  <link rel="stylesheet" href="style.css">
</head>
- style.css
@import "./print.css" print;
- print.css
.no-print {
  display: none;
}
@page で用紙のサイズを指定する
@page は CSS のアットルールで文書を印刷するときに一部の CSS プロパティを変更するために使用します。特に size は @page 内のみで使用できるプロパティで A4 ・ B5 などの絶対的なサイズや 4in 6in のような指定方法が可能です。
size プロパティは実験的な機能であり Firefox や safari などのブラウザでは使用できないことに注意してください。

実際に Google Chrome で size プロパティを指定してみるとたしかにプレビュー時のサイズが異なっていることがわかります。また size プロパティを指定すると印刷時の詳細設定でユーザーが用紙のサイズを選択することができなくなっています。

印刷時の改ページを制御する
以下の CSS プロパティを使用すると印刷時の改ページを制御することができます。
- break-before 指定した要素の直前の改ページを制御
- break-inside 指定した要素の途中の改ページを制御
- break-after 指定した要素の後の改ページを制御
break-before,break-inside には区切りを強制する値(always, left, right, page, column, region)または区切りを防止する値(avoid, avoid-page, avoid-region, avoid-column)を指定できます。break-inside には区切りを防止する値のみを指定できます。
また同時に複数のプロパティが指定された場合には以下の優先度の通りに適用されます。
break-before > break-inside > break-after
このプロパティを使用した例を見てみましょう。<h1> 要素に bread-before:page を指定して各見出しごとに改ページが挿入されるようにします。
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>CSS 印刷テスト</title>
  <style>
    h1 {
      break-before: page;
    }
  </style>
</head>
<body>
  <h1>見出し1</h1>
  <p>ここに本文が入ります。</p>
  <h1>見出し2</h1>
  <p>ここに本文が入ります。</p>
  <h1>見出し3</h1>
  <p>ここに本文が入ります。</p>
  <h1>見出し4</h1>
  <p>ここに本文が入ります。</p>
</body>
</html>
通常の表示時には見た目に変化はありません。

印刷プレビューで表示すると改ページされていることがわかります。


JavaScript から印刷プレビューを呼びだす
ブラウザの既定の方法から印刷を実行するのは慣れていない人にとっては少々分かりにくい操作です。「このページを印刷する」といったボタンを設置してボタンをクリックしたときに印刷ができるようにしたいところです。
そのような場合には window.print() メソッドを使用します。このメソッドを呼び出すと印刷ダイアログを表示します。
<body>
  <h1>CSS 印刷テスト</h1>
  <p>ここは常に表示されます。</p>
  <button id="print" class="no-print">このページを印刷する</button>
  <script>
    document.querySelector('#print').addEventListener('click', () => {
      window.print();
    });
  </script>
</body>
プリント画面のデバッグ
開発時に印刷ダイアログを毎回開いて表示を確認するのは非常に面倒です。ブラウザの開発者ツールを使用すれば印刷画面をエミュレートして表示することができます。
まずは開発者ツールを開いて「⋮」> 「More tools」> 「Rendering」を選択します。

「Emulate CSS media type」を探して「print」を選択します。

すると印刷プレビューで表示したときと同じく .no-print クラスを付与した要素が
非表示となります。


Discussion