CSSで印刷レイアウトをコントロール

Webサイトを制作する上で印刷された時の見栄えを考慮しなければならないことがたまにあります。
考慮しないでコーディングをしてしまうと印刷時にコンテンツが複数ページにわたってしまい変なところで別ページに分割されることがあります。

それをこんな感じに綺麗に改ページを行うためのHTMLの構成とCSSの組み方を考えてみます。

※Chromeを使って確認したコードなのでChromeで確認して下さい。

HTML構成

まず、HTMLの構成から考えてみます。

1つのページは<section>タグを使用します。
そして、複数のページを<article>タグでまとめます。

つまりHTMLとしては下記のような構成になります。


<article>
    <section>
         <h1>1ページ目</h1>
    </section>
    <section>
         <h1>2ページ目</h1>
    </section>
    <section>
         <h1>3ページ目</h1>
    </section>
</article>

改ページ

ここにCSSを当てていき印刷すると綺麗にページが分かれるように組んでいきます。

まず、<section>タグに.print_page、<article>タグに.print_pagesというクラスを付けていきます。
ついでにprint.cssというスタイルシートを読み込みます。


<link media="print" rel="stylesheet" href="print.css">
<article>
    <section class="print_page">
        <h1>1ページ目</h1>
    </section>
    <section class="print_page">
        <h1>2ページ目</h1>
    </section>
    <section class="print_page">
        <h1>3ページ目</h1>
    </section>
</article>

print.cssに.print_pageクラスの中身を定義していきます。
今回はA4縦でピッタリ印刷できるよう組んでいきます。


.print_page{
    width: 172mm; /* A4縦の幅 */
    height: 251mm; /* A4縦の高さ */
    page-break-after: always; /* 各ページの終わりに改ページ */
}

この状態で印刷プレビューを行うと<section>内の文字列がページごとに分かれるようになっているはずです。

改ページ修正

このままでは空白の4ページ目ができてしまいますので最後のページは改ページさせないようにします。


.print_page{
    width: 172mm;
    height: 251mm;
    page-break-after: always;
}
.print_page:last-child{
    page-break-after: auto; /* 最後のページの改ページを防ぐ */
}

最後の<section>タグにpage-break-afterをautoにすることで最後のページの改行を防ぐことができます。
逆にpage-break-beforeを使って、最初の<section>タグにpage-break-afterをautoとしても同じことができます。

固定ヘッダー

簡単に出来てしまいましたがこのままではつまらないので固定ヘッダーを入れてみます。


.print_page{
    width: 172mm;
    height: 251mm;
    page-break-after: always;
    position: relative; /* 固定ヘッダーの基準座標を定義 */
}
.print_page:last-child{
    page-break-after: auto;
}
 
.print_page:before{
    position: absolute; /* 位置の相対指定 */
    right: 0; /* 右から0ピクセルの位置指定 */
    top: 0; /* 上から0ピクセルの位置指定 */
    content: "Asial CSS Print Demo"; /* ヘッダーのテキスト */
}

.print_pageのスタイルにposition: relative;を入れた後にbefore擬似要素でヘッダーを入れます。
position: relative;を入れないと1ページ目の右上にヘッダーが集まってしまうので気をつけてください。

これで各ページの右上にAsial CSS Print Demoという文字が表示されます。

固定フッターとCSSによる自動付番

最後に各ページのフッターにCSSだけを使ってページ番号を入れてみたいと思います。


.print_page{
    width: 172mm;
    height: 251mm;
    page-break-after: always;
    position: relative;
    counter-increment: print_page_count; /* ページ番号のインクリメント */
}
.print_page:last-child{
    page-break-after: auto;
}
.print_page:before{
    position: absolute;
    right: 0;
    top: 0;
    content: "Asial CSS Print Demo";
}
.print_page:after{
    position: absolute; /* 位置の相対指定 */
    right: 0; /* 右から0ピクセルの位置指定 */
    bottom: 0; /* 下から0ピクセルの位置指定 */
    content: counter(print_page_count) "ページ"; /* ページ番号を擬似要素に表示 */
}

使用するCSSプロパティはcounter-incrementとcounterです。
このプロパティを使用するとCSS内でカウント用の変数を扱うことができ擬似要素内で表示させることができます。

変数名は何でもいいのですが分かりやすい名前としてprint_page_countという変数名にしました。

この状態で印刷プレビューをすると3ページに分かれ、なおかつ固定のヘッダーとフッターが各ページに表示されるはずです。

あまり用途がないノウハウではありますがいざとなった時のために覚えておいて損は無いと思います。