# tikz nodes: centering with small font

I am trying to create tikz nodes with centered text, but changing fontsize. Unfortunately, while normally-sized text is nicely centered inside the nodes, the smaller text is not centered, but shifted to the left.

After all I read, I think this might happen because the axis around which is centered is computed from the normal font, but I did not find a workaround or solution to this until now.

The following example illustrates the effect:

\documentclass{scrbook}

\usepackage{tikz}
\usetikzlibrary{shapes,chains,scopes,positioning,arrows}
\tikzstyle{block} = [draw, rectangle, rounded corners, very thick, text centered]

\begin{document}

\tikzset{block/.append style={text width=15em, minimum height=2em,font=\normalsize}}

\begin{tikzpicture}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}

\vspace{5em}

\tikzset{block/.append style={text width=10em, minimum height=2em,font=\footnotesize}}

\begin{tikzpicture}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}

\end{document}


-

(I'm pretty sure we've had this one before, but I can't find it.)

The problem is that you are using font-specific dimensions to specify the width (text width=10em). It is potentially ambiguous as to what font size should be used to compute that: should it be the ambient font size (which is the "normal" size) or the internal font size (which is \footnotesize)? To make sure that no-one is disappointed with its computations, TikZ uses both. That is, it needs to know the value of text width twice and one time it computes it with respect to the internal font and once with respect to the ambient font.

If you wish TikZ to be a little less helpful, you need to decide which of the two methods of computation should be used. The simplest is to use the ambient font size. To do that, we just have to ensure that the first computation of the width is done before the font is changed. This can be accomplished by changing the key font=\footnotesize to execute at begin node=\footnotesize. This places the font change after the width computation and thus 10em is taken to mean "in the ambient font" both times.

There are a few ways to force the 10em to be in the internal font. The first is to make the internal font the same as the ambient font. This is done by putting \footnotesize in your picture. You can put it inside a group or scope to limit its effect. Another is to compute the length explicitly whilst under the influence of \footnotesize and then feed that computed length to the text width key.

Here's some examples.

\documentclass{scrbook}
%\url{http://tex.stackexchange.com/q/54368/86}

\usepackage{tikz}
\usetikzlibrary{shapes,chains,scopes,positioning,arrows}
\tikzset{block/.style={draw, rectangle, rounded corners, very thick, text centered}}

\begin{document}

\begin{tikzpicture}
\tikzset{block/.append style={text width=15em, minimum height=2em,font=\normalsize}}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}

\vspace{5em}

\begin{tikzpicture}
\tikzset{block/.append style={text width=10em, minimum height=2em,font=\footnotesize}}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}

\vspace{5em}

\begin{tikzpicture}
\tikzset{block/.append style={text width=10em, minimum height=2em,execute at begin node=\footnotesize}}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}

\vspace{5em}

\begin{tikzpicture}
\footnotesize
\tikzset{block/.append style={text width=10em, minimum height=2em}}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}

\vspace{5em}

\begin{tikzpicture}
{\footnotesize
\pgfmathparse{10em}
\global\let\pgfmathresult=\pgfmathresult
}
\let\nwidth=\pgfmathresult
\tikzset{block/.append style={text width=\nwidth, minimum height=2em,font=\footnotesize}}
\node[block]                 (node1) {Short text};
\node[block, below of=node1] (node2) {A slightly longer text};
\end{tikzpicture}
\end{document}


Note that as I'm repeating the same code lots, I moved the append style stuff inside each tikzpicture so that its effects didn't accumulate.

-
To be honest, I am also sure it has been asked before, but I could not find the thread either. Anyways, thanks a lot! I will also move my style append stuff inside the pictures - did not think about possible accumulations before. –  Jenny May 4 '12 at 10:04
@Jenny Duplicates aren't really a problem - if we couldn't find the original then anyone else looking for it would also find it difficult. As for the styles, I was quite impressed with the use of .append style in the first place. It was quite a while before I figured out that one could do that and it's not something I see here all that often. –  Andrew Stacey May 4 '12 at 20:23