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:
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
is0pt 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
For vertical centering,
\topskip
glue and the baseline skip glue at the top and the bottom\vspace*{\fill}
at the top and\vfill
(or a more symmetrical\vspace*{\fill}
) at the bottom.