Design Systems Hot Takes

Font size dimensions

6 min read

First, we used pixels to describe the size of things on the web. Most digital tools and technologies communicated in pixels so this seemed like a logical decision to use. Over time, we’ve received other units in CSS that were relative to some other amount. Percentages were based on the parent element and many other units were based on font size.

The use of font size was highly misunderstood across our practice for years. One of the earliest concepts was converting (r)em to pixels since many people weren’t familiar with the new units, but saw benefits to using (r)em in other areas outside of updating the size of the font. Unfortunately, this eventually turned into the bad practice of setting font-size: 62.5% on the html element.

Space

In my later work, I did adopt the concept of using (r)em to define elements outside of font size, specifically space. This looked promising since areas that had larger typography also typically have larger spacing. However, I’ve more recently walked that back. This is because of accessibility.

If we decide to use font relative units to define space and a user decides to increase the font size of the text, this would also increase the amount of space between elements. This would make the overall composition very large. I realized this while exploring Complementary Space, because I could separate what space meant at different regions. It made more sense to keep the amount of space effectively static (using pixels) between elements as long as the perceived hierarchy was maintained. As an example, as long as the space found in the hero section was larger in relation to the space found in table cells, the text could be sized up for legibility while maintaining the essence of hierarchy. This would keep the overall layout smaller while allowing the text to be as large as the user needed.

Width

Another place where people tend to try using relative units is for defining the width, either explicitly or as a limit. One of my principles for composition layout is to not define widths and let the content dictate the size of its container. This isn’t always possible. One common example is when using display: grid. I tend to use the repeat(auto-fit, minmax()) technique to define columns dynamically and this requires some dimension for the minimum or maximum. Most of the time I set this as minmax(260px, 1fr) for card containing layouts and the 260px has very much been a LooksGood™ value that I didn’t put much thought into.

So are relative font units helpful or hurtful when defining width? To get an answer we need to understand why we are setting a value for the width at all. Generally, we set a width on an element so it maintains an expected size, but why? As a thought experiment, we can consider an element primarily made up of text, we want the text to have an optimal reading composition. Lines that aren’t too long but also lines that aren’t too short. This also depends on the kind of content. Optimal line length for long form articles is around 60 characters, give or take. We can use that number to set a maximum width for the article; 60ch.

We don’t need to go too much further to see that the number of characters is something we take into account when speaking about the width of an element. We can imagine this in the opposite direction, if the element is too small, the lines look smooshed. Here’s where we find the key insight. If we defined the width of an element using relative font units, and the user increases the font size, what happens? Think about it.

Let’s use 30ch as a maximum width, which is approximately the 260px value from earlier, not counting the card padding using common font metrics for the body. As the user increases the font size, what 30ch means will also increase as pixels. This means that the 30 characters will continue to be 30 characters, just larger in pixels. Visually, this would look like if we scaled the whole element up. This maintains the overall composition as the font size increases.

On the other hand, if we used a 260px maximum width, the sheer size of large text would wrap too quickly, causing premature line wrapping because the pixels aren’t increasing with the size of the text. For this reason, I now recommend using relative font sizes, more specifically (r)ch units, to define widths. That is, if you truly need to define a width at all. For me, the best case is to still avoid setting a width wherever possible and let the content dictate the size.

Breakpoints

The reason that I had the idea for this article is due to this post on LinkedIn by Matthew Wood. He explains the advantage of using (r)em for media and container queries. He outlines how the approach helps support specific articles within the WCAG, 1.4.4 and 1.4.10.

Due to the common use of minimum and maximum widths in breakpoints, and our earlier exploration into the benefits of maintaining layout composition when using relative font units for this, I can agree that using relative font units for breakpoints would be preferred over pixel values. That is, if you need breakpoints at all.

As I wrote years ago within Gridless Design, the web was made to flow like a document. So if something doesn’t fit, the best way to handle it is to let the element wrap underneath. The more custom you want that behavior to be, the more difficult it is to appropriately handle how it is meant to behave for different user preferences and devices.

Summary

These are my new rules of thumb based on the earlier explorations:

I wouldn’t consider these rigid, but I would refrain from deviating unless you truly understand why.

And for heavens sake don’t make tokens for dimensions. Dimensions are specific to the layout. This includes breakpoints because when the layout breaks isn’t due to being a specific device. It’s because the current composition visually breaks at this point. Unless you’re making tokens to define the parts of layout, avoid making tokens for dimensions.

Accent Color