20

In TikZ, there are draw=none and fill=none options to turn off stroking and filling operations. However, there doesn't appear to be a corresponding text=none option. If I try \tikz \node[text=none] {X};, I get the error message "Package xcolor Error: Undefined color `none'." (The text=red option does work as expected.)

  • Is there indeed no text=none option?
  • What are alternatives? Is it reasonable to use text opacity=0, or is there something better?

I'm asking because I would like to create an "empty" node of the same size as a given image or text. By referencing the anchors of this "empty" node, I can then animate the image or text moving in to occupy the same space. The following is an example of what I'm trying to accomplish. It uses text opacity=0 based on @percusse's suggestion.

\documentclass{minimal}
\usepackage{animate}
\usepackage{tikz}

\usetikzlibrary{calc}

\begin{document}

\begin{animateinline}[autoplay,loop]{10}
  \multiframe{11}{iframe=0+1}{
    \begin{tikzpicture}[every node/.style={draw}]
      \node[text opacity=0] (source) {Text};
      \node[text opacity=0] (target) at (2,2) {Text};

      \node at ($(source)!\iframe/10!(target)$) {Text};
    \end{tikzpicture}
  }
\end{animateinline}

\end{document}
  • Given this ultimate goal, is it preferable to use something like \node {\phantom{Text}};?
4
  • Are you basically just trying to set the size of the node, and you're using some text string to achieve this? In that case it's best to just use options like minimum width, and inner sep, as percusse said, instead of fiddling around with strings of text that have the right size.
    – Jake
    Jun 10, 2012 at 21:40
  • @Jake I've edited my post with an example. Jun 10, 2012 at 21:57
  • Ah yes, thanks! In that case, I think the text opacity key is the most practical.
    – Jake
    Jun 10, 2012 at 21:59
  • The only difference I can see is the text selection in the resulting .pdf. Opacity leaves the text selectable but \phantom doesn't.
    – percusse
    Jun 10, 2012 at 22:07

5 Answers 5

14

If you don't need the text then it shouldn't be there anyway. Either you enlarge the node with minimum width,height,inner sep etc. or you can use the text opacity key comfortably.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[text opacity=0,draw=red,fill=yellow!25] (a) {Text};
\end{tikzpicture}
\end{document}

enter image description here

If you also need some placeholder for a text, you can go slightly esoteric and get the width depth height info beforehand e.g. just for the width;

\begin{tikzpicture}
\pgfmathparse{width{"Text"}}
\edef\mywidth{\pgfmathresult}
\node[minimum width=\mywidth pt,draw=red,fill=yellow!25] (a) {};
\end{tikzpicture}
11
  • 1
    @percusse Should text opacity=0 be preferred over using \phantom? Jun 10, 2012 at 21:39
  • @HenryDeYoung Opacity solution does not get complicated if you make the node text \large etc. but you have to somehow send those font adjustments into the \phantom command say when the node is scaled etc. it may be a little more tedious in terms of code flexibility but I can't think of any obvious big reason for preference.
    – percusse
    Jun 10, 2012 at 21:53
  • @Jake I was wondering about the image inclusion detail but indeed I don't see any reason why not to use.
    – percusse
    Jun 10, 2012 at 21:54
  • text opacity=0 might not be the best option when you want to print it. I once had the following issue: the text of my nodes was not visible in the pdf, but small parts of them appeared in the printed version. I "solved" the issue by setting the text color to the background color. Jun 11, 2012 at 0:00
  • 1
    With text opacity=0, the text is always included in PDF: you can copy it. So, \phantom seems best in terms of confidentiality. Jun 11, 2012 at 0:40
14

you can use \phantom{Text}

\documentclass{standalone}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
\node[draw=red,fill=yellow!25] (a) {\phantom{Text}};
\end{tikzpicture}
\begin{tikzpicture}
\node[draw=red,fill=yellow!25] (a) {{Text}};
\end{tikzpicture}

\end{document}

enter image description here

1
  • Just to note - unfortunately, \phantom doesn't work for multiline text: e.g. \node[draw=red,fill=yellow!25,align=center] (a) {\phantom{Text\\Test}}; will fail with ! Extra }, or forgotten \endgroup.
    – sdaau
    Apr 4, 2014 at 21:30
9

If one wants a true “phantom” text node (i.e. no selectable text in the resulting PDF) and doesn’t want to manually provide the \phantom macro, one can use one of the following solutions:

  1. Using the undocumented keys execute at begin node and execute at end node one can use the lrbox environment (or manually with \setbox) a box which is then used inside \phantom:

    execute at begin node = \begin{lrbox}{\pgfutil@tempboxa},
    execute at end node   = \end{lrbox}\phantom{\usebox\pgfutil@tempboxa}
    

    This works very well for one-liner nodes and also (I assume) for multiparted nodes. Problems arise when the text width key is used because the needed minipage environment is setup outside of the stuff that is given to execute at begin/end node. (Obviously, we could just mimic this ourselves with a minipage and things from TikZ’ original setup).

  2. After TikZ puts the text between { and } in a box it checks the values of the keys text width, text depth and text height and corrects the box measures accordingly. After transformation, the node is created via the \pgfnode macro. We can intercept this here with the following setup (and a little help from etoolbox):

    \usepackage{etoolbox}
    \patchcmd\tikz@fig@continue{\tikz@node@transformations}{%
      \iftikz@node@phantom
        \setbox\pgfnodeparttextbox\hbox{%
          \vrule height\ht\pgfnodeparttextbox depth\dp\pgfnodeparttextbox width0pt%
          \vrule height0ptdepth0ptwidth\wd\pgfnodeparttextbox}%
      \fi\tikz@node@transformations}{}{}
    

    This would simply overwrite the \pgfnodeparttextbox with rules that are exactly the width, height and depth of the original \pgfnodeparttextbox (just as \phantom would do).

    Personally, I prefer this solution, combined with the following keys/conditional, that also provides (besides the text=none syntax) a key phantom.

    \newif\iftikz@node@phantom
    \tikzset{
      phantom/.is if=tikz@node@phantom,
      text/.code=%
        \edef\tikz@temp{#1}%
        \ifx\tikz@temp\tikz@nonetext
          \tikz@node@phantomtrue
        \else
          \tikz@node@phantomfalse
          \let\tikz@textcolor\tikz@temp
        \fi}
    
  3. Another option can be used with the upcoming version of TikZ which provides a node contents key. We can create a key that takes its argument and passes it to node contents encompassed in a \phantom. This will only work for one-liners.

    Phantom/.style={node contents=\phantom{#1}}
    

Code

\documentclass[tikz]{standalone}
\makeatletter
\newif\iftikz@node@phantom
\tikzset{
  phantom/.is if=tikz@node@phantom,
  text/.code=%
    \edef\tikz@temp{#1}%
    \ifx\tikz@temp\tikz@nonetext
      \tikz@node@phantomtrue
    \else
      \tikz@node@phantomfalse
      \let\tikz@textcolor\tikz@temp
    \fi,
  Phantom/.style={node contents=\phantom{#1}},% only CVS, only single line
  PHantom/.style={
    execute at begin node=\setbox\pgfutil@tempboxa\hbox\bgroup,
    execute at end node=\egroup\phantom{\usebox\pgfutil@tempboxa}}
}
\usepackage{etoolbox}
\patchcmd\tikz@fig@continue{\tikz@node@transformations}{%
  \iftikz@node@phantom
    \setbox\pgfnodeparttextbox\hbox{%
      \vrule height\ht\pgfnodeparttextbox depth\dp\pgfnodeparttextbox width0pt%
      \vrule height0ptdepth0ptwidth\wd\pgfnodeparttextbox}%
  \fi\tikz@node@transformations}{}{}
\makeatother
\begin{document}
\tikz[nodes={draw, text width=2cm}]\path
  node[green]        {Text text text text text text text}
  node[PHantom, red] {Text text text text text text text};
\foreach \iframe[evaluate={\iframe=\iframe/10}] in {0,...,10}{
\begin{tikzpicture}[nodes=draw]
  \node[text=none] (source)                  {Text};
  \node[phantom]   (target) at (2,2)         {Text};
  \node[gray]               at (1,1) [Phantom=Text];

  \path (source.center) -- node[pos=\iframe] {Text} (target.center);
\end{tikzpicture}}
\end{document}
5

And why not : text = yellow!25 ?

and like Andrew wrote in his comment : \node[yellow!25,fill,draw=red] (a) {Text}; in this case, you set the colors for text, draw and fill.

draw and fill are different options. If you don't use these options, by default the shape is not draw and not filled but with text (it's equivalent to draw=false), the text is always displayed and by default the color used is black.

If you write \node[name=s] (a) {Text}; the name of the node is a, if it was possible to write \node[text=none] (a) {Text}; the text will be Text. text is a color; if you want you can define : \definecolor{none}{rgb}{1,1,1} and it's possible to define none to be the fill color.

\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[text=yellow!25,draw=red,fill=yellow!25] (a) {Text};
\end{tikzpicture}
\end{document}
2
  • 3
    Or \node[yellow!25,fill,draw=red] (a) {Text}; as a colour by itself sets all three colours to it (text,fill, and draw). This makes it easier to modify later as there's only one colour to change. Jun 11, 2012 at 7:21
  • yes Andrew you are right. I updated my answer. Jun 11, 2012 at 7:39
0

I ran into this issue when using this wonderful hint for easily combining beamer overlays and options passed to tikz commands and looking to avoid duplicating overlay specifications. For this purpose setting text opacity to 0 is fine. Using the command described in the hint we can compare doing this with text opacity.

\node [temporal=<2>{Bres}{text opacity=0}{resdone}] {\( \phi^A_{i,s}(x) \) };

As opposed to what is required to also do it the `right way' and just change the node text.

\node [temporal=<3-6>{Bres}{text opacity=0}{resdone}] { \only<1-2,7->{\( \phi^A_{i,s}(x) \)} };

You must log in to answer this question.

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