# Understanding line height / line spacing / baselinskip in LaTeX

I tried for a while now to figure out how LaTeX is determining the spacing between two lines but instead of getting clearer I'm more and more confused (and it seems the Internet is mostly confused, too), so let's see if turning it into a question can clarify it!

# The naive assumption

First of all my naive understanding of "line height" or what I assumed was the value stored in \baselineskip was the following

Consequently I assumed setting \baselineskip equal to font size should result in lines "touching" each other - no actual empty space between lines (including full ascenders and descenders of the font).

# Reality seems to differ

However it became clear to me, that this can't be true. Consider the following:

\documentclass{article}

\begin{document}
\setlength{\parindent}{0pt}

% font size = \baselineskip - should result in lines "touching", shouldn't it?
\fontsize{10pt}{10pt}\selectfont
\textbar The quick brown fox jumps over the lazy dog\\
\textbar The quick brown fox jumps over the lazy dog

\fontsize{20pt}{20pt}\selectfont
\textbar The quick brown fox...\\
\textbar The quick brown fox...

\fontsize{30pt}{30pt}\selectfont
\textbar The quick brown fox...\\
\textbar The quick brown fox...

\end{document}


While my assumption seems to hold for smaller font sizes, the larger the font size the more obvious it becomes this can't be the whole truth!

# Set line height in multiples of font size?

Similar confusion is also apparent for people trying to set the line spacing to a specific multiple of the font size.

Using \renewcommand*\baselinestretch{1.5}\selectfont or similar does many things - but not result in what one expects to be a one-and-a-half line spacing!

This even resulted in the creation of the setspace package, which is often recommended to achieve the desired result. Looking at the source reveals however, that the authors were not fully able to understand what LaTeX was doing either:

% GT:  Sat 28 Sep 1996:  No, I don't know understand the line spacing
% algorithms!  If someone (LaTeX team) can enlighten me as to the
% general rule, please do!  It would be very pleasant if setspace.sty
% were suited for document font sizes other than 10, 11 and 12 pt.


And in fact the package specifies some hardcoded values for the three font sizes mentioned to achieve consistent line spacing at least for the most commonly used font sizes.

# Why care?

Obvious question: Why care so much if whatever TeX does seems to "look good" at least.

In my specific case I want to implement something in TeX that works like the line-height property in CSS/SVG, so I can set the line spacing precisely in multiples of the font size.
So far a solution is elusive to me which kind off bugs me because I always thought this was the stuff TeX was supposed to be superior in, but it turns out in this particular case it's reluctant to comply.

Therfore I hope you can give me the clarity I need to implement what I want and explain what spacings control the actual distance of two font baselines in LaTeX and how \baselineskip plays into this.

• It seems that you need \offinterlineskip — but, curiously, not if you compile with luatex rather than pdftex. – Thérèse Jan 13 '18 at 21:40
• Might make a difference if you are using fully scalable fonts, versus fonts that come in quantized font sizes. – user139954 Jan 13 '18 at 21:44
• @RobtAll almost all fonts available in TeXLive are scalable format these days – David Carlisle Jan 13 '18 at 21:58

Your first assumption and picture of \baselineskip were correct, but

Consequently I assumed setting \baselineskip equal to font size should result in lines "touching" each other

Is wrong for two separate reasons.

Firstly the "font size" is an essentially arbitrary number assigned by the font designer \fontsize{10pt}{10pt}\selectfont selects a font with nominal size 10pt and \baselineskip equal to 10pt but the actual height of the letters (especially parentheses and accented captitals, or even unaccented capitals) may be more than 10pt. So this may or may not result in \baselineskip glue being added depending if the height of the letters actually used on the line is more or less than 10pt.

Secondly teX does not force the baselineskip by using no space (or negative space) two over-height lines do not over-print, being set to a forced \baselineskip spacing. If the space to be added would be less than the parameter \lineskiplimit then a length \lineskip is used instead.

By default in the standard classes \lineskip is 1pt so you will see a minimum 1pt separation if the baselines would touch but (slightly strangely) \lineskiplimit is 0pt so the distance can approach zero without \lineskip being used, which will cause a "jump" in interline space if the height of the content is gradually increased.

\showoutput
\showboxdepth=3


to your test file, note first that it says

LaTeX Font Warning: Size substitutions with differences
(Font)              up to 5.12pt have occurred.


So the fonts used were not always the size requested (but \baselineskip was always exactly as requested) this explains why the effects are more apparent at some sizes. The log will show

\vbox(633.0+0.0)x407.0
.\glue 16.0
.\vbox(617.0+0.0)x345.0, shifted 62.0
..\vbox(12.0+0.0)x345.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x345.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(550.0+0.0)x345.0, glue set 426.9944fil
...\write-{}
...\glue(\topskip) 2.5
...\hbox(7.5+2.5)x345.0, glue set 143.77742fil []
...\penalty 300
...\glue(\baselineskip) 0.0
...\hbox(7.5+2.5)x345.0, glue set 143.77742fil []
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 1.945
...\hbox(15.555+5.185)x345.0, glue set 152.1931fil []
...\penalty 300

...\glue(\lineskip) 1.0

...\hbox(15.555+5.185)x345.0, glue set 152.1931fil []
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 6.155
...\hbox(18.66+6.22)x345.0, glue set 113.70607fil []
...\penalty 300
...\glue(\baselineskip) 5.12
...\hbox(18.66+6.22)x345.0, glue set 113.70607fil []
...\glue -5.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 23.55556
..\hbox(6.44444+0.0)x345.0, glue set 170.0fil
...\glue 0.0 plus 1.0fil
...\OT1/cmr/m/n/10 1
...\glue 0.0 plus 1.0fil


If you allow the fonts at any size by adding \RequirePackage{fix-cm} as the first line you get no font size warning

and a log of

\vbox(633.0+0.0)x407.0
.\glue 16.0
.\vbox(617.0+0.0)x345.0, shifted 62.0
..\vbox(12.0+0.0)x345.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x345.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(550.0+0.0)x345.0, glue set 427.45435fil
...\write-{}
...\glue(\topskip) 2.5
...\hbox(7.5+2.5)x345.0, glue set 143.77742fil []
...\penalty 300
...\glue(\baselineskip) 0.0
...\hbox(7.5+2.5)x345.0, glue set 143.77742fil []
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 2.5
...\hbox(15.0+5.0)x345.0, glue set 159.07242fil []
...\penalty 300
...\glue(\baselineskip) 0.0
...\hbox(15.0+5.0)x345.0, glue set 159.07242fil []
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 2.5
...\hbox(22.5+7.5)x345.0, glue set 66.10855fil []
...\penalty 300
...\glue(\baselineskip) 0.0
...\hbox(22.5+7.5)x345.0, glue set 66.10855fil []
...\glue -5.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 23.55556
..\hbox(6.44444+0.0)x345.0, glue set 170.0fil
...\glue 0.0 plus 1.0fil
...\OT1/cmr/m/n/10 1
...\glue 0.0 plus 1.0fil

• Thanks, I never thought to blame the font! Using \usepackage{lmodern} fixes the unexpected spaces just as well (I was using it at one point but removed it for this minimum example which only added to the overall confusion) – Patrick Storz Jan 13 '18 at 22:32
• @EduardBraun note it's not the font so much as latex's declaration of it. The computer modern fonts for compatibility reasons by default are only loaded at the sizes available as bitmaps in 1985, even though scalable type1 versions have been freely available for 20 years or so. It's really hard to change that default, but the fix-cm package just loads cm the way most other fonts are loaded, and allows arbitrary size, so yes using lmodern or more or less any other font package has a similar effect here. – David Carlisle Jan 13 '18 at 22:45
• @DavidCarlisle It is indeed slightly strange that the value of\lineskiplimit is 0pt while that of \lineskip is 1pt (without stretch). Wouldn't setting \lineskiplimit to 1pt be more consistent? (Another vertical spacing problem I have never understood is why the value of \belowdisplayskip is different from that of \belowdisplayshortskip, but this probably means I am a typographic heretic...) – Michel Fioc Jan 15 '18 at 15:06
• @MichelFioc D Knuth set it that way in plain and L Lamport followed suit in latex 2.x and we didn't change it in latex2e, but I don't think it can be justified for reasons other than compatibility – David Carlisle Jan 15 '18 at 15:55

The second test includes 1 pt \lineskip between lines and the third test has the lines not exactly 30 pt height because \usepackage{fix-cm} was not used.

• +1 a lot more succinct than my answer but same information:-) – David Carlisle Jan 13 '18 at 22:00