7

I want to balance the bottoms of all the columns. But only that of the last column does not. It comes to half heights of the textheight.

If % of the last %\columnbreak is removed, that of the last column is balanced. But the second page that has no text and two vertical lines appears.

What should I do to balance the bottoms of all the columns without appearing the second page?

\documentclass{article}
\usepackage{multicol}
\multicolsep0pt
\columnseprule.4pt
\pagestyle{empty}

\begin{document}

\noindent
\textbf{\large Examination}\smallskip\hrule

\begin{multicols*}{3}
\begin{enumerate}
\item Qutetion
    \vfill
    \begin{flushright}\underline{Answer\hspace{4em}}\end{flushright}

\columnbreak

\item Qutetion
    \vfill
    \begin{flushright}\underline{Answer\hspace{4em}}\end{flushright}

\columnbreak

\item Qutetion
    \vfill
    \begin{flushright}\underline{Answer\hspace{4em}}\end{flushright}

%\columnbreak
\end{enumerate}
\end{multicols*}

\end{document}

2 Answers 2

6

There are really too many conflicting use cases around balancing and multi-columns :-( and too little support from TeX doesn't help either.

Analysing this request, it is clear that the expectation is that all three columns will look identical. Unfortunately that is not the use case that multicol* implements (and if it is the case that there has been a buggy version 1.8f that actually did this isn't really going to change this).

The use case that multicol*implements is the following:

  • each column is fill until we reach the bottom of the page
  • then we start a new columns
  • the final column is filled with white space at the bottom, so that this "incomplete" column is not spread out.

This is modeled after the way \twocolumn works or how LaTeX finishes a document (or handles a \newpage). So what you get is

enter image description here

which is "correct" as essentially a \vfill is added at the bottom. Now given the fact that the column already contains a \vfill we get equal strength and thus the word Answer ands up in the middle.

Now one can argue about whether or not this should be a \vfillor only a \vfil (and perhaps the latter is more appropriate as that is also what LaTeX uses) but fact is that multicol was using that double strength \vfill since multicol* got introduced.

So let's change that for the moment by replacing an internal definition like this:

\renewcommand\vfillmaxdepth{\vskip 0pt plus 1fil minus \maxdepth}

(that has normally "fill" inside). So what does this gives us?

enter image description here

Hmmmm, so not quite right either. Do you see why?

well, the problem is that the 3 columns are not identical. The last column is ending an enumerate environment and that adds extra vertical space, that we can nicely see above. The reason that there isn't a similar white space is at the top of the first column is that multicolsuppresses such white space at the beginning as that is a usual use case (again you see that there are judgement calls and one oculd have a case where you don't want to have this supressed).

So how to we get rid of this extra space at the end?

Not easy as it turns out. Of course you can figure out what the parameter is that is used here and set it to zero, but a) that parameter is shared among all the "display environments" in LaTeX and b) it is not enough.

So lets try

\vskip-\lastskip % not really LaTeX but there you are

just after \end{enumerate}. Gets us nearly there, but still not correct as we get

enter image description here

I overlayed a few xxxxes so that it is easier to se what's going on. So why is the text in the last column still higher then in the others? The reason is that there isn't any space at the bottom in the first two columns but there is some in the last. We canceled it out with the above command but it is still a space only first a positive one and then a negative one.

But the issue is that any such space means that the depth of the last column is essentially ignored, so in the first two columns the bottom is at the baseline of the word "Answer" and the \underline is actually below the bottom of the column (we have a depth) whereas in the last column the bottom is where the printed material ends, ie we have no depth and all of the material is within the column.

So what one really needs after the \end{enumerate} is something like

\vskip-\lastskip     % drop the extra space from enumerate
\vskip-\prevdepth    % back up by the depth of the last lin

only then you get

enter image description here

Now this isn't quite the way it should be and if you replace multicol* with multicol then you will notice that that the above is needed then (as no \vfill is added at the end of the last column) but that it doesn't work either and you end up with

enter image description here

(again with xxxx overlayed) so the last column is off by this \prevdepth amount.

Now, that I guess is a bug (in version 1.8i) and I fear I need to have a very deep look at this ... and I have many more before ... \prevdepth handling is a nightmare as it seems.

Update

I updated multicol to support this use case directly as I think this can be done without harming other scenarios. Basic approach is

  • at \end{multicols*} firstly back up by \lastskip (if there is space, from say an environment ending, we don't really need that)
  • then back up by \prevdepth (so that we are at the baseline of the last box if there was one)
  • then insert a \vfil (one l) so that by default the column is set ragged.

Now if there if a \fill inside the column it will align nicely at the bottom (unless there was more than one vertical space because we only removed the last).

If the user really wants a specific space at the end \vspace* will do that for him.

The full approach is a little bit more complicated, which is why this needs a little more testing, but if all works out well it will show up in v1.8j.

5
  • It works well. I highly appreciate your immediate response. Thank you for your kind and detail explanation.
    – Kay
    Mar 5, 2015 at 4:11
  • This problem has solved in this way. Write at preamble "\renewcommand\vfillmaxdepth{\vskip 0pt plus 1fil minus \maxdepth}", and after "\end{enumerate}", "\vskip-\lastskip" and "\vskip-\prevdepth". Thank you Mr. Mittelbach.
    – Kay
    Mar 5, 2015 at 14:12
  • 1
    The other day, I've installed TeX Live 2015 pretest for windows. That contains multicols.sty ver 1.8k. It works well. I need not adjust by using "\vskip...." I'm very grateful to you for creating new version.
    – Kay
    Apr 19, 2015 at 17:17
  • @Kay welcome. As one can see it was more complicated as anticipated and I had 2 iterations to hopefully get it right Apr 19, 2015 at 17:33
  • Today, I've got v1.8m from CTAN. Of course, it works well. Thank you very much.
    – Kay
    Apr 20, 2015 at 16:03
4

You have used multicols* rather than multicols which stops balancing.

Without the * the columns are balanced producing:

enter image description here

5
  • I think the OP wants to fill the columns vertically Mar 3, 2015 at 19:04
  • @karlkoeller but I assume the OPs real document has some actual text, which would make a difference here. Mar 3, 2015 at 19:05
  • Thank you for your advice. I mean I want "Answer" to be located lower.
    – Kay
    Mar 3, 2015 at 19:11
  • @Kay so I see, I leave that to Frank:-) Mar 19, 2015 at 15:07
  • @DavidCarlisle guess the picture output is no longer correct - the columns would now line up Apr 21, 2015 at 7:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .