12

I am trying to figure out the best way of nesting tikz nodes having a different background color. I would like the "inner" nodes to "win" concerning the background color. Currently the "outer" node ("fit") always "wins". Is there maybe a better way to aproach this?

A simple example: Nesting an inner node with background color red within an outer node with background color blue:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}
% \begin{tikzpicture}%
%   \node (inner) [draw] {foo-inner};%
%   \node (outer) [draw,fit=(inner)] {};%
% \end{tikzpicture}%
% \begin{tikzpicture}%
%   \node (inner) [draw,fill=red] {foo-inner};%
%   \node (outer) [draw,fit=(inner)] {};%
% \end{tikzpicture}%
\begin{tikzpicture}%
  \node (inner) [draw,fill=red] {foo-inner};%
  \node (outer) [draw,fill=blue,fit=(inner)] {};%
\end{tikzpicture}%
\end{document}%
1
  • One way would be to add fill opacity as in \node (outer) [draw,fill=blue,fit=(inner),fill opacity=0.5] {};, or simply reverse the order. Jan 22, 2012 at 23:30

3 Answers 3

15

You can also try to send the fitting node to the background layer

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,backgrounds}
\begin{document}
\begin{tikzpicture}%
  \node (inner) [draw,fill=red] {foo-inner};%
  \node (inner2) [draw,fill=green] at (2,2) {foo-inner2};%
\begin{scope}[on background layer]
  \node (outer) [draw,fill=blue,fit=(inner) (inner2)] {};%
\end{scope}
\end{tikzpicture}%
\end{document}

enter image description here

3

Note that this is more of hack:

If you reverse the order this "appears" (see Note below) to yield desired results:

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}
\begin{tikzpicture}%
  \node (inner) [draw,fill=red,fill] {foo-inner};%
  \node (outer) [draw,fill=blue,fit=(inner)] {};%
\end{tikzpicture}%
\begin{tikzpicture}%
  \node (outer) [draw,fill=blue,fit=(inner)] {};%
  \node (inner) [draw,fill=red,fill] {foo-inner};%
\end{tikzpicture}%
\end{document}%

Note:

As Jake correctly points out the above solution works only because the first tikzpicture. So, just reversing the order won't work in general. But, you could repeat the node you want at the top:

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}
\begin{tikzpicture}%
  \node (inner) [draw,fill=red,fill] {foo-inner};%
  \node (outer) [draw,fill=blue,fit=(inner)] {};%
  \node (inner) [draw,fill=red,fill] {foo-inner};%
\end{tikzpicture}%
\end{document}%
2
  • 1
    Hm, I think the second example only works because you have the first example in the same document. Try changing the text of the inner node in the second example to something longer, or removing the first tikzpicture.
    – Jake
    Jan 22, 2012 at 23:40
  • @Jake: Thank you so much for pointing this out. Wondering if I should delete this. Jan 23, 2012 at 1:49
0

This is the solution from the pgfmanual.pgf:

\documentclass[border=1pt, tikz]{standalone}

\usetikzlibrary{fit, backgrounds} 

\begin{document}

\begin{tikzpicture}[level distance=8mm]
    \node (root) {root}
        child { node (a) {a} }
        child { node (b) {b}
            child { node (d) {d} }
            child { node (e) {e} } }
        child { node (c) {c} };

    \begin{pgfonlayer}{background}
        \node[fill=red!20,inner sep=0pt,circle,fit=(root) (b) (d) (e)] {};
        \node[fill=blue!20,inner sep=0pt,circle,fit=(b) (c) (e)] {};
    \end{pgfonlayer}
\end{tikzpicture}

\end{document}

If you use many nested nodes, take a look to pgfdeclarelayer and pgfsetlayers.

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

This will define two additional layers and set their order.

You must log in to answer this question.

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