Tikz Node - Prevent TikZ from adding space inline

I have an automatic command to add an ellipse on top of a particular piece of text so that I can highlight it in a presentation (heavily inpired by \newcommand: How to determine if in math mode (and then include )?).

The problem is that the tikz node is bigger than the original text, which in a slide transition makes my text "dance".

Is there a way to prevent tikz from adding any space besides the actual text argument? I tried to use the remember picture,overlay options with phantom{} for the node size, but then the shading would appear on the wrong place.

MWE

\documentclass[]{beamer}
\usepackage{tikz}
\usetikzlibrary{shapes,calc}

\newif\ifsmm
\newcommand*{\mysmc}[1]{%
\relax\ifmmode\smmtrue\else\smmfalse\fi%
\tikz[baseline=(text.base)]%
\node(text)[ellipse, fill=blue, fill opacity=0.2, inner sep=0.2mm, text opacity=1]%
{\ifsmm$#1$\else#1\fi};%
}

\begin{document}

\begin{frame}
This is the example without a highlighted word.\\
This is \mysmc{the} example with a highlighted word. (text is shifted)\\[1cm]

This \mysmc{\color{blue}is} the example with a different size. $a^2+\mysmc{b^2}=c$
\end{frame}
\end{document}

• Do you want inner sep=0pt ? – cfr Apr 25 '16 at 23:09
• Your code doesn't demonstrate the problem - you need 2 slides to show something dancing! – cfr Apr 25 '16 at 23:11
• @cfr I humbly disagree. I put two sentences that have exactly the same beginning. In the first two sentences the word "example" should be aligned, but because of the added space they are not. inner sep=0pt does not resolve the issue – Miguel Apr 26 '16 at 14:04

You need overlay to ignore the extra width, but you also need \hspace to reserve the space and center the overlay.

\documentclass[]{beamer}
\usepackage{tikz}
\usetikzlibrary{shapes,calc}

\newsavebox\smmbox
\newif\ifsmm
\newcommand*{\mysmc}[1]{%
\relax\ifmmode\smmtrue\else\smmfalse\fi%
\savebox{\smmbox}{\ifsmm$#1$\else#1\fi}%
\hspace{0.5\wd\smmbox}% half way
\tikz[overlay,baseline=(text.base)]{%
\node(text)[ellipse, fill=blue, fill opacity=0.2, inner sep=0.2mm, text opacity=1]%
{\usebox{\smmbox}};}%
\hspace{0.5\wd\smmbox}}

\begin{document}

\begin{frame}
This is the example without a highlighted word.\\
This is \mysmc{the} example with a highlighted word. (text is shifted)\\[1cm]

This \mysmc{\color{blue}is} the example with a different size. $a^2+\mysmc{b^2}=c$
\end{frame}
\end{document}


• On issue with this solution is that it changes the size of elements that are not "normal" sized. For example, if I wanted to highlight part of a fraction, then the highlighted part would be larger than it should. An alternate solution based on yours that also works is to do\newsavebox\smmbox \newif\ifsmm \newcommand*{\mysmc}[1]{% \relax\ifmmode\smmtrue\else\smmfalse\fi% \savebox{\smmbox}{\ifsmm$#1$\else#1\fi}% \tikz[overlay,baseline=(text.base)]{% \node(text)[ellipse, fill=blue, fill opacity=0.2, inner sep=0.2mm, text opacity=1]% [xshift=0.5\wd\smmbox]{\phantom{\usebox{\smmbox}}};}% #1% } – Miguel Apr 26 '16 at 14:32

One way to get rid of the shift is to typeset the ellipse on every slide, but only fill or draw it on certain slides.

However, whichever option you choose, I would recommend making your command overlay-specification aware.

Here's an example:

\documentclass[]{beamer}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\newif\ifsmm
\newcommand<>{\mysmc}[1]{%
\relax\ifmmode\smmtrue\else\smmfalse\fi%
\def\tempa{}%
\def\tempb{#2}%
\ifx\tempa\tempb
\tikz[baseline=(text.base)]{%
\node (text) [highlighted, ellipse, fill opacity=0.2, inner sep=0.2mm, text opacity=1] {\ifsmm$#1$\else#1\fi};
}%
\else
\tikz[baseline=(text.base)]{%
\node (text) [highlight on=#2, ellipse, fill opacity=0.2, inner sep=0.2mm, text opacity=1] {\ifsmm$#1$\else#1\fi};
}%
\fi
}
\tikzset{% set up for transitions using tikz with beamer overlays - developed by Daniel (http://tex.stackexchange.com/a/55849/) and, in earlier form, by Matthew Leingang (http://tex.stackexchange.com/a/6155/) and modified for this use, I think by Qrrbrbirlbel (http://tex.stackexchange.com/a/112471/)
alt/.code args={<#1>#2#3}{%
\alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
},
highlighted/.style={fill=blue},
highlight on/.style={alt=#1{highlighted}{}},
}
\begin{document}
\begin{frame}
This is the example without a highlighted word.\\
This is \mysmc<2->{the} example with a highlighted word. (text is shifted)\\[1cm]

This \mysmc{\color{blue}is} the example with a different size. $a^2+\mysmc<2->{b^2}=c$
\end{frame}
\end{document}


\mysmc now takes an optional overlay specification. If \mysmc{} is used, the command does just what it always did. If \mysmc<>{} is used, an ellipse will be constructed on every slide, but filled only on the slides specified in the overlay specification.

In the example above, the first and third instances of the command specify <2-> so their ellipses are filled only on slide 2. The second instance has no overlay specification, so its ellipse is filled on slides 1 and 2.

This ensures that sufficient space is left for the ellipse. While it does create extra space on the non-highlighted slides, I think this is better in a presentation than trying to squish the ellipse into less space than it really wants.

Here's the output: