LaTeX の表に色を敷く colortbl は、セルの背景を塗っているのではありません。セルの うしろに色のパネルを敷いている——作者 David Carlisle 自身の説明書がそう書いています。表の色にまつわる不可解な現象は、ほぼすべてこの一文から導けます。\cline を引いたのに線が見えないのはなぜか。booktabs と組み合わせると罫線と色のあいだに白い帯が残るのはなぜか。このページでは \usepackage[table]{xcolor} の一行から始めて、\rowcolor(行)・\columncolor(列)・\cellcolor(セル)・縞模様の \rowcolors・罫線の \arrayrulecolor を順に見ていき、最後に「そもそも色を使うべきか」という booktabs 側の言い分まで辿ります。
表に色を付けるにはどのパッケージが必要か
必要なのは一行、\usepackage[table]{xcolor} だけです。colortbl を明示的に読み込む必要はありません——xcolor の table オプション が colortbl を自動的に引き連れてくるからです。逆向きに \usepackage{colortbl} とだけ書くこともできますが、それだと色の名前が足りません。colortbl が内部で必要とするのは array と color の二つで、color は gray や red といった名前をほとんど定義しないため、\rowcolors{2}{gray}{white} と書いた瞬間に ! LaTeX Error: Undefined color 'gray'. で止まります。色名と混色を持ち込むのが xcolor の役目なので、実務では [table] 付きの一行に落ち着きます。
% one line brings in both xcolor and colortbl
\usepackage[table]{xcolor}beamer だけは書き方が違い、クラスオプションとして \documentclass[xcolor=table]{beamer} と渡します。色の指定には xcolor の記法がそのまま通るので、gray や red のような名前だけでなく、gray!20(濃さ 20%)や red!30!yellow(赤 30% と黄 70% の混色)も書けます。表の背景に原色を敷くと文字が読めなくなるため、名前!15 から 名前!25 くらいの薄い指定が実用的な相場です。
Option clash for package xcolor が出るとき——そして出なくなった理由
! LaTeX Error: Option clash for package xcolor. は、表の色でもっとも多く踏まれてきた地雷でした。原因は単純で、tikz・pgfplots・beamer などが先に オプション無しの xcolor を読み込んでしまい、あとから書いた \usepackage[table]{xcolor} が「同じパッケージを違うオプションで読み直した」と判定されるためです。ところが xcolor 3.00(2023 年 11 月 11 日) で事情が変わりました。このバージョンから table は読み込み時オプションではなく LaTeX の新しいキー/値機構による プリアンブル・キー として宣言されており、すでに読み込み済みの xcolor にあとから適用できます。TeX Live 2024 の環境で tikz を先に読み込んでから \usepackage[table]{xcolor} と書いても、エラーは出ません(同じ実験を geometry でやると、こちらは従来どおり Option clash for package geometry. で止まります)。
つまり、ウェブに残る「[table] はクラスオプションに移せ」という定番の助言は、いまや古い環境向けの対処法です。それでも古い TeX Live や配布物を相手にする機会は残るので、対処の順序だけ覚えておくと安全です。まずクラスオプションに移す(\documentclass[table]{article} のように書けば、誰より先に指定できます)。それでも駄目なら \usepackage{colortbl} を直接読む——衝突するのは xcolor のオプションであって colortbl ではありません。なお xcolor 3.00 の新機能が効くのは LaTeX 2022-06-01 以降 で、それより古いフォーマットでは自動的に凍結版が使われます。逆に、新しい挙動で既存文書が崩れる場合は \usepackage{xcolor}[=v2] と書けば旧バージョンを明示的に呼び戻せます。
\rowcolor・\columncolor・\cellcolor の違いと置く場所
三つは塗る範囲が違うだけでなく、書く場所が三つとも違います。\rowcolor{色} は 行の先頭——その行の最初のセルの中身より前、つまり直前の \\ の直後に置きます。\columncolor{色} は表の本文ではなく 列指定のなか に、>{\columncolor{gray!20}} の形で書きます。>{…} は array パッケージが提供する「その列の各セルの直前に中身を差し込む」仕組みで、colortbl はそこに便乗しているわけです。\cellcolor{色} だけは自由で、対象のセルの中なら どこに書いても効きます。この非対称は覚えづらいのですが、理由ははっきりしています——行は行の始まりでしか捕まえられず、列は表が始まる前にしか宣言できないからです。
三つとも引数の形は共通で、\columncolor[モデル]{色}[左の張り出し][右の張り出し] のように、色名の前に 色モデル の任意引数、うしろに 左右の張り出し(overhang) の任意引数を取れます。張り出しは色のパネルを列の左右にどこまで広げるかの指定です。右を省くと左と同じ値になり、両方を省くと tabular では \tabcolsep、array では \arraycolsep が使われます。両方を 0pt にすると、パネルは列の内容の幅ぴったりで切れます——セル間に白い筋が入るのはたいていこれが原因なので、隣り合う色をつなげたいときはむしろ張り出しを増やします。
\begin{tabular}{>{\columncolor{gray!20}}l c r}
\rowcolor{blue!30}
Item & Qty & Price \\
Apple & 3 & 380 \\
Orange & \cellcolor{yellow!40}5 & 120 \\
\end{tabular}この三点セットは一度に設計されたものではなく、二十年かけて足されていきました。colortbl の最初の草稿は 1996 年 9 月 20 日で、そこにあったのは \columncolor だけ。\rowcolor はその半月後、1996 年 10 月 5 日に加わっており、変更履歴には「S. Rahtz を喜ばせるため」と書かれています——TeX 界の大立者 Sebastian Rahtz のことです。\cellcolor に至っては五年後の 2001 年 2 月 13 日、Donald Arseneau の寄稿として入りました。それまで一つのセルを塗るには \multicolumn{1}{>{\columncolor{…}}c}{…} と書くしかなく、Carlisle はこの方式の欠点を三つ挙げています。セルの中身が色付けの発動を妨げること、列の整列指定を手で写す必要があり p{} 列では特に間違えやすいこと、そして三つめが「\multicolumn{1} はそもそも馬鹿げている」。一つのセルを塗るなら、迷わず \cellcolor です。
色が重なったらどれが勝つか——セル>行>列
\cellcolor が \rowcolor を上書きし、\rowcolor が \columncolor を上書きします——つまり セル>行>列。範囲が狭い指定ほど強い、という直感どおりの順序なので、覚え直す必要はありません。この順序があるおかげで、列全体を薄いグレーで敷き、見出しの行だけ青にし、注意を引きたいセルを一つだけ黄色にする、という三層の重ね方が競合を気にせず書けます。設計としては、広い範囲の指定を「既定値」、狭い指定を「例外」として扱う仕組みだと考えると腑に落ちます。
| 命令 | 塗る対象 | 置く場所 |
|---|---|---|
\columncolor{c} | 列全体 | 列指定の >{…} の中 |
\rowcolor{c} | 行全体 | 行の先頭(最初のセルより前) |
\cellcolor{c} | 単一セル | そのセルの中(どこでも) |
\rowcolors{n}{a}{b} | 行を交互に(縞) | 表の前に一度 |
\arrayrulecolor{c} | 以降の罫線 | 表の外・行頭・列指定の >{} |
\doublerulesepcolor{c} | 二重罫線のあいだの隙間 | \arrayrulecolor と同じ |
一行おきの縞模様を自動で作る \rowcolors
一行おきに色を変える縞模様は、表の 前 に \rowcolors{開始行}{奇数行の色}{偶数行の色} を一度書くだけで済みます。末尾の s が肝心で、s の無い \rowcolor は単独の行を塗る別の命令です。第一引数は色を付けはじめる行番号なので、見出し行を素通りさせたいなら 2 を指定します。色の引数はどちらも空にでき、空は「色なし」を意味します。ここで、検索で出てくる古い記事と食い違う点を一つ。\rowcolors はもう xcolor の命令ではありません。 2022 年 6 月 20 日の colortbl 1.0f でコードが xcolor から colortbl へ移され、xcolor 3.00 の変更履歴にも移管が明記されています。使う側の書き方は変わりませんが、\usepackage{colortbl} だけでも \rowcolors は定義されている、という現在の事実は知っておくと役に立ちます。
% start striping at row 2, so the header stays plain
\rowcolors{2}{gray!15}{white}
\begin{tabular}{l r r}
Item & Qty & Price \\
Apple & 3 & 380 \\
Orange & 5 & 120 \\
Grape & 2 & 600 \\
Peach & 4 & 450 \\
\end{tabular}縞は「全か無か」ではありません。まず \rowcolors には先頭に任意引数があり、\rowcolors[\hline]{2}{…}{…} と書けば各行の前に \hline などの命令を実行させられます。次に、自動の縞より \rowcolor や \multicolumn による個別指定のほうが優先される ので、縞の途中の一行だけを別色にするのは自然に書けます。そして縞そのものを一時的に止めたいときのために \hiderowcolors と \showrowcolors があり、表の途中に置けば、そこから先の縞を消したり再開したりできます。合計行だけ縞から外したい、といった要求はこれで片づきます。
罫線に色を付ける——\arrayrulecolor と \doublerulesepcolor
\hline・\cline・縦罫線 | の色は \arrayrulecolor{色} で変えます。\color と同じ引数を取り、表の外・行の先頭・列指定の >{} のいずれにも置ける 大域的な宣言 です。ここで一つ落とし穴があります。表の途中で指定した場合、効くのはそれ以降に指定された罫線だけ で、列指定の段階ですでに宣言済みの縦罫線は元の色のまま残ります。大域宣言なので表を抜けても効き続ける点にも注意が必要で、以降の表を巻き込みたくなければ \arrayrulecolor{black} を改めて宣言して戻します。
|| や \hline\hline が作る 二重罫線のあいだの隙間 は、既定では白いままです。ここも塗るには、隙間の幅を決める長さ \doublerulesep とあわせて \doublerulesepcolor{色} を使います。ただしこの命令を使うと、longtable はページ境界で \hline\hline のあいだの空きを 捨てられなくなります。TeX は空き(glue)を捨てる仕組みを持っていますが、色を付けた「空き」は実際には第三の罫線であって、罫線は空きほど簡単には捨てられないからです。長い表をページ送りさせる予定があるなら、この一点は先に知っておくほうが安全です。
\setlength\arrayrulewidth{1pt}\arrayrulecolor{blue}
\setlength\doublerulesep{2pt}\doublerulesepcolor{yellow}
\begin{tabular}{||l|c||}
\hline\hline
one & two \\
three & four \\
\hline\hline
\end{tabular}
\arrayrulecolor{black} % global: reset, or later tables inherit it縦罫線を一本だけ色付けしたいなら、専用の命令を持ち出さずに | の代わりに !{\color{green}\vline} を列指定へ差し込む手があります。細かい話ですが \arrayrulewidth にも触れておくと、これは罫線の太さを決める長さで、既定の細さのまま色を付けると線がひどく弱く見えます。黒なら十分だった太さが、明るい色にした途端に紙面から消える——色を付けたら少し太くする、と覚えておくと見栄えが安定します。
\cline が見えない——線が色パネルの裏に隠れるとき
\rowcolor を敷いた表で \cline を引くと、線は まったく見えなくなります。バグではなく、冒頭で触れた仕組みの必然です。colortbl は色を パネルとしてセルのうしろに 敷くのに対し、\cline はそのパネルよりさらに奥に描かれるため、上から色で覆われてしまいます。Carlisle はソース中のコメントで、\cline は色付き表では実質的に機能しないと認めたうえで、「せめて見える部分だけは正しい色にしておく」と書いています。回避策ははっきりしていて、\cline の代わりに hhline パッケージ を読み込み、\hhline{-~} のように書きます。- が線を引く列、~ が飛ばす列です。これなら線はパネルの上に描かれ、ちゃんと見えます。
% \cline{1-1} would vanish behind the panel; \hhline draws on top
\usepackage{hhline}
...
\begin{tabular}{ll}
\rowcolor{blue!40} one & two \\
\hhline{-~}
\rowcolor{blue!40} three & four \\
\end{tabular}booktabs と併用すると罫線と背景色のあいだに白い隙間ができる
colortbl と booktabs は問題なく併用できますが、\toprule・\midrule・\bottomrule と背景色のあいだに 白い帯 が残ります。原因は booktabs が罫線の上下に入れる空きで、既定値は \aboverulesep が .4ex、\belowrulesep が .65ex です。この空きは行のボックスの外側にあるため、\rowcolor のパネルが届きません。塗りを罫線まで届かせたいときの定石は、二つの空きを 0pt にし、失われた分を \extrarowheight に移し替えることです。行の高さは保たれたまま、色だけが罫線に接します。
% let the row color reach the booktabs rules
\setlength\aboverulesep{0pt}
\setlength\belowrulesep{0pt}
\setlength\extrarowheight{.75ex}もう一つの定番の症状は、大きな文字や背の高い中身が、すぐ上の \hline や色パネルの上端に接触する ことです。colortbl はそもそも罫線の幅を決めるためにセルを一つひとつ箱に入れて measure しているので、ついでにと用意されたのが長さ \minrowclearance です。\setlength\minrowclearance{2pt} のように設定すると、背の高い行の上にだけ少し余白が入ります。ただし Carlisle 自身は、行間を揃えたまま解決できる \extrarowheight や \arraystretch を先に増やすほうがよいと書いています。大文字の高さにこの値を足したものが通常の行の高さを超えると、行送りが目に見えてガタつくためです。
最後に、そもそも色を使うべきかという問いを置いておきます。booktabs を書いた Simon Fear の立場は明快で、良い表は 余白と数本の横罫線 で読ませるものであり、縦罫線は決して使わない、二重罫線も使わない、の二点を守れば大きく外さない、というものでした。彼は値を並べた「formal table(正式な表)」と、アイコンを散らし色も使うであろう「tableau」を区別し、前者のレイアウトは何世紀もの経験で確立しているのだから、めったなことで変えるべきではないと述べています。ちなみに booktabs のバージョン番号は 1.61803398——黄金比 φ に収束していく、という作者の遊びです。表に色を敷く前に、行の高さと罫線の本数だけで解けないかを一度疑ってみる価値はあります。