Methods for Controlling Spacing in Web Typography

If you were developing sites in 2006, then you may have worked with a designer like me who was all up in your business about fonts not looking exactly the same in the browser as they did in mockups.

Then you may have tried explaining to me the pains of cross-browser compatibility and how different browsers render fonts differently from one another. In response, I likely would have sent you an image file that contains the content instead to make sure everything looked the same in all browsers. Yes, I was one of those designers.

Web fonts have come a very long way since then and we now have tools to tweak the way fonts render in browsers. Some have been around for quite a while. I remember my mind nearly bursting with excitement when I discovered FitText.js and Lettering.js way back when.

There are still plenty of situations today where adjusting fonts is needed to ensure the best legibility despite having all these fancy tools. We're going to cover a few of those in this post along with methods for how to deal with them.

Getting one exact headline to look right

I often run into this one, especially when a design contains a highly customized web font that looks great in general, but might look funky when used in a certain context.

Take the following headline using Abril Fatface from Google Fonts:

It a lovely font! However, there are a couple of points I'm not loving with this particular headline, specifically the spacing between a couple of letters, which makes things a little crowded:

This is where kerning comes to the rescue! Kerning is literally defined as the spacing between letters. All font files, whether we know it or not, contain some degree of kerning and we have the CSS font-kerning property to remove it:

.no-kern-please {
  font-kerning: none;
}
<h1 class="no-kern-please">Rubber Baby Buggy Bumpers</h1>

It's is a subtle difference, but one that can come in handy if your designer (or your own eye) wants to do it.

Note that disabling kerning is not always in your best interest. As James Kolce noted in a comment below, well-designed types use kerning as a tool and have a reason to do so. Removing the kerning with CSS, while addressing some specific design needs in a one-off situation, could have unintended consequences on the spacing between letters in the font overall, which could make spacing between other letters not-so-great.

See the Pen Kerning Toggle by CSS-Tricks (@css-tricks) on CodePen.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeOperaFirefoxIEEdgeSafari
29*16*34NoNo7*

Mobile / Tablet

iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
8*37No4.4*5955

Fixing poor letter-spacing across the board

If you've ever worked with a web font where the space between every single letter is either too wide or too narrow, then you know exactly how painful this situation is. Here's an example using another beautiful Google web font called Dorsa:

That might make for a decent display font for headlines, but could you imagine trying to read that as a paragraph? No bueno.

Kinda hard to read that content!

The CSS letter-spacing property can help make a sweeping change to the paragraph content if we add a couple pixels between each letter:

.spaced-out {
  letter-spacing: 2px;
}

I wouldn't go so far as to say this is still the best font for paragraph text, but it is much easier to read with that extra spacing:

See the Pen zKkPqK by CSS-Tricks (@css-tricks) on CodePen.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeOperaFirefoxIEEdgeSafari
301729126.1

Mobile / Tablet

iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
4.0-4.137No4.45955

Too little or too much spacing between words

This is an offshoot of the last situation except that the spacing issues are between each word rather than individual characters.

This is where the CSS word-spacing property is great and universally accepted by all browsers. Here's an example of a prose using the Prompt web font which is a little wider than many other fonts and would look nicer if it was dialed down a bit for this use case.

See the Pen GjJaaE by Geoff Graham (@geoffgraham) on CodePen.

Gnarly spacing between lines

Not all line heights are considered equal. Take the way some fonts look bigger than others, even though they have the same assigned font-size value.

See the Pen Difference in line height by font by CSS-Tricks (@css-tricks) on CodePen.

Setting the font-size sets the bounding box for which a font is allowed to take up space. If we set our font-size at 20px then that creates a box that takes up 20px of vertical space for each character to occupy.

Some fonts will take up more of the space than others and that will both give the appearance that one font is larger than the other but also that there is more or less vertical space between lines.

We can use the line-height property to help adjust that vertical space. A decent rule of thumb is something like font-size * 1.5 = line-height (or use a unitless line-height: 1.5;) for legibility but that will depend on the font being used and how it occupies vertical space. Check out molten leading.

Crispness and Legibility

Not all fonts are created equal across operating systems. That's because each operating system, be it Windows, Mac OS or anything else, will have different process for how many pixels to use when displaying fonts.

Many of us web designers loathe the thought of being beholden to how a system interprets our typography decisions.

Image source: webtype.com

There are CSS properties at our disposal to increase the apparent resolution of how fonts are displayed on different systems. This process is more formally known as subpixel rendering because it instructs the browser to attempt to fill missing pixels where they might exist.

There is no shortage of #hotdrama over whether it is appropriate to play with the subpixel rendering of fonts. Despite being written a few years ago, Dmitry Fadeyev summed up his argument against the practice nicely.

The antialiasing mode is not a “fix” for subpixel rendering — in most cases it’s a handicap. Subpixel rendering is technically superior, clearer, and more readable than antialiasing because by utilizing every one of the subpixels it increases its effective resolution used for font smoothing by three times. Antialiasing is useful for certain circumstances, such as for light on dark text, but it is absolutely not a replacement for subpixel rendering, and certainly not a “fix”.

But let's say we wanted to do it anyway. CSS gives us a certain level of control over the crispness and legibility by using font-smooth to fill in what operating systems might leave behind.

The font-smooth values include:

  • auto: Allows the browser to decide the best case for filling in pixels on fonts.
  • never: Disables the system from auto-smoothing fonts. This will display the font in its natural state, jagged edges and all.
  • always: Instructs the browser toll always add pixels to fonts where it sees the opportunity.

Note: The font-smooth property is considered an unofficial property at the time of this writing and is not recommended for use on a production site. There are vendor prefixes to achieve the effect in WebKit and Mozilla, though there is no standard implementation.

Given that note, the following vendor prefixes are currently available with their own values:

-webkit-font-smoothing

  • none: Disables font smoothing in WebKit browsers.
  • antialiased: Smooths the font on the same level as the pixels already provided by the system.
  • subpixel-antialiased: Smooths the font on a more micro level to give the sharpest text possible, particularly on high-resolution screens.

-moz-osx-font-smoothing

  • auto: Allows the browser to decide whether to optimize the font smoothness.
  • inherit: Takes the property value of the parent element.
  • unset: The same as specifying none in the WebKit prefix.
  • grayscale: Similar to the antialiased value in the WebKit prefix.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeOperaFirefoxIEEdgeSafari
63*48*58*NoNoTP*

Mobile / Tablet

iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
NoNoNoNoNoNo

Oh, wait, you're using SVG?!

SVG has its own level of support for the techniques we've been covering in this post. We've got kerning (not likely to do much) and the usual suspects letter-spacing and word-spacing. Interestingly, we also have a textLength attribute which can be used to explicitly set how wide the text should be rendered, and it will stretch/squish the text to accommodate. The lengthAdjust attribute controls whether that should happen to just the characters or the glyphs (like punctuation) too.

See the Pen SVG Text Spacing by CSS-Tricks (@css-tricks) on CodePen.

In Conclusion

Typography on the web is hard! Yes, we do have a ton of control over how type is displayed, rendered and positioned on the screen. But with great power comes great responsibility. At least you now have a few tools at your disposal to respond back to web designers who are stuck on the the precision of typographical design in the browser.