要件
「レスポンシブデザインを印刷する」大前提の要件として私が設定したものは以下
- 現状のCSSフレームワークを大きく改修せずに対応したい
- 可能な限り既存CSSに手を加えない(付け足しで対応したい)
- Sassのパーシャルで対応したい
以上です。
株式会社クインテットのレスポンシブデザインではBootstrapベースの独自CSSフレームワークを使っているのですが、Sassベースなのでパーシャル追加で対応したく、かつ、最低工数で対応したいので、既存のフレームワークを改修したくない、という贅沢な要件です。
調査
各ブラウザの印刷に関する仕様・状況を把握せねばならないので、「Windows」と「MAC」、「Google Chrome」「Firefox」「IE11」「EDGE」で調査。
いろいろありましたが、調査結果だけまとめ。
問題点
- 画面サイズがタブレットサイズくらいになってしまう【ほぼ全て】
→RWDなので、タブレット時のレイアウトになってしまう
→クインテット仕様の場合、グローバルがでない(ハンバーガーメニューなので) - 固定物(position: fixed;)が印刷ページごとに印刷される【IE、EDGE】
- 高さ固定に使っている「matchHeight.js」を適応しているものの高さが変になる
- 明朝体が表示されない??【MACのChromeのみ】
- 背景が印刷されない【ほぼ全て】
この中では特に1〜3番目をどうにかしないといけない・・・。
解決策
答えを先に書くと、要件の「現状のCSSフレームワークを大きく改修せずに対応したい」が不可能でした・・・。
印刷用のパーシャルを用意する
クインテットのCSSフレームワークはSass+パーシャルで構成されているので、Sassの最後に印刷用のパーシャルをインポートして対応させました。
Bootstrapの印刷用CSSを適応する
クインテットのCSSフレームワークはBootstrapベースなので、Bootstrapの印刷用CSSを適応させることにしました。
Bootstrapの印刷用CSSは以下から拝借しました。
https://github.com/onocom/bootstrap-print/blob/master/bootstrap-print.css
※onocom様、ありがとうございます!!
唯一手を加えたのは
overflow-y: visible !important;
これをコメントアウトしたくらいです(変なところにスクロールバーが出てしまったので)。
matchHeight.jsの問題
これはCSSで強制的に無効化。
無効化すると高さ揃わなくなるんですが、背に腹は代えられません・・・
[data-match-height],[data-mh] {
height: auto !important;
}
「matchHeight.js」はカスタムデータ属性で指定しているので、そのカスタムデータ属性を持つ要素の高さを強制的にautoにしました。
背景色を強制的に印刷させる
CSSで
-webkit-print-color-adjust: exact;
を指定すれば、強制的に背景を印刷させられます。
ただし、「Google Chrome」でしか使えません。
↓ブラウザ対応表
https://caniuse.com/#search=print-color-adjust
「Google Chrome」以外のブラウザを使っている場合には背景の印刷は手動で設定するようにしてください。
そもそも「EDGE」は背景を印刷できるようにする設定そのものがないようです・・・。
その他諸々調整
あとは諸々調整用のCSSを用意
@media print {
body {
zoom: .8;
padding-top: 0; //固定ヘッダ用に空けていたPaddingをリセット
.container {
width: 1200px !important;
}
* {
-webkit-print-color-adjust: exact;
font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", "sans-serif";
}
[data-match-height],[data-mh] {
height: auto !important;
}
}
.head_main, // 固定ヘッダ用のクラス
.position_sticky, // position: sticky; を指定したクラス
.sticky {
position: relative;
}
iframe {
background: lightgray;
}
}
IEやEDGEで印刷がはみ出す事象が確認されたので、zoomプロパティでちょっと縮小。
倍率は見ながら調整したほうが良いかも。
fixedになっていたヘッダは固定解除し、Bootstrapの「.container」がPCサイズになるように指定。
MACで謎の明朝体が表示されない問題があったので、念の為フォントをゴシックでリセット。
iframeは、私の環境で表示されてなかった(GoogleMap埋め込みとか)ので、グレーになるように設定。
position; sticky; しているコンテンツに注意
position: sticky;
要素を指定範囲内で追従させる「sticky」を活用している方も多いともいますが、「sticky」しているコンテンツはレイアウトが崩れる場合があるので、印刷時には「releative」になるように変更を加えたほうが良いです。
メディアクエリの書き換え
そしてこれが最もやりたくなかった、フレームワーク全体の改修・・・。
通常以下のような感じで記述していたメディアクエリを
@media (max-width: 767px) { /*スマホレイアウト*/}
@media (min-width: 768px) { /*タブレットレイアウト*/}
@media (min-width: 992px) { /*PCレイアウト*/}
@media (min-width: 1200px) { /*PC大画面レイアウト*/}
以下のように書き換えました。
@media only screen and (max-width: 767px) { /*スマホレイアウト*/}
@media print, screen and (min-width: 768px) { /*タブレットレイアウト*/}
@media print, screen and (min-width: 992px) { /*PCレイアウト*/}
@media print, screen and (min-width: 1200px) { /*PC大画面レイアウト*/}
適応されるレイアウトがタブレットくらいのサイズになる原因が、SP用のレイアウトが適応されていたから。
クインテットのRWDはモバイルファースト記述で、タブレットやPCサイズはメディアクエリで適応させていたので、スマホ専用の記述を印刷時には適応しないように「@media only screen」にした、というわけです。
逆に言えばこの程度で済んだので軽傷かもですね。
クインテットはGitHubでコード管理しているので、Gitで一斉置換してしまおうかと・・・。
まとめ
HTMLやCSSの設計状況では、上記の対応をそのままやっても対応できない部分があるかも知れませんが、ある程度参考にはなるかと。
ココ最近、ウェブページを印刷する。ということを考えたこともなかったので目からウロコな感じ。
しかし今回の件は、指摘を受ける前に気を回しておくべき事案でしたね。
反省・・・。
=うしお=
ご対応ありがとうございます。
思った以上にお手数をおかけしたようで・・・
クリニックの方は私たちの想像以上にPCに慣れていない方が多く、
印刷して確認したいニーズがあるので助かりました!
いえ、こちらこそ申し訳ありませんでした。
あまり印刷のことを考えていなかったので良い機会にもなりました。
また何かご要望があれば何なりと。m(_ _)m