◆ 画像を使って背景色をつけるスクリプト
◆ Chrome なら CSS だけで対応可能

web の印刷ってブラウザがデフォルトで背景を印刷しないようになっていますよね
web ページってリッチな見た目にするために背景に色がついてないところが珍しいくらいで 全部印刷するとインクがすごいことになりそうですから

それでも背景を印刷したいケースはあるわけです
通常はブラウザのオプションで「背景も印刷する」に設定すればいいのですが 一部ブラウザ(Edge とか Edge とか Edge とか) では対応してなかったりします
QA サイトの回答で 「Internet Explorer で開く」 ボタンを押しましょう と書いてたのにはちょっと笑いました

こんなだから Edge への乗り換えがイマイチなんでしょうね

あとついでに Chrome や Firefox でもユーザの設定問わず強制的に背景印刷させて なんていう無茶な要求をするところもあるようです

そんな人のために作ってみた 背景色を画像で置き換えるスクリプト
!function(){
const style = document.createElement("style")
style.innerHTML = `
.color-block { display: none; }
@media print {
.color-block {
position:absolute!important;
left:0!important;
top:0!important;
width:100%!important;
height:100%!important;
display: block!important;
visibility: visible!important;
z-index: -1!important;
}
}
`

function paint(selector, fill_color){
document.head.append(style)
const color_block = Object.assign(document.createElement("img"), {
src: `data:image/svg+xml;utf8,<svg width="1" height="1" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="1" height="1" fill="${fill_color}"/></svg>`,
className: "color-block",
})
for(const elem of document.querySelectorAll(selector)){
const pos = window.getComputedStyle(elem).getPropertyValue("position")
if(pos === "static") elem.style.position = "relative"
elem.append(color_block.cloneNode(true))
}
}

window.paint = paint
}()

サンプル

<style>
table {
width: 500px;
border-collapse: collapse;
}
th, td{
border: 1px solid #f93;
text-align: left;
padding: 3px 10px;
}
</style>
<table>
<tr><th>abc</th><td>def</td></tr>
<tr><th>abc</th><td>def</td></tr>
<tr><th>abc</th><td>def</td></tr>
</table>

<script>
paint("th", "mistyrose")
</script>

paint 関数にセレクタと色を指定すれば印刷時のみ画像で色をつけてくれます
画像だと背景色を印刷しないようになっていても印刷されますから 設定によらず印刷できます

paintbyimg01
paintbyimg02


背景色を有効にしたいと言っても 「ここは table のヘッダだから必要だけど全体が薄い水色なのはいらない」 と言ったことがありそうなのとグラデーションや背景画像があるとうまく対応できないので全要素の背景色を自動設定するようにはしていません

必要なところのみ paint 関数で塗ってください


やってることは 単純で 1 x 1 px の色付き svg 画像を data URI で作って塗りたい要素の 100% の大きさで配置してます
z-index が -1 なので文字があればそれが上に来るので背景色のように扱われます

Chrome だけなら

-webkit-print-color-adjust という Chrome のみの CSS があるので Chrome だけならこれで対応ということもできます

標準ではないので 今後変わる可能性は十分ありますが 全体向けとしての仕様が決まる感じもないのでしばらくはこれで良さそうな気もします



ところで 以前書いた サーバサイドに現時点の DOM 送って PDF 化したものをレスポンスで受け取る方法だと こういう問題もなくて意外といいんじゃないかなーと思ってたりします