15

When using \cellcolor in a booktabs table, I find that the output is not really appealing:

Table

I don't really care that the colored cell does not touch the lines above and below (cf. Coloring columns in a table with colortbl and booktabs), but what I find ugly is that the \cellcolor command looks bad in combination with the shortened \midrule of its header. I was originally going to ask how to simply shorten the \cellcolor in a similar way, but I guess the output would still not be very appealing since the 3 would not be centered in its background anymore.

So, here's the more basic question: what is a best practice here to make things look appealing? I do like the booktabs style, and I have a few tables in which I'd like to highlight some cells. Note that I'm not dead set on using backgrounds for the highlighting, but I can't think of a better means: using bold seems to communicate that the highlighted values are more important (while in fact they are error cases), using italics they'd be too little obvious.

Here is the corresponding MWE:

\documentclass{article}

\usepackage{booktabs}
\usepackage{colortbl}

\begin{document}

 \begin{tabular}{ccccc}
    \toprule
        \multicolumn{2}{c}{a} & \multicolumn{3}{c}{b} \\
    \cmidrule(lr){1-2}\cmidrule(lr){3-5}
        1 & 2 & \cellcolor[gray]{0.9}3 & 4 & 5 \\
    \bottomrule
\end{tabular}

\end{document}
2
  • Is not trimming the \cmidrules in question an option for you? For instance, in the example you give, could you live with issuing the commands \cmidrule(r){1-2}\cmidrule{3-5}, which will trim the first cmidrule on the right and leave the length of the second cmidrule unchanged?
    – Mico
    Nov 8, 2013 at 11:10
  • @Mico: if possible, I'd like to keep the trimming of the mid rules consistent; in the example above, it seems strange to me that a's mid rule would be trimmed while b's would not be.
    – rainer
    Nov 8, 2013 at 11:19

2 Answers 2

17

\cellcolor adds padding to ensure adjacent cell backgrounds are touching each other. I believe you don't need \cellcolor at all.

\documentclass{article}

\usepackage{booktabs}
\usepackage{xcolor}

\makeatletter
\newcommand{\ccell}[3][]{%
  \kern-\fboxsep
  \if\relax\detokenize{#1}\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\colorbox{#2}}%
  {\colorbox[#1]{#2}}%
  {#3}\kern-\fboxsep
}
\makeatother
\definecolor{cellgray}{gray}{0.9}
\AtBeginDocument{\setlength{\cmidrulekern}{0.3em}}

\begin{document}

\begin{tabular}{ccccc}
\toprule
\multicolumn{2}{c}{a} & \multicolumn{3}{c}{b} \\
\cmidrule(lr){1-2}\cmidrule(lr){3-5}
1 & 2 & \ccell[gray]{0.9}{3} & 4 & 5 \\
1 & 2 & \ccell{cellgray}{3} & 4 & 5 \\
\bottomrule
\end{tabular}

\end{document}

The two \kern commands make TeX thinking the default padding of \colorbox has not been added to the cell's width. Changing a bit the amount of trimming from \cmidrule ensures the mid rules cover the colored cell.

Note that the syntax of \ccell allows for directly specifying a color or also using a defined color.

enter image description here

The definition of \ccell can be simplified into

\makeatletter
\protected\def\ccell#1#{%
  \kern-\fboxsep
  \@ccell{#1}%
}
\def\@ccell#1#2#3{%
  \colorbox#1{#2}{#3}%
  \kern-\fboxsep
}
\makeatother
3
  • Thanks, I like the simplicity of this solution. However, this approach "breaks" if some of the cells with background have text of different lengths: the gray background will only cover the text's length, not that of the whole cell. Is there a way to improve that?
    – rainer
    Nov 11, 2013 at 14:28
  • @rainer I'm afraid not.
    – egreg
    Nov 11, 2013 at 14:56
  • Ok, I thought so. Thanks anyway :)!
    – rainer
    Nov 11, 2013 at 15:04
10

There's also the usual tikzmark approach:

\documentclass{article}

\usepackage{booktabs,colortbl}
\usepackage{xparse}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\newcommand{\fillcol}{gray!50}
\newcommand{\bordercol}{white}
\pgfkeys{/tikz/.cd,
      set fill color/.code={\renewcommand{\fillcol}{#1}},
      set border color/.code={\renewcommand{\bordercol}{#1}},
      left offset/.store in=\leftoff,
      right offset/.store in=\rightoff,
      above offset/.store in=\aboveoff,
      below offset/.store in=\belowoff,
      left offset=-0.02,
      right offset=0.12,
      above offset=0.325,
      below offset=-0.1,
      below right offset/.store in=\belowrightoff,
      below right offset={\rightoff,\belowoff},
      above left offset/.store in=\aboveleftoff,
      above left offset={\leftoff,\aboveoff},
}%

\NewDocumentCommand{\tikzmarkin}{o m D(){\belowrightoff} D(){\aboveleftoff}}{%
    \IfNoValueTF{#1}{%true
      \tikz[remember picture,overlay]
      \draw[line width=1pt,rectangle,fill=\fillcol,draw=\bordercol]
      (pic cs:#2) ++(#3) rectangle (#4)
      ;}
      {%false
      \tikz[remember picture,overlay]
      \draw[line width=1pt,rectangle,fill=\fillcol,draw=\bordercol,#1]
      (pic cs:#2) ++(#3) rectangle (#4)
      ;
      }
}      


\newcommand\tikzmarkend[2][]{%
\tikz[remember picture with id=#2] #1;}

\begin{document}

 \begin{tabular}{ccccc}
    \toprule
        \multicolumn{2}{c}{a} & \multicolumn{3}{c}{b} \\
    \cmidrule(lr){1-2}\cmidrule(lr){3-5}
        1 & 2 & \tikzmarkin{a}3\tikzmarkend{a} & 4 & \tikzmarkin[above left offset={0.15,0.325}, below right offset={0.05,-0.1},set fill color=red!80]{b}5\tikzmarkend{b} \\
    \bottomrule
\end{tabular}

\end{document}

Similarly to hf-tikz, there are styles to change width of the highlighted area. One might change left, right, above, below offsets or the combined above leftor below right offsets. An example is given looking on the way in which 5 has been highlighted. Via offsets the user has the complete control over the highlighting area size.

The result:

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .