1

I have two TikZ nodes in my paper. I want to have a color rectangle behind both of them, while I don't how to implement.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,backgrounds,fit}
\begin{document}
  % my first (unsuccessful) try
  % \begin{tikzpicture}[remember picture,overlay]
  %   \node[fit=(a)(b),fill=yellow] {}; 
  %            % ^--^-- undefined a and b
  % \end{tikzpicture}

  \begin{itemize}
    \item 
      \begin{tikzpicture}[remember picture]
        \node[rectangle,draw] (a) {a};
      \end{tikzpicture}
    \item
      \begin{tikzpicture}[remember picture]
        \node[rectangle,draw] (b) {b};
        % my second (unsuccessful) try
        % \begin{scope}[on background layer,overlay]
        %   \node[fit=(a)(b),fill=yellow] {};
        % \end{scope} 
      \end{tikzpicture} 
  \end{itemize}
\end{document}

I made two tries:

  • Draw the color rectangle first: failed because the two nodes weren't defined yet
  • Draw the color rectangle in the background layer: failed because background layer doesn't seem to work between different tikzpicture environments.
  • Can't you put them in the same picture? – cfr Aug 20 '17 at 22:25
2

If you must have separate pictures and your needs are very simple, then you can change the blend mode and it will look the same as if you'd put the rectangle behind. However, you are not really putting anything behind using this method, so this cannot be expected to work in other cases.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,fit}
\begin{document}
  \begin{itemize}
    \item
      \begin{tikzpicture}[remember picture]
        \node[rectangle,draw] (a) {a};
      \end{tikzpicture}
    \item
      \begin{tikzpicture}[remember picture]
        \node[rectangle,draw] (b) {b};
        \begin{scope}[blend mode=overlay,overlay]
          \node[fit=(a)(b),fill=yellow] {};
        \end{scope}
      \end{tikzpicture}
  \end{itemize}
\end{document}

simple solution with <code>blend mode</code>

For more complex cases, either put everything in a single tikzpicture environment or, if you absolutely cannot do that, you need to look into PDF layers, I think. However, that's a whole different set of problems, so I would not go there unless absolutely necessary. In particular, I wouldn't go there just to keep the different pictures as distinct items in a list. Working around the issue or giving up on the desiderata are likely to be much happier and more reasonable solutions.

A better solution for more complex cases might be something like the following.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,backgrounds,fit}
\begin{document}
  \begin{tikzpicture}
    [my node/.style={draw, anchor=mid west} ]
    \node [my node] (a) {a};
    \node [my node, below=\baselineskip{} of a] (b) {b};
    \scoped[on background layer]{\node [fit=(a)(b), fill=yellow] {};}
    \node (ab) [left=2.5pt of current bounding box.west |- a.mid] {\textbullet};
    \node at (ab |- b.mid) {\textbullet};
  \end{tikzpicture}
\end{document}

background solution

| improve this answer | |
  • Wow! It works. My needs are actually quite simple. Thank you very much. – Tianren Liu Aug 20 '17 at 22:36
  • @TianrenLiu blend mode is very underused. Some of the options don't work correctly in all PDF viewers. However, overlay works fine in Okular, which isn't terribly compliant, as these things go, so should be reasonably safe. As I say, just remember that it is not really behind the nodes so if you put a picture or something there, it will block them from view. – cfr Aug 20 '17 at 22:47
0

Another solution for the simple case. In this case it's possible to draw each node with its own background, and later on (with another tikzpicture) fill the gap between nodes.

It's important that all nodes have a similar width and fit nodes have outer sep=0pt.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,backgrounds,fit}

\begin{document}
  \begin{itemize}
    \item 
      \begin{tikzpicture}[remember picture]
        \node[minimum size=7mm, draw] (A0) {a};
        \begin{scope}[on background layer]
            \node[fit=(A0), fill=yellow, outer sep=0pt] (A1) {};
         \end{scope}
      \end{tikzpicture}
    \item 
      \begin{tikzpicture}[remember picture]
        \node[minimum size=7mm, draw] (B0) {b};
        \begin{scope}[on background layer]
            \node[fit=(B0), fill=yellow, outer sep=0pt] (B1) {};
         \end{scope}
      \end{tikzpicture}
  \end{itemize}
  \begin{tikzpicture}[remember picture, overlay]
        \fill[yellow] (A1.south west) rectangle (B1.north east);
  \end{tikzpicture}
\end{document}

enter image description here

As an alternative to a regular node with a fit node on background it's possible to use a matrix node:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,backgrounds,fit, matrix}

\tikzset{%
    mymatrix/.style={%
        matrix of nodes,
        nodes={minimum size=7mm, draw},
        fill=yellow,
        outer sep=0pt,
    }
}

\begin{document}
  \begin{itemize}
    \item 
      \begin{tikzpicture}[remember picture]
        \matrix[mymatrix] (A) {a\\};
      \end{tikzpicture}
    \item
      \begin{tikzpicture}[remember picture]
        \matrix[mymatrix] (B) {b\\};
      \end{tikzpicture} 
  \end{itemize}
  \begin{tikzpicture}[remember picture, overlay]
        \fill[yellow] (A.south west) rectangle (B.north east);
  \end{tikzpicture}
\end{document}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.