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?
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?
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}

For each cell that will receive the shading you need to do the following:
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>}}
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).
tikzmark, but somehow my sense of proportionality is violated ;-)
– Stephan Lehmke
Jun 10 '12 at 04:46
\documentclass{article} \usepackage{tikz} \begin{document} \pgfversion \end{document}. If your version is older, update your system.
– Gonzalo Medina
Jun 10 '12 at 14:06
french option for babel you need to use \newcommand\tikzmark[1]{% \tikz[overlay,remember picture,baseline] { \node [anchor=base] (#1) {}; }} (notice the extra pair of braces) in the first code (since the french option makes ; active).
– Gonzalo Medina
Jun 10 '12 at 21:48
\multicolumn like that; in my code there's an example on how rules can be added. If doubts persist, the follow-up question seens again the best option.tabular inside a table environment it looks like the shading overwrites the actual text.Is there a fix for that?
– bonanza
Feb 25 '16 at 13:26
How about this?
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
\matrix (A) [matrix of nodes,
row 2 column 2/.style={ nodes = { top color=blue!20, bottom color=red!20 }}]
{
A & B & C \\
D & E & F \\
G & H & I \\
};
\end{tikzpicture}
\end{document}
This will produce

Added: If you need the full power of tabular, you're better off with Gonzalo's solution, especially since it looks much cleaner now. It is however possible to emulate at least some of the things you're asking for. Here's an updated example with fake l, r and c columns. (With manually set widths. It's probably possible to get automatic widths with some more work.) I also added a few lines and an ugly multicol hack.
Of course, once you start to add more and more, you soon end up with code that's at least as complicated as Gonzalo's.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix,calc}
\begin{document}
\begin{tikzpicture}
\matrix (A) [matrix of nodes, nodes in empty cells,
text height=9pt, text depth = 1pt,
row 3 column 1/.style={
nodes = { top color=green!20, bottom color=red!20 }},
row 2 column 2/.style={
nodes = { left color=blue!20, right color=red!20 }},
row 1 column 3/.style={
nodes = { top color=blue!20, bottom color=red!20 }},
column 1/.style={ text width=15mm, align=left },
column 2/.style={ text width=15mm, align=right },
column 3/.style={ minimum width=20mm} % centered!
]
{
Lorem & ipsum & dolor \\
sit & amet & consectetur \\
adipiscing& {} & {} \\
};
% Draw some lines
\draw (A-1-1.north east) -- (A-3-1.south east);
\draw[thick, dotted] (A-2-2.south west) -- (A-2-3.south east) -- (A-1-3.north east);
% Faked multicolumn
\node[text height=9pt,text depth=1pt] at ($(A-3-2)!0.50!(A-3-3)$) { Multicol text here };
\end{tikzpicture}
\end{document}

With {NiceTabular} of nicematrix. This environment is similar to the classical environment {tabular} (of array) but creates PGF/Tikz nodes under the cells, rows and columns.
It's possible to use these nodes with Tikz to put whatever Tikz construction you want before the array.
\documentclass[10pt]{article}
\usepackage[margin=2cm]{geometry}
\usepackage{xcolor}
\usepackage{nicematrix,tikz}
\usetikzlibrary{shadings}
\begin{document}
\begin{NiceTabular}{cccc}
\CodeBefore
\tikz \shade [shading=color wheel white center,opacity=0.5] (2-|2) rectangle (6-|4) ;
\Body
un & deux & trois & quatre \
cinq & six & sept & huit \
neuf & dix & onze & douze \
treize & quatorze & quinze & seize \
dix-sept & dix-huit & dix-neuf & vingt \
vingt et un & ving-deux & vingt-trois & vingt-quatre
\end{NiceTabular}
\end{document}
You need several compilations (because nicematrix uses PGF/Tikz nodes under the hood).
Since the version 6.0, it's also possible to use the key tikz of the command \Block.
\documentclass[10pt]{article}
\usepackage[margin=2cm]{geometry}
\usepackage{xcolor}
\usepackage{nicematrix,tikz}
\usetikzlibrary{shadings}
\begin{document}
\begin{NiceTabular}{cccc}
un & deux & trois & quatre \
cinq & \Block[tikz={shading=color wheel white center,opacity=0.5}]{4-2}{}
six & sept & huit \
neuf & dix & onze & douze \
treize & quatorze & quinze & seize \
dix-sept & dix-huit & dix-neuf & vingt \
vingt et un & ving-deux & vingt-trois & vingt-quatre
\end{NiceTabular}
\end{document}
The output is the same.