[Tex/LaTex] Difference between \hfil and \hfill

primitivesspacing

I am trying to understand the difference between \hfil and \hfill. I always thought that these commands were roughly equivalent except that \hfill was "stronger" than \hfil. As a result, I thought that I could centre a line of text using either of the lines:

\hfil Horizontally centred \hfil

\hfill Horizontally centred \hfill

It turns out that only the first of these snippets actually horizontally centers the text but I do not understand why.

There is a similar issue with \vfil and \vfill. My understanding is that \vfill can be defined as \vspace{\fill}, so it makes sense that you cannot vertically center some text using

\vfill Vertically centered \vfill

because \vspace is ignored at the top of the page. By the same reasoning,

\vspace*{\fill} Vertically centred\vfill

should work and it does, although not quite perfectly. In a similar way, you can use \hspace*{\fill} to horizontally centre text.

Is anyone able to clear explanation of what the differences are between \hfil and \hfill, and between \vfil and \vfill? I am aware of the post What is the difference between 'fil' and 'fill'? but this does not help me.

In trying to understand what is going on I created the following MWE:

\documentclass{article}
\usepackage[paperheight=40mm, paperwidth=80mm,showframe]{geometry}
\parindent=0pt
\begin{document}

  \hfil Horizontally centred \hfil

  \hfill Horizontally centred \hfill

  \hspace*{\fill} Horizontally centred \hfill

  \hfill Horizontally centred \hspace*{\fill}

  \hfil Horizontally centred \hspace*{\fill}

  \newpage

  \vfil Vertically centred\vfil

  \newpage

  \vfill Vertically centred\vfill

  \newpage

  \vspace*{\fill} Vertically centred\vfill

\end{document}

which produces the four pages:

enter image description here

Of course, I know that I can centre text with either

\centerline{Horizontally centred}

\begin{center}Horizontally centred\end{center}

but that's not what I am asking….although I am not convinced that I know the best way to vertically centre text!

Best Answer

The first case: \hfil Horizontally centred \hfil\par (the blank line adds \par).

When \par is processed, the first thing TeX does is \unskip, then it adds a very high penalty, so the next added glue \hskip\parfillskip is not removed. Since the default value of \parfillskip is 0pt plus 1fil, you get centering. Almost, because you have a space after “centred” that's not removed.

The second case: \hfill text\hfill\par (the blank line adds \par).

This works as before, but now the \parfillskip glue is killed by \hfill.

The third case is essentially the same as the second one.

The fourth case: \hfill Horizontally centred \hspace*{\fill} almost centers the text (the space after “centred”, remember), because \unskip doesn't remove \hspace*{\fill} (it internally ends with another glob of glue just for this), because \parfillskip glue is killed.

The fifth case: the \hfil glue at either sides (explicit and provided by \parfillskip respectively) are killed by \hspace*{\fill}.

How do you achieve centering? With

\par{\centering Horizontally centred\par}

For vertical centering,

  1. you have to kill the \topskip glue and the baseline skip glue at the top and the bottom
  2. use \vspace*{\fill} at the top and \vfill (or a more symmetrical \vspace*{\fill}) at the bottom.
\documentclass{article}
\usepackage[paperheight=40mm, paperwidth=80mm,showframe]{geometry}

\setlength{\parindent}{0pt}

\begin{document}

\vspace*{-\topskip}
\vspace*{\fill}
\nointerlineskip
Vertically centred\par
\nointerlineskip
\vfill

\end{document}

enter image description here

Related Question