5

I would like to add even vertical spaces after minipages in a same page. In other words, vertical spaces between adjacent minipages, the vertical space between the last minipage and the bottom of a page should be the same.

Expected page layout: expected page layout

When all minipages can be put into 1 page, the typesetting is expected. But when all minipages spread to multiple pages, there is no vertical space after the last minipage in a page.

MWE:

\documentclass[a4paper]{article}

\usepackage[pass,showframe]{geometry}
\usepackage[demo]{graphicx}
\usepackage{pgffor}
\usepackage{multicol}

\begin{document}

\foreach \img / \imgw / \imgh in {{xxx.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.7\textheight}}} {
    \noindent%
    \begin{minipage}[t]{\linewidth}%
        \includegraphics[width=\imgw,height=\imgh]{\img}%
    \end{minipage}\par\vfill%
}

\end{document}

The output from the above code is: enter image description here

How to achieve the expected layout?


Edit: Experiments with proposals

Because a minipage may contain text, caption and image in my real TeX source, I tried proposals:

  • \vspace*{\fill}\pagebreak[0] from @egreg
  • \vfill\null from @Herbert

When a minipage only contains image, layouts looks the same. When a minipage contains 1 line text and an image, layouts looks the same.

But when a minipage contains a caption and an image, \vspace*{\fill}\pagebreak[0] gives more compact layout, while \vfill\null gives relative loose layout.

MWE:

\documentclass[a4paper]{article}

\usepackage[pass,showframe]{geometry}
\usepackage[demo]{graphicx}
\usepackage{pgffor}
\usepackage{caption}

\begin{document}


\foreach \img / \imgw / \imgh in {{xxx.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}}%
                                  } {
    \noindent%
    \begin{minipage}[t]{\linewidth}%
        \captionof{figure}{This is a caption}
        \includegraphics[width=\imgw,height=\imgh]{\img}%
    \end{minipage}\par\VFILL_PLACEHOLDER
}

\end{document}
  • \vspace*{\fill}\pagebreak[0] as \VFILL_PLACEHOLDER enter image description here

  • \vfill\null as \VFILL_PLACEHODER enter image description here

And the question is how /null changes space behavior?

  • Use \vspace*{\fill} – egreg Sep 15 '17 at 9:25
4

\vfill is discarded at a page break, \vspace*{\fill} isn't.

\documentclass[a4paper]{article}

\usepackage[pass,showframe]{geometry}
\usepackage[demo]{graphicx}
\usepackage{pgffor}
\usepackage{multicol}

\begin{document}

\foreach \img / \imgw / \imgh in {{xxx.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}}} {%
    \noindent
    \begin{minipage}[t]{\linewidth}%
        \includegraphics[width=\imgw,height=\imgh]{\img}%
    \end{minipage}\par\vspace*{\fill}
}

\end{document}

enter image description here

If you need to break pages in the process, you can add \pagebreak[0]:

\documentclass[a4paper]{article}

\usepackage[pass,showframe]{geometry}
\usepackage[demo]{graphicx}
\usepackage{pgffor}
\usepackage{multicol}

\begin{document}

\foreach \img / \imgw / \imgh in {{xxx.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.2\textheight}},
                                  {yyy.png/{\linewidth}/{0.7\textheight}}} {%
    \noindent
    \begin{minipage}[t]{\linewidth}%
        \includegraphics[width=\imgw,height=\imgh]{\img}%
    \end{minipage}\par\vspace*{\fill}\pagebreak[0]
}

\end{document}

enter image description here

  • @diabonas Fixed – egreg Sep 15 '17 at 10:02
  • I have made some experiments, and it looks the proposal is stable in various scenarios. I have add experiments under 'Edit: Experiments with proposals' of the question. – SongHerz Sep 16 '17 at 6:09
3
    \end{minipage}\par\vfill\null % add empty box

enter image description here

  • When a minipage contains a caption, it seems the layout is too loose. New experiment is under 'Edit: Experiments with proposals' of the question. – SongHerz Sep 16 '17 at 6:06
3

And the question is how \null changes space behavior? The answer:

\vspace*{\fill}\pagebreak[0] does \penalty10000\vfill\penalty0 at TeX primitive level. The penalties have zero dimensions, i.e. there is only \vfill from dimensions point of view.

\vfill\null does \vfill\hbox{} at TeX primitive level. And if the \hbox is put to the main vertical list, the \baselineskip is typically added (not whole baselineskip, it depends on the depth of the previous box). So, there is \vfill plus a dimension from \baselineskip. That is bigger than the first case, it is not the same.

Moreover, the second case does not include \nobreak (alias \penalty10000) before \vfill, so the page break can be occur at \vfill and \vfill is removed. But first case keeps \vfill and the page break can be done at \penalty0 only.

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.