What's the difference between \strut
, \mathstrut
and \vphantom
? When would I prefer one of them to the others, and why?
[Tex/LaTex] Strutting around: What’s the difference between \strut, \mathstrut and \vphantom
boxesstrut
Related Solutions
You need to use \copy\strutbox
to get the box. The definition \newbox\strutbox
merely allocates a box number for the strutbox, then assigns that number to \strutbox
using \chardef
. Hence \strutbox
in isolation typesets the character in the current font with the same number as the box number allocated to strutbox.
\sbox
is a short form of \savebox
in the same way that \mbox
is a short form of \makebox
for the common case where you do not need to specify any lengths and want the natural size of the box. \setbox
is the underlying TeX primitive so it does not read its arguments as a normal macro (like the comparison between \hbox
and \mbox
) and it is not safe to use with colour commands unless you take extra precautions to insert extra groups, that the LaTeX versions do automatically.
Added note: One other important difference I forgot before, it is implicit in the examples below but not highlighted. \sbox\boxa{aa}
is like \setbox\boxa\hbox{....}
so it supplies the \hbox
. So if you need to save vertical material you need to save a vbox in an hbox, whereas with \setbox
you can do \setbox\boxa\vbox{aaa \par bbb}
however there is not much difference between a vbox and an hbox containing a vbox, unless you start using unboxing primitives, so this difference isn't a major one in practice.
UPDATE examples added as requested (the source is more informative than the output)
\documentclass{article}
\tracingonline2
\showboxdepth10
\showboxbreadth10
\usepackage{color}
%these are the same except the latex version \newsavebox
%checks that the name is not already used.
\newbox\boxa
\newsavebox\boxb
\begin{document}
\setbox\boxa\hbox{abc}
\sbox\boxb{abc}
The above look the same but see
%\showbox\boxa
%\showbox\boxb
\begin{verbatim}
> \box26=
\hbox(6.94444+0.0)x15.27782
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 c
! OK.
\end<verbatim}
\begin{verbatim}
> \box27=
\hbox(6.94444+0.0)x15.27782
.\pdfcolorstack 0 push {0 g 0 G}
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 c
.\pdfcolorstack 0 pop
\end{verbatim}
The LaTeX version has extra specials inserted so that colour acts like
fonts and stays with the box.
If you \emph{use} colour in the box it gets more serious
\setbox2\vbox{{% stop this broken test leaking to the page
\setbox\boxa\hbox{ab \color{red}c}
%\showbox\boxa
\begin{verbatim}
> \box26=
\hbox(6.94444+0.0)x18.33336
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\glue 3.33333 plus 1.66666 minus 1.11111
.\pdfcolorstack 0 push {1 0 0 rg 1 0 0 RG}
.\OT1/cmr/m/n/10 c
\end{verbatim}
See the box just contains a color push and the color pop is not saved
in the box but happens at the point of the save, so the colour stack
is corrupted which depending what you are doing can crash your printer
or just get the wrong colours or\ldots.
\setbox\boxa\hbox{{ab \color{red}c}}
%\showbox\boxa
\begin{verbatim}
> \box26=
\hbox(6.94444+0.0)x18.33336
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\glue 3.33333 plus 1.66666 minus 1.11111
.\pdfcolorstack 0 push {1 0 0 rg 1 0 0 RG}
.\OT1/cmr/m/n/10 c
.\pdfcolorstack 0 pop
\end{verbatim}
see that fixed it and the pop and push are now matched.
\sbox\boxb{ab \color{red}c}
%\showbox\boxb
\begin{verbatim}
> \box27=
\hbox(6.94444+0.0)x18.33336
.\pdfcolorstack 0 push {0 g 0 G}
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\glue 3.33333 plus 1.66666 minus 1.11111
.\pdfcolorstack 0 push {1 0 0 rg 1 0 0 RG}
.\OT1/cmr/m/n/10 c
.\pdfcolorstack 0 pop
.\pdfcolorstack 0 pop
\end{verbatim}
Latex gets it right.
}}% this box not put into the page so the colour stack is not
% corrupted.
Even without colour there are differences
\setbox\boxa\hbox{aa\verb|\relax|}
%\showbox\boxa
\begin{verbatim}
> \box26=
\hbox(6.94444+0.8333)x41.49976
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 a
.\hbox(0.0+0.0)x0.0
.\OT1/cmtt/m/n/10 \
.\OT1/cmtt/m/n/10 r
.\OT1/cmtt/m/n/10 e
.\OT1/cmtt/m/n/10 l
.\OT1/cmtt/m/n/10 a
.\OT1/cmtt/m/n/10 x
\end{verbatim}
%\sbox\boxb{aa\verb|\relax|}% commented out as it makes an error.
\begin{verbatim}
! Missing } inserted.
<inserted text>
\end{verbatim}
\end{document}
Best Answer
Each are defined as follows in the default document classes (
article
,book
andreport
):\strut
with
\strutbox
defined as\mathstrut
Using
\mathstrut
would be equivalent to using\vphantom(
, with\strut
sets a zero-width rule (\@width\z@
) with depth.3\baselineskip
(\@depth.3\baselineskip
) and height.7\baselineskip
(\@height.7\baselineskip
). Note that the latter is font-dependent, since it uses\baselineskip
. That is, it is modified with font change selections using\fontsize{..}{..}\selectfont
, including the use font switches like\small
,\large
, etc.I would use
\strut
within text or math, and use\vphantom
if there is anything else I want a specific height of without the horizontal displacement. For example, when breaking two lines of math with different heights but still wanting to use extensible delimiters\left
and\right
.\mathstrut
is specific to the size of(
and (quoting barbarabeeton), "\mathstrut
is often better in math than\strut
. Which one is better depends on the local context."Loading the
amsmath
redefines these boxes somewhat, although their interpretation remains the same.