Why is `\strut` working in these scenarios?

The main issue here deals with the bounding boxes associated with the contents. Some elements have different depths than others, most notably from text without descenders. For example, Hello has no depth, while spacing has some. The idea behind \strut is to ensure that \strut Hello and \strut spacing (for example) cover the same ground vertically.

A quick example of this is visible when you view this MWE:

enter image description here

\documentclass{article}
\newcommand{\ddd}[1]{\fbox{\strut#1}\,\fbox{#1}}% Show the difference in bounding boxes
\setlength{\fboxsep}{-\fboxrule}% For this example
\begin{document}

Letters: \ddd{a}\ \ddd{b}\ \ddd{p} \ddd{Q}

\bigskip

Words: \ddd{Hello}\ \ddd{spacing}

\end{document}

Is can be seen, the bounding boxes of these letters/words are vertically equivalent to one another, even though they each may have different descenders/ascenders. More specifically, \strut ensures at least a 70% \baselineskip in terms of height, and 30% \baselineskip in depth in the prevailing font. From \strutbox's definition (used by \strut) in the LaTeX kernel as part of \set@fontsize:

\setbox\strutbox\hbox{%
  \vrule\@height.7\baselineskip
        \@depth.3\baselineskip
        \@width\z@}%

So, specific to your case, you can see that the \strut inside the \parbox increases the depth of the box, and therefore the skip from one line to the next (see the difference in the bounding boxes related to spacing above).

The second comparison to Hello is somewhat bizarre in your particular case. In the first you raise it based on height+depth (or \totalheight) while in the second you raise it based on depth only (\dp). Since Hello has height, the first raise is non-zero, while it is zero in the second, since Hello has zero depth.

Also see, as reference, How to keep a constant \baselineskip when using minipages (or \parboxes)?


From the comments on the on the other answers, it seems like you want to concentrate on

 \leavevmode\strut\vadjust{%
    \noindent
    \raisebox{\dp\strutbox}[0pt][0pt]{\makebox[0pt][r]{Hello}}
  }%

The first \leavevmode isn't really needed as \strut is defined to get into horizontal mode, however it does no harm and makes it clearer that the code needs horizontal mode. Then comes the \strut this is important and we'll come back to that. Then \vadjust: the content of \vadjust is evaluated immediately (like \vbox) but the resulting vertical material is not boxed but inserted into the vertical list that will be later constructed from the lines in the paragraph.

The intention of the code is to make hello aligned to the baseline of the previous box, but the vadjust material is inserted directly into the list not forced to baseline spacing so to align to the baseline of the previous box you need to back up by the depth of the previous box. the "previous box" has not yet been constructed, it consists of whatever text ends on the line that has the vadjust node If that line had arbitrary text its depth would not be known. However as \strut was added and this had bigger depth than any letter or other normal text it is reasonable to assume the depth of the line is the depth of strutbox.

So \raisebox{\dp\strutbox} gets you back to the baseline of the previous line.

This will fail if you put some deep inline math or an inline tabular in the line, but if you need to deal with that you need a more complicated two pass measuring scheme.


First of all, what does \strut do? It simply produces an invisible rule whose height is 70% and the depth 30% of the current baselineskip.

A \parbox[t] makes a box as high as its first line; all the successive lines contribute to the depth. Thus, when a \parbox[t] is found, between the line in which it is and the next one, the \lineskip glue will be inserted (excluding the trivial case of a one line \parbox[t]). A fix for getting uniform spacing is thus to end the \parbox[t] with \strut and adding one in the next line. This will ensure (except in the case where lines are too high or deep) that the baselines are \baselineskip apart (using the fact that the \lineskip glue is usually zero).

This is shown in your first example, with the \parbox nested in a tabular. There's no need to add a \strut in the following row, because rows in a tabular are kept apart from each other exactly by struts.

The second example is more contorted. The material in \vadjust should be vertical material and not horizontal material, which causes however horizontal mode to start. The material is added between lines and, since it contains a box, it will contribute its height and depth (but no interline glue). You can check this by saying \vadjust{Hello} instead. So it doesn't provide a good illustration of \strut usage.