Skip to content
This day’s portion

Some notes on measure (or line width) on websites

| Comments | Post

Measure is a typographic term for line width. It’s one of the key elements of micro-typography on the web – along with font family, font size, leading (or line height), letter and word spacing and font weight. These elements are fluid (especially on screens) and a mixture of (near) science and art. They also affect each other.

An example paragraph from my website.

The measure on this website.

In this article I’m concentrating on measure and how it works with longer texts, such as blog posts.

What we’re trying to achieve

Our most important task is to make our text as comfortable to read as possible. That may seem obvious, but sometimes we might change our measure for a different reason – normally to make our text look better. For example, we might want to make the measure wider so our blog post doesn’t leave acres of white space on a wide screen monitor. Conversely, we might make it narrower in order to lengthen our paragraphs, thereby creating a less fragmented looking text.

It’s worth introducing a principle here that will apply to all our web typography: We design text to be read, not looked at.

How we read

When we read our eyes fixate on points within a line of text for about 100-500ms, taking in information. The movements between these fixations are called saccades, and last for 20-40ms. Note that we also regress, i.e. return to previous points within the text. Saccades are one of the body’s fastest actions.

Reading is therefore not a smooth process; it consists of a series of sudden, muscular movements between moments where the eye stops and takes in information. When we reach the end of a line, and are satisfied we’ve understood it correctly, the eye then has to make a longer, backwards movement and locate the next line. This combination of sudden back and forth movements within lines, and longer, sweeping movements between lines is what makes reading tiring.

What measure needs to do

Our measure needs to find a balance between the number of saccades, regressions and shifts between lines. Note that the actual line length on a screen is mostly unimportant, which is one reason for using a relative unit (e.g. em or rem) when declaring our line width.

Fixations don’t fall precisely between words, but the more words you have in a line the more movements you’ll need to read it. Some guides will suggest an ideal measure in terms of characters, but because of the relationship between the number of words and saccades and regressions, I prefer to express this as a number of words. Note that this means that some languages will require wider measures than others because of their word length; German requires a wider measure than English, for example.

The ideal reading measure is 10-15 words per line.

Setting measure

Because people read differently, and lines of the same length will consist of different numbers of words depending on the content, writer and their style, this is a matter of judgement. The best way to find the right measure is to experiment: use a real text and count the number of words over a series of lines with different measures.

An example paragraph from my website.

Use real text to guage the ideal measure. This text consists of lines of 11-14 words.

We can set our measure using the CSS max-width property:

.measure {
	max-width: 30rem;
}

And then use this HTML:

<article class="measure">

	<!-- your article -->

</article>

By using rem rather than px our measure will always be relative to the font-size we declare on our html element. If we decide to change our base font-size, the measure will change accordingly. Take this example:

html {
	font-size: 118.75%; /* Will probably compute to 19px */
}

.measure {
	max-width: 600px;
/* Will always be 600px, regardless of our font-size.
This is probably OK when the font-size is 19px */
}

.measure {
	max-width: 30rem; /* Will probably compute to 570px */
}

Later, we might want to change our base font-size. See what happens:

html {
	font-size: 150%; /* Will probably to compute to 24px */
}

.measure {
	max-width: 600px;
/* Will always be 600px, regardless of our font-size.
This means fewer words per line when our base
font-size computes to 24px */
}

.measure {
	max-width: 30rem; /* Will probably compute to 720px */
}

Always use max-width rather than width. If we use width the measure will remain the same, regardless of our screen width. This could cause a horizontal scrollbar to appear on a mobile phone screen.

A note on large font sizes

In my experience, the actual width of a line of text on a screen is largely unimportant – it’s the number of words in the line that matters.

You’ll find some websites use really large fonts, which will result in wide lines, especially with a generous max-width. Take this example:

html {
	font-size: 150%;
}

.measure {
	max-width: 40rem;
}

This will probably give us a maximum line width of 960px. This is not necessarily anything to worry about as our number of words per line, saccades and regressions would be the same if the font-size was set to 100% and the line width computed to 640px. It does affect our leading (or line height), but that’s for another article (remember, all of these micro-typographical elements relate to each other).

A note on narrow screens such as phones

So far we’ve been talking about setting a maximum width to establish our measure. On narrow screens, such as many mobile phones, we probably won’t hit that limit, and therefore won’t achieve our golden range of 10-15 words per line unless we set our font-size to something low, perhaps even below 100%.

Butterick advises we take this approach:

Regardless of screen width, the optimal line length is still 45-90 characters. As you test your layout, make sure that text elements stay within this range.

I don’t agree. We’re faced with a decision here – either we reduce the text size so it results in a 10-15 word line length, or we maintain a good font size, probably resulting in a measure of 5-7 words. I’d argue font size is more important than measure in making our text as readable as possible. Make sure you set a legible font-size for narrow screens and accept the measure won’t be ideal. Also bear in mind you’re going to get different results across different devices, so try and test on at least one low end and one decent phone.

Art and science

Hitting on a good measure is dependent on a couple of set factors, namely font-size, and your typeface’s proportions. Take this example, where we use this CSS:

html {
	font-size: 118.75%; /* Probably 19px */
}

.measure {
	max-width: 30rem; /* Probably 570px */
}

But note the same text doesn’t result in the same number of words per line when we use different typefaces. IBM Plex Serif gives us 7-8 words while Source Sans Pro works out at 8-10:

The same paragraph and proportions in two different typefaces.

IBM Plex Serif is a bigger font than Source Sans Pro.

This is because IBM Plex Serif has larger glyphs than Source Sans Pro. As a consequence, you’d probably use a bigger max-width with IBM Plex Serif.

So that’s the science of measure, but we also need to consider how a text feels. This is largely a matter of taste – sometimes a slightly wider line just looks right with a certain typeface, or within a certain layout. Humans are fairly resilient when it comes to reading, and can deal with a wide range of different typographical factors. This provides an opportunity to say something beyond the actual words – as long as readability remains our primary concern.

Add a comment

Required fields marked *. I won’t publish or share your email address.

Comments

None 🦉.

Mentions

Comments and replies to this post from other sites and services, such as micro.blog and Twitter.

Jessica Smith

So, this is not the ground-up overhaul I mentioned wanting to do in yesterday’s entry. (If it was, there wouldn’t be so much wasted horizontal space on desktop.) However, if there’s one thing that’s true about myself, it’s that sometimes my brain just won’t let go of an idea. Even if it was something I had no intention of doing any time soon, once my internal monologue starts going, “Hmm, but I wonder if a good starting point for X would be to do Y… let’s just try it out, what harm could it do?” if I don’t hit any obstacles I’m an unstoppable force. I was in such a state of “flow” last night that I was working on this for about six hours straight… until 2:30am… and after I woke up this morning I went almost straight back to work and took minimal breaks all day. However! I’ve accomplished a lot of good shit that I’m very pleased with! Allow me to give you a brief tour.

Nord Theme

As you’ll see straight away, I’ve changed the colour scheme. Where previously I had a mostly-greyscale theme (only link colours standing out), I’m now drawing on the numerous blues of the Nord theme. In the default, light theme, the main column now features #4c566a (mid- to dark-blue) text on a #fafafa (almost-white) background. Should be just a little bit softer than the stark #000 text I had before.

There’s less contrast now between the colour of links and the regular text colour, so links are now softly underlined to add a little bit more visual distinction. (They are still bold, as well.) I’m using the red Nord accent colour as a link-hover colour.

a screenshot of my website's homepage, with Nord Light theme active<h2>Dark Mode</h2>

But as some of you will have noticed already, I’ve also introduced dark mode! For this, I’m using #d8dee9 text on a #3b4252 background (that is, the darkest shade of the Nord “Snow” colours on the second-darkest of the Nord “Polar” colours). Most links are one of the Frost accent colours (I labelled it aqua…) and the nav-bar and link-hover colour are the yellow accent colour.

As was probably pretty clear yesterday I’m not exactly a dark mode connoisseur, but my humble opinion is that this is right up there with the most readable dark mode schemes for me… and not ugly, or anything. The underlines and soft horizontal rules that I like to use to demarcate different pieces of content are still nice and subtle, the accent colours look nice together, and overall I’m just pretty happy with it.

a screenshot of my website's homepage, with Nord Light theme active<p>As for implementation, I decided to take the easy way out: I made my light-mode layout first, then created a dark-mode.css stylesheet to override all the colours for dark mode. I link to it from my head section like so:1</p>

<link rel=stylesheet href="/css/dark-mode.css" media="screen and (prefers-color-scheme: dark)">

So, if you actively have dark mode set on your device, you’ll see my website in dark mode. If not, you won’t. There are lots of sites out there that have implemented Javascript switches so people can toggle between the two modes at will… I haven’t done that, cos it looked a lot harder than just adding an extra spreadsheet with a media query, but it’s on my “maybe one day” list. My priority was more catering to people who feel that light mode themes strain their eyes, and have expressly set their system preferences accordingly.

Typography

This is another thing I’d wanted to improve for a while, at least for the whole, uh, 12 days since Leon Paternoster wrote this fantastic article on measure – the interplay between line widths and font size. He writes that ideally, your content column should be at such a width that each line has 10–15 words on it.

My old layout definitely had more than that. Obviously line-by-line word counts vary but my quick counts had it averaging about 20 words per line. Also, now that I was aware that this was a thing, suddenly I really noticed it every time my eye went back to the start of the wrong line when I went back over my own posts! So, when I embarked on this revamp, I decided to bump the font size up from “medium” to “large”, and set the width of the main column to 40rem (which comes to 640px in my browser, with the Charter font I’m using, but YMMV).

Better Responsive Design

The last edition of this layout was the first-ever responsive design I’d ever made, and it was OK. But it wasn’t good. There were a bunch of random little quirks that made it obvious (at least to me, browsing my own site and knowing exactly what went through my mind as I coded different things) that I’d built for desktop first, with mobile as an afterthought. Considering that approximately 40% of my visitors are browsing on a mobile screen (and another 7% on tablet-sized screens), I thought that was a pretty large chunk of visitors that I could improve the experience of.

Some of the changes were somewhat minor things. For example, previously, my main column had a width of 90% of the viewport, up to a maximum of 820px. But if someone’s browsing on a 375px phone screen, there’s no reason for them to lose 5% of space at either side plus the 10px of padding within the column itself. So, for visitors on screens less than 435px wide, the main column will now take up 100% of the viewport. I also took away the rounded corners on the footer and nav bar, because it didn’t really look as good when they were curving into the edge of the screen. Compare below the old layout (on the left) to the new one (middle and right):

<img src="https://www.jayeless.net/2021/08/my-new-theme/mobile-posts-old.png" alt="a screenshot of my posts page with the old theme active, as seen from mobile" /><img src="https://www.jayeless.net/2021/08/my-new-theme/mobile-posts-light.png" alt="a screenshot of my posts page with the Nord Light theme active, as seen from mobile" /><img src="https://www.jayeless.net/2021/08/my-new-theme/mobile-posts-dark.png" alt="a screenshot of my posts page with the Nord Dark theme active, as seen from mobile" />

After I increased the font size for desktop viewers, I realised that this made the text too big on mobiles, leaving far too few words per line. So below that 435px threshold, I decreased that back to the “medium” size that it was before (as you see in the screenshots above).

Then I also fixed some pages that looked pretty wonky before – particularly individual recipe pages and the “reading” and “book review” list pages. The book review list is particularly finicky because of the way I have title, date, genre and series labels all kind of overlapping on the same lines and the book cover right there… 🤯 Anyway after a lot of trial and error and calculations, I think I got it right. They look a lot better now.

<img src="https://www.jayeless.net/2021/08/my-new-theme/book-reviews-old.png" alt="screenshot of the old book reviews list, with all the book covers teeny-weeny" /><img src="https://www.jayeless.net/2021/08/my-new-theme/book-reviews-new.png" alt="a screenshot of book reviews list in the new theme, with the book covers looking a much more proportionate size now" /><img src="https://www.jayeless.net/2021/08/my-new-theme/book-reviews-newdark.png" alt="a screenshot of book reviews list in the new theme in dark mode, with the book covers looking a much more proportionate size now" /><img src="https://www.jayeless.net/2021/08/my-new-theme/recipe-old.png" alt="screenshot of a recipe with the old layout – a style glitch makes the word ‘A’ from the recipe description appear next to the photo, well away from the rest of the description" /><img src="https://www.jayeless.net/2021/08/my-new-theme/recipe-new.png" alt="a screenshot of the same recipe with the new layout in Nord Light theme – the glitch is fixed, the image is centred and the description appears in one piece below" /><img src="https://www.jayeless.net/2021/08/my-new-theme/recipe-newdark.png" alt="a screenshot of the same recipe with the new layout in Nord Dark theme. the glitch is also fixed in dark mode" />

SVG Icons

On my home page, and at the bottom of every blog post, I include some social media icons to let people know where they can interact with me. Previously, these icons were dark grey. That clearly wasn’t going to work for dark mode, and even for light mode, my preference was that they not still be grey. Yet this raised the question: with the only difference between my themes being an extra stylesheet, how was I going to make the icons different colours in the different modes? I thought about downloading two sets of icons, each one in a correct accent colour for its respective mode, and setting one to display: none; in each stylesheet so only one would display at a time… buuut I hate non-semantic workarounds for things that should be strictly style issues.

So, I embarked on a different path. I knew there was some kind of CSS fill attribute to colour in SVGs, but I didn’t know how it worked. Looking it up, I decided to not even pursue that strategy because I found a better way: within the SVG file itself (because they’re really just XML files!) you will find this attribute fill that can take the value currentColor. As in, you can fill shapes within an SVG with the current text colour by editing the source code to the SVG itself. omgggg.

This does not work, however, if you embed the SVG in an <img> tag. I guess because there is no “current colour” within the SVG file itself, only in the page embedding it. However, HTML5 lets you put the <svg> tag directly into your web page if you want; you don’t need to use <img>. And by putting it in directly, it does inherit the colour.

So, because I’m using Hugo, I moved the SVG icons I’d downloaded from FontAwesome to my /layouts/partials directory, and renamed the .svg suffixes to .html. Then I included them as partial layouts! For example, this is the part of my home page that links to my social media profiles:

<nav class="sm-profiles">
	<a href="https://micro.blog/jayeless" title="@jayeless on Micro.blog" rel="me">{{ partial "icon-microblog.html" .}}</a>
	<a href="https://toot.cat/@jayeless" title="@jayeless on Toot.cat (Mastodon)" rel="me">{{ partial "icon-mastodon.html" .}}</a>
	<a href="https://todon.nl/@jayeless" title="@jayeless on Todon.nl (Mastodon)" rel="me">{{ partial "icon-mastodon.html" .}}</a>
	<a href="https://www.instagram.com/jayeless/" title="@jayeless on Instagram" rel="me">{{ partial "icon-instagram.html" .}}</a>
	<a href="https://twitter.com/thejayeless" title="@thejayeless on Twitter" rel="me">{{ partial "icon-twitter.html" .}}</a>
	<a href="https://www.goodreads.com/user/show/7451465-jessica" title="Jessica on Goodreads" rel="me">{{ partial "icon-goodreads.html" .}}</a>
</nav>

And you can go check the source code for my home page if you want to see what the result is. (Spoiler: some long lines of code.) Updating my syndication link template was harder because I had to learn how to concatenate strings in Hugo (seriously, it has no business being that hard), but I still managed it. At any rate, this way, no matter whether you view those icons in light mode or dark mode, they take on the correct colour for links in that respective stylesheet. From now on I can also change link colours freely and the icons will just change automatically without me having to re-customise or re-download or anything. Happy days.

<img src="https://www.jayeless.net/2021/08/my-new-theme/sm-icons-light.png" alt="screenshot of a section of my front page in light mode, showing dark-ish blue icons" /><img src="https://www.jayeless.net/2021/08/my-new-theme/sm-icons-dark.png" alt="screenshot of a section of my front page in dark mode, showing a more aqua shade of icons" />

Responsive Images

Honestly, this topic is one I should write a separate entry about. However to summarise, for several months now, I’ve been using a Hugo shortcode to automatically generate responsive images, and enable visitors to load the most appropriate size for them, depending on what screen size they’re browsing on.2 The trouble is, because I was changing my column width, I had to redo it. On the bright side, since I was redoing it anyway, I got to make some changes. In particular, I dropped the number of sizes I generated down from six to four five – just 320px, 440px, 640px and 1280px (enough to span a quarter, a third, half or the full width of this column on a full-size screen at 2x pixel density, like on my MacBook) – and 830px, which I called the “iPhone special” size in my code because it’s mainly to spare mobile browsers (with 2x pixel density and screens wider than 320px) from having to download the 1280px image.

Anyway, since I was changing things up anyway, the main thing I wanted to try was generating images in WebP format instead of JPG, because Hugo has supported this since May’s 0.83.0 release, and WebPs reputedly offer a significant improvement to file sizes. I was still going to generate a “fallback” JPG image at 640px, because ~5% of users still cannot see WebPs (particularly, MacOS Safari users who are still on a pre-Big Sur version, and iOS Safari users on 13.x or earlier).

However, what I found was that WebP only really offered a saving at larger sizes. With the two smaller sizes the two formats were on par, and at the 640px size, WebP was only ~10kb smaller… not really enough to justify having to generate two 640px images. So, I scrapped WebP for 640px and below. Browsers that can’t handle WebP can fall back on the 640px image, which is enough to span the width of this column at full size at 1x pixel density, after all.

What all my testing on mobile has taught me, though, is that it’d be a really good idea to give mobile visitors a way to click an image when there are 2–3 in a row so they can see it bigger. Half or one-third of a mobile screen turns out to be a lot tinier than the same fraction of the full-width column on desktop, who’d have thought?

Update photos, icons, favicon

This was just me tinkering once I’d got all the important stuff done, but:

  • I replaced the photo of me on the front page with a more current one (where you can see the lovely waves I’m cultivating!),
  • updated the photos on my “about” page with some newer and higher-quality ones (plus rewrote some text there),
  • replaced the photo in my h-card (that mini-bio at the bottom of posts and list views) with the avatar from my favicon because at that small size it looked better, and
  • used my newfound knowledge about SVGs to recolour that avatar in the Nord palette. That avatar was made with the free tool Avataaars by the way, just to give them credit when an easy opportunity arises.

Wow!

Honestly, if you made it through this post, you deserve a medal. While there are still, as I mentioned, further refinements I want to make, I’m overall very happy with what I’ve accomplished and, also, extremely tired and eager to catch up on lost sleep from last night 😂 It’d be sooooo easy to stay up hours more taking away 10px padding here, adding 2px padding there, and so on but I think I’ve just gotta call it a day and finally push my masterpiece to production. If only I knew how to harness this unerring concentration and channel it towards doing things purposefully.

  1. Before you even say anything, yeah, it looks like one of my jobs for the near future is working out how to customise Hugo’s in-built syntax highlighting. ↩︎

  2. I didn’t do it for this post though because my shortcut generates JPGs which seems suboptimal for PNGs. Sorry. If it was not 1am I would invest more effort into rectifying this. ↩︎