Firefoxからの印刷でページが切れる問題の回避法

まず最初に書いておきます。
この記事はFirefoxのユーザーには関係ない内容です。HTMLを使った画面を作る開発者やデザイナー向けです。
また、今回私が動作確認をしたのは Firefox 2.0.0.12 です。その他のバージョンではまた違う動きをする可能性もありますし、完全に原因を把握した訳ではなく、動作がかなり微妙なのでもしかするとこの回避法でも回避できない場合もあるかもしれません。
なお、文中のHTMLは<>を全角で表記しています。

1.発端

システム開発の準備作業として紙芝居*1を作った際、ある画面がInternet Explorer 6(IE6)とOpera Ver9.26(検証のためダウンロードした最新版)では問題なく印刷できるのに、Firefox2.0.0.12では一部のページが切れてしまうと言う問題に遭遇した。

2.調査

Webを使って調べたところ次のような記事が見つかった。
Mozilla-gumi Forum
firefoxの印刷が切れる問題: マイチキンハート
現象が非常に似ているので、バージョンの違いには目をつぶり、スタイルシート(CSSファイル)やHTMLに埋め込んだSTYLEの「position」や「overflow」を変更してみた。しかし解決はしなかった。また、改ページ関連の「page-break-before:」「page-break-after:」「page-break-inside:」を変更しても改善することはなかった。

3.ブレイクスルーその1

対象のHTMLを見ると特徴的な事柄があった。

  • a.問題箇所

<TABLE class="XXXX">
<TR><TD>
見出し情報
</TD></TR>
<TR><TD>
<TABLE class="YYY1">
<TR><TD>
項目1 行明細1
</TD></TR>
<TR><TD>
項目1 行明細2
</TD></TR>


</TABLE>
<TABLE class="YYY2">
<TR><TD>
項目2 行明細1
</TD></TR>
<TR><TD>
項目2 行明細2
</TD></TR>


</TABLE>
</TD></TR>
</TABLE>

  • b.正常に印刷される箇所

<TABLE class="XXXX">
<TR><TD>
見出し情報
</TD></TR>
<TR><TD>
<table class="YYY2">
<TR><TD>
行明細1
</TD></TR>


</TABLE>
</TD></TR>
</TABLE>

a.b.ともにテーブルの中にテーブルが入れ子になっているが、aでは子供のテーブルが複数有り、bでは子供が1つである。aの情報を1ページ表示した後、2ページ目以降があるのにそれを無視してbの内容が表示されはじめ、bは3ページ目の末尾まで正常に表示されていた。
このことから、テーブルの入れ子構造の処理に原因があると推測した。

4.つかのまの凱歌

aを下記のように修正した

  • a'.修正後のa

<TABLE class="XXXX">
<TR><TD>
見出し情報
</TD></TR>
<TR><TD>
<TABLE class="YYY1">
<TR><TD>
項目1 行明細1
</TD></TR>
<TR><TD>
項目1 行明細2
</TD></TR>


</TABLE>
</TD></TR>
</TABLE>
<TABLE class="XXXX">
<TR><TD>
<table class="YYY2">
<TR><TD>
項目2 行明細1
</TD></TR>
<TR><TD>
項目2 行明細2
</TD></TR>


</TABLE>
</TD></TR>
</table>

ビンゴだった。入れ子になる子供テーブルを一つにするだけでaの部分は正常に印刷されるようになった。

5.無知の壁

あとはスタイルシートを調整し、意図通りのレイアウトにするだけ…。そう簡単に考えていた。しかしどうもうまく行かない。いくらスタイルシートを調整しても意図通りに表示されない。問題は解決したのになぜ!?
この答えは簡単だった。
スタイルシート(CSSファイル)の中に日本語のコメントを入れてはいけないらしいという情報を見つけることができたのだ。実際に日本語のコメントを除去したところ、ある程度の結果が得られ調整可能な状態になった。
それ以前にも日本語コメントは入っていたのでなんかしらの文字が引き金になっていたと思われる。経験では「5c」を含む文字が悪さをすることが多いのだが、コメントをascii文字にすれば回避できるし、EUCのコードは一文字も覚えていないので今回は調査をしなかった。恐ろしいことにShift-JISなら「5c」を含む漢字をいくつかはっきり覚えている。
念のため、IEOperaでも動作を確認し、一仕事終えた余韻に浸ろうとしていた私は、予想できなかった現実を目の当たりにすることになる。

6.最大の壁

プレビューの確認だけでは正常に動作するとは言えない。最終的には実際に印刷をして確認をした。
なんということか。
先ほどまで正常に印字されていたbの部分が印字されなくなってしまっていた。しかも、現象はさっき解決したのと同じ、つまり1ページ目は印刷されるのに2ページ目以降が切れてしまうと言う物であった。
今回印刷した画面は一番最後にフッターがついている。それはどの場合にも正常に印刷されていた。
まったくわからない。どうして正常に印刷できていた部分が、そことは関係ないところを修正しただけでまともに印刷されなくなってしまうのか…
Firefox NGという但し書きをつけるしかないのか…。あきらめかけていたその矢先だった。

7.ブレイクスルーその2

何の根拠もない思い付きである。オカルトと言ってもいいかもしれない。
「テーブルの行数が多すぎるのでは?」
そういう仮説が思い浮かんだ。
全くなんの期待もせずに無駄な作業をのろのろと進めた

  • b'.修正後のb

<table class="XXXX">
<TR><TD>
見出し情報
</TD></TR>
<TR><TD>
<table class="YYY2">
<TR><TD>
行明細1
</TD></TR>
<TR><TD>
行明細2
</TD></TR>


<TR><TD>
行明細20
</TD></TR>
</table>
</TD></TR>
</table>
<table class="XXXX">
<TR><TD>
<table class="YYY2">
<TR><TD>
行明細21
</TD></TR>
<TR><TD>
行明細22
</TD></TR>


<TR><TD>
行明細40
</TD></TR>
</table>
</TD></TR>
</table>
<table class="XXXX">
<TR><TD>
<table class="YYY2">
<TR><TD>
行明細41
</TD></TR>


<TR><TD>
行明細ラスト
</TD></TR>
</table>
</TD></TR>
</table>

恐ろしいことが起こった。
正常に印刷できるのである。全く理由がわからない。しかし、大事なのは正常に動作することである。システム化した場合当然動かなくなる可能性は残っている。それでも、紙芝居レベルで動かない以上、システム化しても動くはずがない、そう考えると大きな一歩である。

8.まとめ

Firefox 2.0.0.12で入れ子の表組みをしてスタイルシートを利用した場合、正常に印刷されないことがあります。
回避策として、
1.親のテーブルの中に子供のテーブルを一つ以上入れないこと
2.上記を含め、テーブルの大きさをある一定限度にとどめること
が考えられます。






以下は余談です。


もし、自分が趣味で作っているサイトで同様の問題が起きたとしたら、一応調べて修正する気になったとしても6の壁にぶつかった瞬間にそれ以上粘ることは無かったと思います。
自分書いたコードのせいとは思えないんですよね、これ。何度もチェックしてHTMLとしては正しいっぽくてスタイルシートにも問題はない、そして、画面にはちゃんと表示されているんですから。状況から類推するにそもそもの原因はFirefox2.0.0.12に有る可能性が高いのです。
それでも、とりあえず、紙芝居レベルでも修正をした。それはなぜか?
もし、この画面が採用されて実際にシステムで生成することになると、一般のユーザーが印刷することになるんですよ。その時、Firefoxで印刷できなかったとしたらどう思うか?
Firefoxだっせー」と思う人もいらっしゃるかも知れません。もしかすると「うわ、これ作ったプログラマーorデザイナー行けてね〜」と思ってくれる人もいるかもしれません。そう、それならいいんですよ。でも、実際には「あーあ、この会社だめじゃん」と思っちゃう人も少なからずいるんですよね。それは、たとえ今直接やりとりしているお客様が「そこまでこだわらなくてもいいよ」とおっしゃってくれても可能ならば避けたいんです。むろんどうしてもできないことだってあります。でも、できることなら、自分、あるいは自分の会社と自分の会社にとってのお客様だけの問題ではなく、さらにその先に波及する問題でもあるので解決したかったんです。


今回の解決法はネットで探した限りどこにも書いてありませんでした。原因がはっきりとはつかめていないので汎用的な回避法ではないのかも知れませんが同じ悩みを抱えている開発者やデザイナーの中にはこれで問題を解決することができる人もいるかもしれません。そういう思いもあって、今日ここに公開しました。
しかし公開した一番大きな理由は別の所にあります。


自分で忘れないようにするための備忘録(笑)。


システム開発まで間があるのですっかり忘れてしまってまた検索して今度は自分のサイトにたどりつくなんてこともあるかもしれませんね。

*1:背後のロジックは作りこまず画面イメージだけを作りユーザーに説明するための資料