Skip to main content

The EMs have it: Proportional Media Queries FTW!

By Lyza Gardner

Published on March 28th, 2012

Topics

I still like the notion of the metaphorical connection between content-based sizing units (e.g. ems) and layout definitions (e.g. breakpoints). And the zooming behavior cited here was always meant more as a sidelong example than a core argument. Nonetheless! You should note that the zooming behavior has long since been made consistent in browsers (i.e. fixed). Keep that in mind if you cite or otherwise put stock in this post. I never meant to be absolutely prescriptive about ems as units—use whatever feels natural and appropriate for your design strategy. And thanks for reading!

–Lyza, March 11, 2015

A core tenet of Responsive Web Design (RWD) is fluidity and proportion. Instead of using fixed-width layouts, we enlightened web devs and designers use percentages in our CSS. Font units aren’t pixels or points anymore, they’re percentages (typically for top-level baseline reset) or, more often, ems. And yet the vast majority of us still write width-based media queries in pixels, e.g.:

@media all and (min-width: 500px) {} @media screen and (max-width: 800px) {}

It’s a natural thought process: for windows or screens of particular width ranges, we want to flow our content in a particular way. This naturally seems like a pixel dimension. But, once again, to bring out my big hammer, what about when we look at things from a content perspective?

Folks who design for traditional reading media—where the content really is king—don’t center design decisions around the absolute width of content-holding elements so much as around the optimal line lengths for the content they’re flowing. There are some tried-and-true numbers one can shoot for that make for the “right” number of letters (and thus words) per line for comfortable human reading.

Thus actual column width is a function of font size and ems-per-line.

You may have seen the rule of thumb (useful, admittedly!) that makes the following general equation in terms of baseline font sizes in CSS:

100% = 1 em ~= 16px ~= 14pt

This means that, at your baseline, that is, before you’ve adjust font sizes in any child elements, the default font size in the browser is usually approximately 16px and usually approximately 14pt but always 100% and 1em.

If we start from a baseline of 16px, you may well wonder what the difference (beyond academic) is between a media query like:

@media all and (min-width: 400px)

and one like this, that uses ems multiplied against the 16px baseline approximation:

@media all and (min-width: 25em)

Here’s the 64-dollar question or whatever:

What happens when the baseline is not 14pt/16px?

On Ye Olde Desktop Web, this situation most often comes about (“most often” is unscientific here, but I’m willing to toss out the hypothesis, at least) from user-intiated zoom in browsers. Low-sight users might do it, I know I do it when I’m surfing the web on my Mac Mini from the couch across the room. I’m not that old but, man, it’s hard to see the contents of a Wikipedia article on a 23″ monitor from 10 feet away.

As I zoom in, that is, make the text larger in my browser, I’m no longer at a 14pt/16px baseline. 100%/1em in my world is now a different number, maybe 18pt, maybe 32px. Pixel-defined content holders no longer have comfortable amounts of words per line. Pixel-defined content holders that float might wrap awkwardly as the content in them swells.

Our creative director and CSS wizard extraordinaire, Aileen, whipped us up a beaut of a responsive new site layout. For various screen widths, our site’s nav has a few different behaviors.

In pixels at normal zoom, the nav elements fit in a line roughly at a width of around 656px. There’s generous room to detatch and float next to the logo at around 960px.

For screens/windows narrow enough that the full set of top-level nav elements would not fit on one line, we use the menu button nav pattern.
For screens/windows narrow enough that the full set of top-level nav elements would not fit on one line, we use the menu button nav pattern
For screens/windows in a particular range that are wide enough to fit the top-level nav elements on a single line, we do that.
For screens/windows in a particular range that are wide enough to fit the top-level nav elements on a single line, we do that.
For screens/windows wide enough to fit all of the top-level nav elements horizontally and have enough room left over for our logo, we detatch and float the nav to the top right.
For screens/windows wide enough to fit all of the top-level nav elements horizontally and have enough room left over for our logo, we detatch and float the nav to the top right.

I’ll show you a little experiment. I’m using the Chrome browser, and I’m viewing our site with a window about 670 pixels wide. With a pixel-based media query, that puts me in the second category of nav experience: all of the top level items are shown horizontally, docked to the top of the content:

OK, now I’m going to use the Zoom In command twice to make my text larger.
With a pixel-based media query
With an em-based media query

The pixel-based media query @media all and (min-width:656px) still evaluates to true with the zoomed-in text and therefore creates awkwardly-wrapped nav elements.

However, the em-based media query of @media all and (min-width: 41em) scales to the larger text size. Zoomed in like this, the browser no longer satisfies that query: we have fewer than 41ems to work with. So we deliver the menu-button nav pattern and other layout and styling appropriate for the way the text fits. Content, again, is what ends up dictating what we’re doing in the end.

You could also make the text smaller and watch the same proportional adjustments occur, in the inverse.

BTW: It should be noted that, unlike window resizes, which cause media queries to be re-evaluated immediately, you’ll need to reload the current page if you zoom in or out for em-based media queries to re-apply. My hunch is that most users who zoom a lot keep their zoom set as they navigate around different pages and aren’t changing zoom settings on a site-by-site basis. I could be wrong about that, though.

The media queries on our site are all crafted based on the approximate baseline. We played with our browser window widths, adjusting them until it looked like they were at the appropriate width to create a breakpoint at normal text zoom. We noted that pixel measurement and divided it by the rough baseline of 16px to arrive at our em units. There may well be a better way to do this math, but this seems to do the trick so far.

One of the things that spurred me toward thinking about em-based media queries was my own Kindle Touch. Through no action of my own, the Kindle browser’s default text zoom is, roughly put, high. Like newer smartphones, the Kindle has a high pixel density, 167ppi. An absolute-sized font (say, 16px) on a high-density screen is correspondingly tiny. Most smartphone browsers get around this by reporting their resolution differently for purposes of the web. An iPhone 4, for example, which has a real resolution of 640×960 and 326ppi, masquerades as 320×480 in the browser as a way to get normally-designed websites to look normally-sized and not teeny tiny. For the iPhone, 1em is still approximately 16px or 14pt, and so pixel-based media queries generally behave equivalently to em-based ones (disclaimer: that’s a broad generalization).

The Kindle Touch, on the other hand, has taken a different approach. It reports its web pixel resolution as 600×800, but its default text size is considerably larger than 16px/14pt.

Our early, pixel-based media queries for our nav looked dreadful on the Kindle. Its resolution meant that it was using our tablet-range layout, but its text was enormous, causing widespread ugliness as the pixel-width elements didn’t scale to adjust. The site looks pretty decent, however, with media queries in ems:

Our site looks tolerable on a Kindle Touch. That's about as good as it's going to get on that browser.
Our site looks tolerable on a Kindle Touch. That’s about as good as it’s going to get on that browser.

Sadly, I did find that, as reported by Stephanie and Bryan Rieger, the Kindle considers itself to be in color, so the media query @media all and (monochrome) doesn’t match it and @media all and (color) does. Too bad! Speaking of Kindle and Stephanie Rieger, the Kindle Fire tablet’s browser is also a great cautionary tale about mistaken complacence about “standard” device screen widths like 480, here is an enlightening tweet:

Food for thought, Stephanie, food for thought…

p.s. Thanks to the observant folks in the community who have noticed that our nav, at wider widths, has drop-down elements that are not ideal in terms of usability. We‘re cooking up ideas about how to make this better! have actually made improvements to the tablet-version nav on touch devices since I started working on this post! More to come in Nav-Land.

Comments

Jason Grigsby (Cloud Four Team Member) said:

For years, zooming has been the elephant in the room that web designers haven’t wanted to acknowledge. Carefully crafted designs destroyed with a few quick keystrokes.

I realize we mostly talk about media queries in the context of delivering content to different devices, but using em-based media queries in this manner is a huge, under-appreciated win for both web designers and users.

Thanks for documenting this and showing it in action.

shawn said:

This is a really interesting concept and something I have been trying to grasp for some time now. Navigation using em’s seems very logical.

By any chance is there any possibility that you would be willing to share the navigation Sass files that this site runs on?

While I can see everything I really need to via the css, it just seems that it would be much easier to understand exactly what you are doing by being able to read the source void of all the other stuff going on.

Either way, great article and seriously good food for thought. Thank you

Replies to shawn

Lyza Gardner (Article Author ) replied:

Hi Shawn,

You’re doing foreshadowing for another blog post I’ve been mulling over writing. I can sense you see the echoes in the end-result CSS–yes, I started the CSS using SASS/SCSS. However, SASS was a new process for us (the entirety of the site pretty much was) and was too painful for our team to adopt quickly. So in the middle of the design process I output to CSS and we stopped using SASS.

I like SASS. I use it for projects where I’m flying solo. But the complexity of the breakpoints of this site—SASS is weak when it comes to breakpoints, as you cannot use variables for them—made for some ugly compiled code that was difficult to debug. Sounds like we Cloud Four folks need to attend some of those great recent talks about CSS management and sanity, eh?

shawn said:

I did notice that when the navigation hits ‘mobile’ widths, that you are dropping the sub-nav elements. Like when I click the navigation on mobile device, the ‘about’ tab, there is no links for ‘calendar, book’. Is this by design, or do you plan on adding in the sub-navigation links at a later date?

Derek Pennycuff said:

W00t! Great stuff. Thanks for sharing.
I’m pretty sure the default behavior in Firefox is to automatically keep track of zoom levels on a per-site basis. That’s what it’s done for me for the past several years, and I don’t tweak any settings in regards to that.
But I just tested it out on the Cloud Four home page and it renders the media-query re-draws just fine without needing a refresh. 🙂

Joe Snell said:

Wow. I’ve never thought of using ems in media queries. Post is superb. Makes so much sense practically and logically. Some design challenges that that were previously a pain, will now be non-issues.

Thank you!

Yoav Weiss said:

Looks like a great approach!
Any notes on browser compatibility?
The problem I see here is that once I hit 300% zoom on Chrome (both stable and dev), it crashes and can never recover since I can’t lower the zoom levels of a site *before* I browse to it…

Scott Jehl said:

+1 – good info here, Lyza. Thanks for writing. Em queries certainly do pair well with fluid layouts from what I’ve seen. One thing I’ve seen in the past that might be worth noting, with regards to this part:

We noted that pixel measurement and divided it by the rough baseline of 16px to arrive at our em units. There may well be a better way to do this math, but this seems to do the trick so far.

It’s been a couple months since I last checked, but depending on the browser, setting a custom font-size on the HTML or body element may or may not affect the value of 1em in media queries, even though it does change it in the rest of the CSS (I think Opera’s implementation differs from the others, or it used to at least). The Cloudfour site appears to set the body to font-size: 87.5%, so it might prove a good test case to see how browsers currently handle that for media query em values – maybe it’s consistent now, I’m not sure. If body font size does affect the value of 1em in a query, the breakpoints would likely occur at narrower places than intended.

But even if the browser implementations do not still vary, perhaps the addition of em queries values are all the more reason to not override the body’s font-size, as the usefulness of a math helper (like the old 62.5% trick) tends to decrease when you can’t use it everywhere in a CSS file.

More Opera trivia: in that browser, zooming the page causes live reassessment of em media queries without a refresh. I’m not sure how many other browsers do that, but it’s a pretty nice feature!

Thanks again.

Replies to Scott Jehl

Lyza Gardner (Article Author ) replied:

Hi Scott,

Yeah, I was worried about our non-100% font-size, so I ended up creating a test page with various convolutions of type reset and font size on the body element. I found that no matter what you do to your font size in *any* of your elements, the media queries are always against the baseline. Granted, I haven’t extensively tested in every browser known to man. I’ve also verified that the em-based media queries on our site specifically are dead on for their pixel-based originals, at least in desktop browsers and on iOS and Android.

Replies to Lyza Gardner
Matt Haenlin replied:

Hi Lyza,
Great article! I’m currently working on incorporating this technique into a client’s site. In our CSS we set body font-size to 70%. This doesn’t affect the media query as you mentioned. I’ve defined a breakpoint at 1024 and get the same results with min-width: 64em or min-width: 1024px. What’s interesting is when I tried setting the width in EMs on my main container the 70% body size definitely made a difference! We’re working with on overall grid width of 968, so initially I set the container to 60.5em (width: 968 / 16 = 60.5) but that was way to small. When I took 70% of 16 and used that I got the right proportion. So %70 of 16 is 11.2 and my container width in EMs is 86.43 (width: 968 / 11.2 = 86.43). So far only tested on Chrome 17.0.963.83, Firefox 11, and Safari 5.1.5 on Mac OSX 10.6.8. Thanks!

Stomme poes replied:

Scott:
I was also going to comment on Opera’s behaviour. It’s quite nice on well-built sites, since when I’m zooming in I eventually get the “mobile” layout. Works great when the site’s not garbage!

And yeah, Opera’s the only one I’ve seen this in, but I haven’t had the chance to test in IE9. However, I don’t expect to be surprised there.

Imar said:

Worth considering to try and standardise browser behaviour. As Derek points out above, I just zoomed one of my responsive designs (using pixel-based media queries) in both Chrome and Firefox and they behaved differently. Firefox applied the media queries as though the viewport were shrinking, and Chrome did not.

Jason Grigsby (Cloud Four Team Member) said:

@Yoav I can’t replicate the bug in Chrome on my machine zooming as far as I can go. Are you on a Mac or a PC? Do you have another machine handy that you could test on?

Replies to Jason Grigsby

Yoav Weiss replied:

I’m on a Linux box (Ubuntu 11.10) and the bug seems consistent on several machines with this OS. Tried an XP VM and chrome doesn’t crash there.
On the other hand, it seems that Chrome on XP does not refresh its EM MQ when zooming in/out. It stays with the layout relevant to the zoom level it has when the page was loaded.
All in all, Chrome’s support seems flaky to me.
Do you have a link to an isolated test case of EM MQs, that I can use in a bug report?

Chris Hilditch said:

Great Post! I’d never considered using ems with media queries.

I had a little look at the CSS not re-applying on zoom problem, by changing the link rel, and changing it straight back again it gets re-applyed.

$('#styleSheetId').attr('rel','force-re-apply').attr('rel','stylesheet');

This could be combined with a little snippet from stack over flow (
http://stackoverflow.com/questions/6163174/detect-page-zoom-change-with-jquery-in-safari ) which detects a zoom, and you sort of solve this problem.

I haven’t tested this extensively, but it seems to work in nicely IE9/Chrome.

Chris.

Peter StJ said:

Great post, I already sent note to our design team to study your findings.

However I noticed that this works great in Firefox and IE9, however Chrome does not react as expected, which came as a surprise as the snapshots in your post are taken with Chrome. Chrome on both Linux and Windows is not doing what it is expected (17.0.963.83). Just a side note, maybe you should check this out.

Marcy said:

Thanks for explaining so well the differences between percent and em grid widths. I’ve played with ems, but always go back to percent before the project is finished. I guess I’m going to have to stick with it next time, now that I understand the advantage. I’ve also looked at sites with a Kindle, but I think my daughter has adjusted her text size before she hands me her device. Now I know what to check out!

Richard Le Poidevin said:

I can see one potential problem with the zooming / navigational change. I’ll work on the assumption that a lot of people who zoom have disabilities or may be older and have poor eyesight and may less tech-savvie. So could changing the navigation confuse them? (Although a wrongly formatted menu, having the horizonally scroll are not good options either). Also by condensing the menu into a drop down with makes it harder for users with poor mouse skills and disabilities. Generally though, I think it’s a good idea, but must be fully explored and understood.

AlastairC said:

It’s worth noting that the only rendering engine that doesn’t trigger pixel-based media queries on zoom is Webkit, overall, I think pixels are a more suitable relative unit for layouts:
http://alastairc.ac/2012/04/relative-pixels/

Janghou said:

Great post!
Opera and Firefox trigger a reflow after zoom, no pagerefresh is needed for changing lay-out, in contrary to what is mentioned in the post.
Confirmed, also Chromium (18.0.1025.151 (Developer Build 130497 Linux) Ubuntu 10.10) crashes on zooming and can’t reload, like reported above.

“Aw, Snap!”
Funny thing: Chromium recommends reloading or going to another page. (WTF reporting a bug is not recommended?)

Replies to Janghou

Janghou replied:

Took another look at the issue, but Firefox and Opera are both treating pixel based an EM based media queries the same. If you zoom in they also reflow on pixel based queries. They seem to do the calculation under the hood.

So your solution isn’t that revolutionary in the end, just a workaround for mediocre performance of Chrome IMHO. And now we know there are bugs in Chrome too.

Still a good read, never thought about EM based media queries before.

Nour Akalay said:

Hello,
I really liked this tutorial (one of those ahaaa moments I often have lately) when I noticed a tiny mistake with your menu button.
When you resize the browser and the Orange menu button appears, hovering over it never shows the pointer.
I think it is because in your css you have
nav ul:before {
cursor: pointer;

}
To work you should have it applied directly to the ul, not the ul:before.
Just my 2 bits.
All the best.

Dave said:

Hi Lyza

I’m late to the party here I realise but hopefully I may get a reply. First of all I applaud your documentation of this phenomena and I like many have tried to shy away from the issues zooming text has caused. Usually because I have used a starting point like BP or another framework to take away all the heavy lifting and to my knowledge none of them handle this well. Anyways you have got me thinking now and I think I will try and take your observations on board and incorporate your suggestions into some of my upcoming work.

Now to my question have you experienced any issues with FF13 on OSX (FF11 & 12 displayed the same issue) were responsive layouts are not handled properly below a certain page width (ems or pixels). Specifically the page does not reflow as the browser chrome is resized. I think it is to do with how FF handles ‘resize’ of page and perhaps scrollbars foo. Can you confirm?

Randall said:

I love this article. It’s everything I have been thinking/working with and more. You have filled in so many gaps. TY!

I have been working on a framework using relative units. Cannot wait to share my Fn responsible fluid grid system. You can see the most basic non-production version of it at work in my responsive resume above. More to share soon and thanks again for sharing your great insights:)

Jack Wheeler said:

Great article. It sums up so many issues that designers are facing as viewing platforms change. I’ve recently been experimenting with Susy (http://susy.oddbird.net/) responsive grid system for Compass/SASS. It uses em-based media queries. I have to admit, I did not fully comprehend the benefits until I read your article. Thanks!