[Tex/LaTex] Gradient color in one cell of a table

colortables

I'm trying to create a tabular and I'm facing the following small issue.

I would like to make the background of one cell a gradient color. Is it easy to do that in LaTeX? And if so, how to do it?

Best Answer

Here's one option using the improved version of \tikzmark exposed by Andrew Stacey in his answer to tikzmark to have different behaviour if first run (and mark locations not yet available). The idea is to use \multicolumn and the !{...} syntax from the array package to place the marks at the beginning and at the end of the cell; then \shade (from the TikZ package) was used to place the shade.

A little example showing some shading effects (one of them using the shadings library) when having various cells associated to the different column types (l,c, p{<length>} and merged cells):

\documentclass[10pt]{article}
\usepackage[margin=2cm]{geometry} % just for the example 
\usepackage[frenchb]{babel} 
\usepackage[table]{xcolor} 
\usepackage{array}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{calc,shadings}

% Andrew Stacey's code from
% https://tex.stackexchange.com/a/50054/3954
\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] {#1;}}
\makeatother
% end of Andrew's code

\newcommand\ShadeCell[4][0pt]{%
  \begin{tikzpicture}[overlay,remember picture]%
    \shade[#4] ( $ (pic cs:#2) + (0pt,2ex) $ ) rectangle ( $ (pic cs:#3) + (0pt,-#1*\baselineskip-.8ex) $ );
  \end{tikzpicture}%
}%

\begin{document}

\ShadeCell[14]{start1}{end1}{%
  shading=color wheel white center,opacity=.15}
\ShadeCell{start2}{end2}{%
  left color=red!20,right color=green!20}
\ShadeCell[13]{start3}{end3}{%
  top color=green!20,bottom color=red!20}
\ShadeCell{start4}{end4}{%
  left color=blue!20,right color=green!20}

\begin{tabular}{| l | p{6cm} | c |}
\hline
Uncolored cell 
  & \multicolumn{1}{!{\tikzmark{start1}} p{6cm} !{\vrule\tikzmark{end1}}}{\lipsum*[2]} 
  & Uncolored cell \\
\hline
\multicolumn{1}{!{\vrule\tikzmark{start2}} l !{\vrule\tikzmark{end2}}}{Another colored cell} 
  & Another uncolored cell & Another uncolored cell \\
\hline
Uncolored cell 
  & \lipsum[4] 
  & \multicolumn{1}{!{\tikzmark{start3}} c !{\vrule\tikzmark{end3}}}{Another colored cell} \\
\hline
\multicolumn{2}{!{\vrule\tikzmark{start4}} c !{\vrule\tikzmark{end4}}}{Another merged colored cell}
  & Uncolored cell \\
\hline
\end{tabular}

\end{document}

enter image description here

A brief explanation on how to use the code

For each cell that will receive the shading you need to do the following:

  1. Use \multicolumn{<number of columns>}{<format specification>}{<text>} specifying the second argument in the form

    !{\tikzmark{<name1>}} <format> !{tikzmark{<name2>}}
    

    where <name1> and <name2> can be quite arbitrary strings not previously used; I suggest using something like start<number>, end<number>, but you can use any other strings (valid for naming nodes in TikZ). If you need to add vertical rules to the cell, you must use \vrule inside !{...}; for example, to have vertical rules on both sides of the cell you can say

    !{\vrule\tikzmark{<name1>}} <format> !{\vrule\tikzmark{<name2>}}
    
  2. Use the \ShadeCell command in the following way:

    \ShadeCell{<name1>}{<name2>}{<shade specification>}
    

    where <name1> and <name2> are the strings you used in the previous step, and <shade specification> is a valid shade according to TikZ syntax. If the contents of the cell spans more than one line (when using a p{<length>} columns, for example), then you can use the optional argument of \ShadeCell with the proper value to make the shade cover the cell vertically; for example; if the text of the cell spans 5 lines then you need to use something like

    \ShadeCell[4]{<name1>}{<name2>}{<shade specification>}
    

    (The optional argument is the number n-1, where n is the number of lines that the text spans).

Related Question