Bootstrap4なページの印刷TIPs

2 min read読了の目安(約1800字

概要

基本的にレスポンシブなサイトでも、時には特定のページを印刷したい(と言われる)時があると思います。

想定する画面の横幅が違いますから、(例えばA4横の)印刷をしたい時にはレイアウトに関する最初のお約束である<div class="container-sm">を解除しないといけません。

その自動化の方法を簡単に紹介します。

方法

<body>直後に<div class="container-sm" id="container">が置いてあると仮定します。

javascript

var mediaQueryList = window.matchMedia('print');
mediaQueryList.addEventListener('change', function (mql) {
	if (mql.matches) {
		$('#container').removeClass('container-sm');
	} else {
		$('#container').addClass('container-sm');
	}
});

です。2行目は

mediaQueryList.addListener(function (mql) {

とも書けますが、.addListener()は廃止予定だそうです[1]ので、最初から新しい方を書くと良いですね。

他に試してダメだったこと

印刷に際して、addEventListener()は4回呼ばれています。
私の理解ですと、

  • 1回目、印刷プレビューが呼ばれたのを検知している
  • 2回目、javascriptによってプレビューとスクリーン(同一のソース)が更新されたのを検知している
  • 3回目、印刷機能の終わり(プレビュー完了)を検知している
  • 4回目、ソースを変えても、もうスクリーンにしか影響しない

したがって、以下の方法はダメです。

setTimeout (function(){
	$('#container').removeClass('container-sm');
}, 500);
	$('#container').toggleClass('container-sm');

冒頭に掲載した以外の方法で意図した通りに動く方法が他にあれば教えてください

HTML

印刷に対するCSSの対応は

<link rel="stylesheet"href="css/print.css" media="print" />

などと、headタグに挿入し、本番のCSSファイルとは別にした方が差分がわかりやすくて良いです。
この、media="print"という指定ができることがあまり知られていないような気がします。

css

print.cssの方では冒頭に以下のような指定をして1ページあたりのサイズを決めます。[2]

@page {
    size: A4;
	/* marginやpaddingなどを指定 */
}

横の場合

@page {
  size: A4 landscape;
	/* marginやpaddingなどを指定 */
}

背景

私はWeb専門でないエンジニアなのに、Web屋さんから印刷用レイアウトが可能か?
みたいな問い合わせをちらほらいただくので、あまり世間で知られていないのかなぁ、
と思いましたのでZennのテストもかねて共有させていただきます。

この記事を読んだ後に読むと便利な記事

脚注
  1. VSCodeで警告が出て気付いた。 ↩︎

  2. 複数ページに分割する方法などは割愛します。 ↩︎