You may have heard that when defining the size of things in your website, you should be using
rem units, rather than good old fashioned pixels.
You’ve probably heard mumblings like ‘accessible’ and ‘fluid’ and ‘flexible’ and thought it sounded like a pretty good idea. Maybe you even feel like using only pixels is an amateur move.
Well I have some fantastic news for you. You don’t need to mess up your life with these pesky units.
Pixels are just fine. In fact it turns out that pixels are really good at defining the size you want things to be.
In an ideal world, everyone would just believe everything I say without me having to back it up with ‘evidence’. But I have been told this is not the case, so please, follow along as I begrudgingly assess each of the reasons for using these flimflam units of measure.
#1 It’s better for accessibility
Or more specifically: “use rems and your layout will scale better if the user zooms.”
People tend to overthink accessibility. I saw a question the other day (a YouTube comment no less) — someone looking for an “accessibility testing tool”. Something “more thorough” than just a WCAG compliance thing.
Here, I made one for ya:
I also sell a bigger one for monitors up to 30" (it’s a towel). Then there’s the “universal” model, which is a pillowcase for your head.
My point: you don’t need in depth knowledge and fancy tools for working out if rems and ems are ‘better for accessibility’* — just imagine that you are someone with bad eyesight. If you have a terrible imagination, wrap your screen in ClingWrap (or whatever you call ClingWrap in your weird country).
*Of course accessibility is not just about readability, but that’s what we’re talking about here.
Now ask your ill-sighted self, which of these three things would you do to make your computer more readable:
- Change the default font size for your operating system. This makes all text, menus, the clock, other apps, and web page text bigger.
- Zoom on individual web sites that have particularly small text.
- Change the default or minimum font size in your browser settings.
I don’t know about you, but if I had trouble reading small text, I’d bump up the default font size for the OS and forget about it.
(Handy for presentations, too.)
Let’s dive a little deeper…
For the sake of investigation, I’ve whipped up a simple demo site. (Here’s the jsbin if for some inexplicable reason you’re interested.)
This is how they all look at the default zoom (where 1em = 16px).
Here we are, Chrome in Windows, with the OS text zoom at 150%.
Next up, I’ll set the OS zoom back to 100% and turn the browser zoom up. This is for sites that think 12px for major navigation text is acceptable because you can fit more on the screen. Not naming any names, but …
It’s Amazon. 13px default font-size, 12px for some top level navigation. Uncool.
Luckily, browser vendors don’t share Amazon’s disdain for the elderly, and allow you to zoom with little more than a keypress and a scroll.
I’ve got eyes like a beagle and still I zoom for some sites. I do it for the Chrome DevTools too, the default font size is 12px, but somehow I forgive.
(Side note: if you find the font-size on Wikipedia a bit small, or don’t like the way the text stretches the whole way across the page, I apparently wrote a Chrome extension called Skinny in 2013 to keep text lines short and give wikipedia a font-size bump.)
Back to it. Let’s take a look at those examples with the browser zoom at 150%.
The browser UI (tab name, URL etc) is small again, but the page content looks the same.
And finally changing the default browser font size. We’ll try Firefox first, here it is with no zoom:
And after setting the ‘minimum font size’ to 20px:
The nav is narrower in the px version, and the header text is a bit bigger.
And here we are in Chrome with the text size set to “Large”.
Aha, finally a significant difference. The title that was hard coded to
18px has not changed size, nor has the width of the teal navigation menu which is set to 100px wide.
You might think this is a clear win for rems, but it ain’t.
Although we have no evidence as to whether or not people rely on changing their browser text size, we do have some indisputable facts.
- We know for sure that changing browser text size has no effect on facebook, youtube, amazon, twitter, medium, linkedIn, eBay, and I only got halfway down the Alexa top 100.
- So, we know for a fact that if someone can’t read 16px text, and they want to use one of those sites, they must use some other method.
- We also know that changing browser text size has no effect on the rest of the operating system, obviously.
- So again, we can deduce that if a user can’t read 16px text but wants to be able to read Excel menus, mail, system settings, finder/explorer, whatever else, they need to do that in some other way.
The above facts, to me, make it crystal clear that browser text size adjustment is of no use in the real world. And so I will not take this setting into account in my decision making process.
That’s the ‘better for accessibility’ argument blown out of the water, now moving along to …
#2 Breakpoints scale when you use rems/ems
Or to put it another way, if you define your breakpoints in pixels, they are fixed and won’t change if your users zoom the page. Because a pixel is a pixel, right?
Well that’s just a lie. (I’m guessing that at some point in the past it was true, people don’t just make things up, do they?)
My gorgeous example site has a breakpoint at
600px. That’s set as
37.5ems for the middle one and
37.5rems for the bottom. With no zoom, these all equate to 600px.
Below this size, the sender and subject text is stacked vertically, above this they are side-by-side.
Let’s fire up IE11 for a change of pace. I’ll zoom the page to 150%, then drag the window so it’s juuuust about 900px wide. (For the mathematically challenged, that’s 600px × 150%.)
So, what do you think IE11 will do?
Will it think that the breakpoint is absolutely at 600px at all times, and therefore show the big screen view? Or will it adjust that breakpoint by 150% so the change occurs at 900px. In that case we’ll get the small screen view (text vertically stacked)?
Well, I was surprised enough to find that IE did indeed scale my breakpoints as I zoomed.
And this is way back in IE11. What about some other browsers…
Safari did exactly what I expected. (Be weird.)
It scaled my 600px breakpoint reasonably, but not quite to 900. It’s good enough though, here the window is plenty wider than the 600px breakpoint, but with the zoom at 150%, all three have displayed as though they were below the breakpoint.
So if you’re worried about your breakpoints not scaling if you use pixels, don’t be. Or at least go and find a browser that doesn’t scale them, and make a decision based on its browser share. If you must support IE8, and it turns out that it doesn’t scale breakpoints you may have a legit reason to use rems. (Of course IE8 doesn’t support media queries or rems, but let us not dwell.)
#3 Use ems for ‘dynamic’ spacing around text
This is almost a good idea, I see where the proponents are coming from. “Why change font-size and padding, when you can use ems for the padding, then only change the font size?” they say in their outside voice.
I get it, I really do. I just prefer to be precise and set, say, the font-size and the padding for a button so that it’s exactly 60px tall on big screens, and exactly 50px on small screens, visually matching my exactly 60px/50px header bar.
And if my designs are coming from a professional designer, I’m yet to come across one that doesn’t care exactly what size a button is. Does such a creature even exist?
But if you’re designing a site yourself, and don’t really care exactly how tall that button is, or exactly how far your paragraph text is from the heading above, and want the spacing to grow as the font-size changes, then using ems for margin/padding is the right tool for the job.
Now, on to one of the more baffling ‘reasons’ for using rems and ems. (I don’t know why I’m numbering these headings.)
#4 Make modules that you can resize simply by changing the root element font-size
These words that you have so graciously been reading were spurred by a blog post that came out a few weeks back, Design a responsive site with em-based sizing.
It explains (accurately) that by using a combination of rems and ems, you can create a component (say, a modal window) that can scale to different sizes just by changing a single font-size on the root element of the component.
It makes sense. In the same way that “if you often murder people, it is handy to carry a shovel in the boot of your car” makes sense.
It’s great advice I’m sure. But I can’t remember the last time I did a murder, and I can’t recall the last time I wanted a component that grew in all dimensions, paddings and font-sizes, by the same factor, by changing just one value.
So here’s my advice. When you’re starting a project, ask yourself: will I need to create any modules that will sometimes be a certain size, and other times be exactly 10% bigger in every dimension. If the answer is yes, follow the advice in the blog post above, it is exactly what you are looking for. And carry a shovel in your boot, ya psycho.
You can scale all the text on your page with one property
(I’ve decided not to number the headings anymore.)
Another befuddling reason to use ems goes like this: you have defined
font-size in your CSS in, totally, like, 50 different places. You want all 50 to be bigger on bigger screens, and smaller on smaller screen, and that’s a lot of media queries.
This is apparently best solved by using rems everywhere, then changing the root font size in your media queries. Boom! All your text will change size at once.
I think this advice can be safely ignored for two reasons. I shall list them for you.
- It assumes that you want to increase/decrease all text on your site at the same time for a given breakpoint. Headings, menu items, body text, all at once, all by the same factor. Now that’s courage.
- The real problem here is that you’ve got
font-sizedefined 50 times. If this is you, you need to get your typography organised. Oh no. Do you hear that? That’s the pounding hooves of a typography rant…
Here’s the thing, when you have a separate file just for typography, and you have, say, 12 styles in there, and for each style you have different sizes for four screen sizes, that’s 48 different font-size declarations and probably line-heights, maybe margins and letter-spacings too. As Winston Churchill once said, “that’s a lot of stuff”.
Now, it’s easy to see all this and think “oh no, that’s a lot of repetition, we need to do this a different way — no matter what the cost — to avoid repetition.”
I disagree. A lot. Too often I see complexity introduced into apps in the name of The Almighty DRY. Don’t underestimate how much complexity is introduced when you mix multiple units. NASA used two different units on their Mars orbiter, and they still can’t find it.
Don’t let your website get lost in space.
Oh and it’s not just different units, but having text in some part of your app that changes size based on the
font-size in some other place? That’s the antithesis of encapsulation, it says pish to determinism, and is just generally asking for trouble.
So… think your typography through, set it up once, do it in pixels, cope with a bit of repetition, bask in the certainly that your text will be the size you told it to be, then forget about it.
That rant went on for much longer than what you just witnessed, but I wrote the rest out in a letter and didn’t post it.
I think it all boils down to this: there are times when you should use rems and ems — they’re in the spec for a reason. But the scenarios in which you need them are fewer and farther between than the prevailing wisdom would suggest.
So don’t go looking for a reason to use ems and rems. It is enough to what they do. Use pixels, and if a scenario pops up where ems or rems are the better tool for the job, go for it.
Bonus round; on the topic of units
The below have little to do with this article, so I shall list them with no real explanation of what they’re doing here and offer no further outro. It will be unsatisfying.
- If you have two adjacent bits of text and want the padding between them to be like a space, try
1chon for size.
- If you want your body background color to fill at least one page vertically, try
100%. But in general if you’re going to use
vh, you better test real hard on iOS devices.
- Did you know vertical-align can be a percentage? If you find that
topisn't lining up just the way you want it, don’t go adding something nasty like
top: -3px. Instead try
- When it comes to flexible layouts, don’t forget about flex-grow and flex-shrink. It might be a bit tricky to wrap your head around them at first, but just like a giant lollipop, they’re worth it.