All your base, are belong to us — or what base size do em-based media queries use?

by Stephanie Rewis on March 10, 2015

Yesterday, we had a discussion at work about rems, ems and percentages. I’ve used ems for media queries for years. I’ve used rems for font sizing for a couple of years. I felt like I had a pretty good handle on how it all works.

Most of you probably understand the difference, but let’s do a quick recap to refresh. When sizing using rem units, the sizing is based on the HTML element’s font size. When sizing using em units, the sizing is based on the parent element’s font size.

Here’s an em unit example: I’ve created a module named .foo and it contains several other elements. I want the heading inside to be 32px, so I set it to font-size: 2em. If my body font size is equal to 16px, and as long as I’ve set no font-size on the the .foo module or any ancestor of it, it will be rendered at 32px. However, if the .foo module or an ancestor has the font set to “font-size: 14px;” or “font-size: .875em;”, that new size (from the ancestor element) will now cascade to the heading inside as the base to compute by, and our 2em heading will be rendered at 28px.

This is the reason many of us moved to rem units. It’s more reliable to set the font-size on the html element and, if left at the 16px default, you can be confident that setting a heading size to 2rem will always give you a heading rendered at 32px. If you’re the only person writing the code in the site, you can get that same effect with em units by having a rule set in stone that you never, ever, ever set a font size on anything other than type (p, hx, lists, etc). But that’s in a perfect world where you control all the code and never pass it off to another developer. If you do work with other people, things can become messy and unreliable.

This brings me to the reason for this post — using em units for your media queries. Much has been written about it over the years, but the short story is — for reasons related to content and line-lengths — I use em units for my media queries so that the breakpoints adapt to changing font sizes. If the user changes their default, or zooms the browser, all my breakpoints react to this new font-size base.

So what’s the big deal with the break points?

Based on yesterday’s conversation, I was doing an experiment. Since all my font-size, padding, margin, etc, is set in rem units, changing the size of the HTML element should scale the whole design either up or down. And it does. However, I expected it to also change the em-based breakpoints. It does not. I experimented with changing the size of the HTML element or the body element (sometimes even to straight up pixel values) and the breakpoints remained sized based on 16px. #headscratch (Here’s my Codepen to play with if you like:

After testing this several different ways, I did what one does — I reached out to the Twittersphere — the fount of all obscure knowledge. Within two minutes of posting, @susanjrobertson set me in the right direction: I tested her theory, and by cracky, she was dead on! Fact is, the em base in media queries comes from the user’s setting (which is the 16px browser default if not changed by the user). The author has no control over this at all! Giving this some thought, it makes total sense. If my user has changed the default size of their browser to 32px because they have low vision, their line lengths will be shorter unless my media query breakpoints are now also using a 32px base and change accordingly. The same applies to zooming in the browser, I want my media query breakpoints to change based on their zooming. (Lyza Danger, who likely wrote the article I read years ago that got me started with using em-based media queries has updated this week to state that browsers have fixed zooming.)

The moral of the story is — your media queries, sized with em units, are going to be based on 16px per em unit — unless the browser’s font size has been changed by the user. You can not override the user’s wishes. This means that the idea of scaling a whole design by changing the HTML element’s default size (maybe up to 18px, or down to 14px) will not change your media queries base size. It absolutely will scale your whole design to use any base size you desire (when all your values are rem based) — but your media queries will still be based on 16px. So in my opinion, it seems best to keep the HTML element at 100% (16px) so that it matches the em units of your media queries (or the overrides of your user).

12 Mar: Edited for clarity & to update with Lyza’s update!

{ 6 comments… read them below or add one }

Lu Nelson March 12, 2015 at 2:45 am

It’s not a disadvantage. EM units at the media-query level are not affected by html-scale because they refer to the medium: i.e. device-scale (outside the html). You can set html font-size in EMs too, which is logically consistent. User-set device-scale just means you can’t assume a PX value for anything in your design unless you specifically size it in PX (and even then often not); and that best policy is to set html font-size in EM or %, which is relative to device-scale, and then set anything inside the html scope in REMs, which is relative to html-scale. This forms a relative-size chain: nothing breaks, user/device-scale can be anything, and HTML font-size can be anything, media queries always trigger where they should.

wicek3d March 12, 2015 at 3:55 am

Hey, thanks for this article.

I’m unclear about using rem in media queries instead of em – how would that impact the website layout while zooming or changing the browser window?

Stephanie Rewis March 12, 2015 at 2:44 pm

Thanks Lu, that’s exactly what I found. I guess I’d just never thought about WHERE the em-based media queries were grabbing their base value from. And it makes total sense that it’s outside the HTML.

@wicek3d – rems don’t work for media queries. I used to think that was a bug. But it makes total sense now, since rem units are based on the HTML element size, and media queries are computed from the user’s base size (which is prior to the HTML element is involved).

brothercake March 12, 2015 at 4:59 pm

This is exactly the reason for using em breakpoints :-)

RE: using flexible units for padding etc. — I’m increasingly convinced that that’s not a good idea. It creates a flexible layout that allows the whole thing to scale with text size, but I don’t think that’s a desirable outcome — because although it may look nice, it’s a waste of space.

Users need to be able to scale text, but they don’t need to be able to scale padding as well. Doing so increases pressure on the viewport — the larger the text you need, the less space you potentially have to display it in (once you’ve reached the point where your browser is as big as your screen), and that means shorter line-lengths and more scrolling for the user.

So maybe it’s better to stick with px for padding etc — it creates the base design you want at the default size, but allows it to change proportions to provide ever more relative space for larger text.

Michael March 15, 2015 at 1:34 pm

I think some IE browsers are 12px? Pretty sure, so safe to define the base font I believe.

Stephanie Rewis March 16, 2015 at 12:43 am

@brothercake – Interesting thoughts… I’m currently making lots of plans and considering many options. As one does. ;)

@Michael – In 15 years of development, I’ve never heard of a 12px browser — IE or otherwise. Do you have stats or a link for that information?

Leave a Comment

{ 5 trackbacks }