6

I've been working on a document with extra vertical space at the top of some pages and noticed that in certain contexts the spacing comes out differently on the first page compared with later pages. See the following MWE:

\documentclass{article}
\usepackage{lipsum}

\begin{document}
\vspace*{10pt}
\lipsum[1-2]
\newpage
\vspace*{10pt}
\lipsum[1-2]
\end{document}

The space at the top of the second page is smaller than on the first page. Weirdly if you use only one paragraph of lipsum the problem goes away. It is also fixed by using

\null\vspace{10pt}

instead. Can someone please explain what is going on here?

6

The problem is that the \baselineskip glue is inserted before the first line in the page after \vspace*. And it depends on the depth of the previous line. At beginning of the document, this depth is zero, but after the last line of the second paragraph is printed, the depth is derived from the depth of the p and q letters. If you remove the second paragraph then the last line includes only the rutrum word and it has zero depth.

If \vspace* isn't used after page break then the "unstable" \baselineskip is removed because it is "discardable item" after page break and \topskip glue is normally used.

The \vspace* implementation is bad, because it saves \prevdepth (it is used for next \baselineskip glue), then it puts non-discardable item (\hrule) plus desired \vskip and then restores the \prevdepth register:

\def\@vspacer#1{%
  \ifvmode
    \dimen@\prevdepth
    \hrule \@height\z@
    \nobreak
    \vskip #1
    \vskip\z@skip
    \prevdepth\dimen@
  \else ...

Now, the "unstable" \baselineskip is added after the material from \vspace* and it isn't removed at page break.

I suggest to use

\par \null \nobreak \vskip-\baselineskip \vskip<desired amount> \relax

instead LaTeX's \vspace*.

  • Well, not entirely exact: there is no “unstable” interline glue which is removed at the top of the new page. Interline glue is inserted only when a box is appended to a vertical list, unless it is the first box contributed to the main vertical list,in which case the \topskip glue is added. The point, here, is that \prevdepth is not reset when the output routine is invoked, so the \vspace command “sees” the value that was in force at the end of the previous page. This reduces the interline glue which is inserted when the first box is added under the \vspace. – GuM Feb 28 '16 at 13:35
  • @GustavoMezzetti Your comment is not entirely exact. Suppose in main vertical list: box, penalty-500 interline-glue box. This interline-glue is "unstable" (depends on the prevdepth which is derived from previous box depth). Suppose that the the page builder and next the output routine is executed after the second box (or after more material not mentioned here). Page builder decides (for example) that penalty-500 is breaking point. Then the following "unstable" glue is removed and topskip is used instead it. But output routine knows the depth of the second box, no the first in such case. – wipet Feb 28 '16 at 14:43
  • The situation you describe can occur, and in that case the interline glue is discarded: I am just saying that this is not what happens in this case, where it is the interline glue that follows the \vspace which is wrong. Not really important, anyway! :-) Rather, in the code you suggest, you should honor LaTeX conventions about vertical space and put \vskip 0pt \relax at the end. – GuM Feb 28 '16 at 16:26
2

Wipet's analysis is correct. If precise spacing at the top is needed, the prevdepth should be neutralized.

\documentclass{article}
\usepackage{lipsum}

\makeatletter
\g@addto@macro{\newpage}{\nointerlineskip}
\makeatother

\begin{document}
\nointerlineskip
\vspace*{10pt}
\lipsum[1]
\newpage
\vspace*{10pt}
\lipsum[1]
\end{document}

However, a \nointerlineskip should be added in case we need a space in the very first page, because LaTeX inserts a whatsit at the top.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.