Rendering of cast metal type

Every browser comes with its own default CSS settings for the size and spacing of web page text, but it is rare that these values are optimal for the presentation of every typeface. I’ve covered sizing text with CSS in a previous article, so that won’t be my concern here: instead, I’ll be concentrating on line-height and margin.

Commonly referred to in the printing industry as leading, line-height is the vertical distance between lines of text in a content block. Depending on the browser and typeface used, line-height will commonly be a default value between 1.2 and 1.4, referred to as the “normal” value. In addition to this numerical value and keyword, leading can also be specified using percentages or a length value such as pixels or ems.

Screenshot showing too tight leading on h1 element
Too tight leading on h1 element from setting universal CSS line-height with a length measurement

Low leading values crams text together, reducing legibility. At the other end, “loose” leading adds too much vertical space, forcing the reader to work overtime as they try to scan continuous lines of text. Selecting the right amount of leading to display text is part of the typographer’s art, and depends on many factors, including the stroke weight and style of the text, font-size and measure length.

As a general rule, try to set font declarations as early as possible in stylesheets, creating a default for everything that follows. A typical starting point would be something like the following:

body {
	font-family: Calluna Sans, Arial, Helvetica, sans-serif;
	font-size: 1.6rem;
	line-height: 140%;
}

This sets the font size at the root of the element to approximately 22 pixels in height.

The problem is that when set with any length value line-height does not scale across different text sizes, as you can see above: the paragraph text has the correct leading, but that on the h1 element is too tight.

Somewhat unusually in CSS, line-height can be set as a pure number, without any specified measurement system. When set as a floating-point digit, leading does scale correctly across different font sizes:

body { 
	font-family: Calluna Sans, Arial, Helvetica, sans-serif; 
	font-size: 1.6rem;
	line-height: 1.5;
}
Screenshot showing correct leading on elements
Correct leading on elements with CSS line-height set using a numerical measurement

Now you’ve guaranteed that leading won’t be too tight for text of any size on your page. As a general rule, paragraph text should be set to a leading value of at least 1.5 to make it legible and accessible. There’s nothing stopping you from altering leading for other elements: it’s safe to assume that headings will require less leading than paragraph text. You can also shortcut the declaration with the font property, as shown below.

body {
	font: 1.6rem/1.5 Calluna Sans, Arial, Helvetica, sans-serif;
}
h1 { line-height: 1; }

By specifying leading as a number, you now have the ability to set line-height that will scale proportionally across different font sizes.

Other Potential Issues With line-height

If you’re using <sub> or <sup> to set superscript or subscript text in a web page, the default line-height on the elements can throw off the leading of paragraphs, as shown in the illustration.

One solution is to set line-height for <sub> and <sup> elements to 0, as I have suggested in my CSS reset and boilerplate: doing so won’t alter the position of subscripted or superscripted text, but will preserve the correct leading between paragraph lines. Alternatively, you can use an OpenType font to typeset superscript text automatically.

margin

In CSS, margin is used to separate content blocks. In the case of paragraphs, headings, and other text elements, margin-top and margin-bottom is used to provide vertical distance between blocks of text. Setting both to 0 on paragraph text, for example, will provide the impression of continuous paragraphs. If that was the case, you’d typically add text-indent to distinguish the start of each paragraph:

p {
	margin-top: 0;
	margin-bottom: 0;
	text-indent: 2rem;
}

Leaving both margin-top and margin-bottom undeclared will provide normal separation between paragraphs, but leaving the defaults on headings can cause layout issues. For example, with the following markup:

<body>
	<section>
		<h1>A Princess Of Mars by Edgar Rice Burroughs (published 1917)</h1>
		<p>In submitting Captain Carter's strange manuscript to you…

We will add the following CSS:

body {
	font: 1.6rem/1.5 Calluna Sans, Arial, Helvetica, sans-serif;
	margin: 0;
	background: #333;
	}
section {
	background: #fff;
	width: 70%;
	margin: 0 auto;
	}
h1 { line-height: 1; }
h1, p { 
	margin-left: 5rem;
	margin-right: 5rem;
}

Everything in the CSS would indicate that the h1 should touch the top of the page; instead, we see a result that you can see in the illustration.

Screenshot showing unexpected space above h1 element
Unexpected space above h1 element due to margin-top

To fix this issue, we must set margin-top for the <h1> element to 0; we can counterbalance this by pushing the heading down with some padding-top added to the <section>:

section {
	background: #fff;
	width: 70%;
	margin: 0 auto;
	padding-top: 5rem;
}
h1 { 
	line-height: 1;
	margin-top: 0;
}
h1, p {
	margin-left: 5rem;
	margin-right: 5rem;
}

Thoroughly understanding the contributions of both line-height and margin to text layout will help you tremendously in creating effective design for your web pages.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.