Spacing your typography and components to avoid surprises in development.
I’ve worked in organisations large and small, agencies and in-house. One thing that’s been common everywhere is the designers’ shock at how spacing has been implemented to their designs in production.
“The spacing is all wrong” — Designer during QA process
First off, it could be that the frontend developers have established spacing units that are different to yours, they’re using a “closest” or “looks about right” approach but that’s not what I want to talk about today.
Sorry fellow designers, the most common reason for this I’ve found has been a problem with the design files or specs themselves.
I’ve broken this article up into 5 sections. The box model, The em-box, Line-height, Margins and Baseline grids.
The box model
If you’re familiar with designing for the web or have done any CSS you should be familiar with the box model. You can read about it on MDN if not.
Even a designer that knows all about the box model can seemingly have a mental block when it comes to typography. Yes, typographic elements use the box model too!
The em box
The em box is the rectangle around each individual glyph of the font.
When you set a font size of 16px, you‘re not actually setting any part of the letterforms themselves to 16px, you are setting the em-box to 16px. The glyph inside the em-box varies in size depending on the typeface you’re using. This, excluding font-metrics like x-height, is one of the reasons why some fonts can look bigger or smaller than others, even if they are technically the same font size.
When we think about font-size in our design files for CSS, we need to think about the size of this box, not the visible size of the glyph.
Within the box model, the content box for a typographic element is defined by the line-height, not the font size.
For example, when you have a font-size of 40px, if the line-height is smaller, say 24px, the box around your text from a CSS perspective will be 24px high even if it can’t contain the text. So when you’re considering a spacing scale, the unit that’s actually most important to hit a baseline grid is the line-height.
Leading is not line-height
This problem was more pronounced in the era of Adobe software being industry standard, when programmes intended for print were being used to design websites.
Photoshop, Illustrator and InDesign (and I believe old versions of Figma) did not have line-height as a concept. They use the traditional term from lead type called “leading”. This name is derived from lead being inserted underneath each line of type to increase the spacing between lines.
So what’s the difference?
Leading in the digital sense is not set as the height of the extra lead, it’s set as a number inclusive of the font-size. So with a 16px font-size, if you wanted 4px “lead” the leading would be 16px+4px = 20px.
With leading this 4px is applied underneath the text.
In CSS, line-height is equally distributed above and below the text box, so using the same units as above we need to flip it round. 20px line-height -16px font-size = 4px. Then we divide 4px / 2 to give us 2px distributed above and below the text box.
It’s this distribution that can start to cause unexpected spacing issues if you haven’t designed with it in mind.
The distribution of line-height cannot be changed, it is always line-height -font-size, divided by 2 and distributed top on the top and bottom of the text block. You can’t have more spacing at the top than bottom as much as that would be a desirable option to have.
You cannot efficiently define typography for the web in software that uses leading rather than line-height. Luckily modern UI specific software use CSS line-height rather than leading, but as a designer you need to pay close attention to the bounding box.
If you select some text in Sketch, that box around it IS the line-height, as demonstrated with this extreme example below.
This is how your type is going to be implemented in CSS. If you find this box overlapping other elements (for example, components or another paragraph, heading etc) you’ve either set your line-height too large, or you’ll need to use negative margin to achieve the design.
To take this example further, if you were to stack two of the 16px/40px line-height boxes on top of each other, there would be a large optical margin, but from a CSS perspective this is actually `margin-bottom: 0;`.
As you’ll remember from the box model, the margin is the outermost layer of the box. Typographic elements use margin to space them apart. This is the probably the most common point of failure I see in design files.
Typographic spacing is often defined by what designers want it to be, from the baseline. The optical margins that cannot really be replicated in CSS, unless of course the developer does not use the units defined in your design!
The real world impact of design files using an optical margin, rather than using the box model in their design is illustrated below.
Something I’ve seen more times than I can remember is leading (or line-height) being treated like it doesn’t exist on the last line of the paragraph and the margin / paragraph spacing being measured from the baseline to the top of the next line.
Development implementation of spec
If a developer was to implement this spec as prescribed it would actually look more like the below… yes, it’s only 4px difference in total, but consider the impact of this across every element on the page. The larger the font-size, the larger the line-height, the larger optical margin.
For a developer to implement the design as it appears optically, they would need to reduce the paragraph margin to 12px as shown below. This achieves the intended design (apart from the text sitting 2px lower than they might have thought), but suddenly you have a spacing unit in the frontend that you as the designer are unaware of.
This divergence will cause issues with everything you design in the future and, if you’re working on a team with multiple developers who may or may not do this, inconsistency within the same application or website.
Of course all of the above has an impact on a baseline grid. If the units are changed or the design doesn’t consider the real world box model for type then there is no chance you’re going to hit any type of horizontal grid.
Creating a true baseline grid in CSS as you might be used to in print software, while possible, is arguably not worth it.
It’s much easier to just consider the bottom of each block as the thing that needs to hit your horizontal grid increments. This works for all content, because remember, EVERYTHING is a box.
I’m sure there’s a technical error or two in here, but ultimately following the intent of this article in your design work will lead to a much better relationship with the frontend developers on your team, not to mention higher quality, consistent output!