Skip to content

Instantly share code, notes, and snippets.

@david-mark
Created September 23, 2012 01:28
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save david-mark/3768460 to your computer and use it in GitHub Desktop.
Save david-mark/3768460 to your computer and use it in GitHub Desktop.
"RWD" and "Mobile First" buzzwords explained

Have been fighting with some RWD "expert" on Wikipedia of late. At the time of this writing, my edits to the related article are still visible.

http://en.wikipedia.org/wiki/Responsive_Web_Design

RWD is just a buzzword. According to the article (and a fairly recent book it seems), it incorporates these techniques:

  1. Use EM units to size text (and containers of text of course).
  2. Use media queries
  3. Let the browser scale images (by using em's instead of pixels)

The first has been a no-brainer for a decade (at least), but didn't catch on until the last few years or so. It never made sense to size text with pixel units, despite the fact that pixels are indeed relative units (logical pixels in CSS cannot be assumed to be 1:1 to the physical pixels on displays). Some agents allow the user to control the number of pixels rendered for each specified in CSS. The nice thing about em's is that they are relative to the font size, as opposed to device constraints or unrelated user settings.

Anyway, the 800-pound gorilla that is Internet Explorer refuses to scale text that is sized with pixel units. That should have been reason enough to avoid pixels for text. The standard comeback for that assertion was always to use the zoom feature (introduced in IE 7) instead, but that scales everything on the page, creating horizontal scroll bars, which create the worst sort of user experience.

So use EM's for text and don't forget to set the BODY to 100% to match the user's preferences. Many designers will tell you that the default setting in IE makes the text "too large", but that's their problem (likely because their layouts fall apart unless the text renders exactly to the pixel as they planned it). If the user wants smaller text, they can easily adjust it. The user doesn't care if the text looks slightly smaller in other browsers. It's a fairly good assumption that an IE user will never see the text side-by-side with another browser, else they would probably be using the other browser in the first place. Well, that goes for IE 8- anyway (IE 9 is actually a pretty good browser).

I believe there is a 1.5 that should be on that list (haven't read the book) that says use liquid layouts. That was also established long ago as the best first step in supporting more than one screen resolution, but it also took forever to catch on (also likely due to jigsaw puzzle layouts that fell apart outside of a narrow range of "approved" resolutions). If you've ever heard "why aren't you at 2048x1536?!" or seen "site is best viewed at 1024x768", that's what they are getting at. Designers typically blame end-users when things go wrong, but a good rule of thumb is that the end-user is never wrong.

So use EM's and liquid layouts. Nothing new so far.

The second item is where the wheels fall off. As any "RWD" expert will tell you, media queries aren't supported in:

  1. Many older or lesser mobile devices (as compared iOS or Android-based devices)
  2. IE 8-

Their "solution" to this involves trying to emulate media queries with... you guessed it: scripts. Every CSS problem is ultimately a JS problem, right? This brings up all sorts of issues, such as the fact that scripting may not be available or may have been disabled by the user, network administrator or even stripped by an overzealous firewall. Seems designers have always wished that was not the case, but it is the case (and will always be a very real consideration). Furthermore, scripts require host features that may or may not exist or work properly. In short, your layout needs to be usable without assists from scripts.

This is where "Mobile First" came in. Figuring that the best way to beat the spotty media query implementations was to offer a style sheet slanted towards small screens as a first option and then use conditional comments and media queries to dress up "all other browsers" (as they see it: IE 8- and the latest mobile browsers).

Here is a simplified (relatively speaking) example:

<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="all">
<!--[if (lt IE 9)&(!IEMobile)]>
<link rel="stylesheet" type="text/css" href="/css/desktop.css" media="screen">
<![endif]-->
<link type="text/css" rel="stylesheet" href="/css/desktop.css" media="screen and (min-device-width:40em)">

Messy and somewhat backwards, particularly as handhelds have increased screen resolution at a dizzying pace over the last few years. Furthermore, any browser that is not IE and does not support media queries will get the "handheld" style sheet. :(

Reading this recent history on blogs, StackOverflow and the like, I had to wonder if the world had forgotten about the "handheld" media type. Since around the turn of the century, when I saw it used on the W3C site, I've been using those to override rules in my primary CSS that are less than ideal for small screens (e.g. heavy background images, multi-column layouts, etc.). As would be expected, many of the older/lesser mobile devices support this media type.

After a bit of searching, it turns out that "handheld" media was rediscovered a few years back, but the new pioneers made a critical mistake in their evaluation. Most articles about the technique recommend using "screen" media for your primary CSS and then to rewrite it all for an alternate, stand-alone "handheld" style sheet. Clearly that was a bad interpretation.

It doesn't work for two reasons: "screen" doesn't cover "projection", "print" and other types. You want to override the rules provided to "all" media types, not create new style sheets for every media type. After all, the "C" in CSS stands for "cascading". ;)

The other reason, as documented on the blogs, is that some mobile browsers get confused and load both "screen" and "handheld" style sheets (just as if "all" was used instead of "screen"). Aha! :)

Here is an example of how it should be done:

<link type="text/css" rel="stylesheet" href="/css/desktop.css" media="all">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="screen and (max-device-width:40em)">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="handheld">

Clean and forward facing. If you have been (properly) using the "handheld" media type all these years, you just need to add an additional reference to it to handle the newer small screen devices that ignore "handheld" media, but support media queries. Add additional media queries for additional ranges. Also note that the units should always be EM's (just like you used for your text and containers).

Typically the "handheld" style sheet is tiny. Here is an example from the My Library site:

html { background-color:#FFFFCC;color:#000033 }
body { margin:.1em;border:none;min-width:0;padding-top:1em }
#skipnav { float:right;display:block }
#sidebar { float:none;width:auto;border:none;margin:0 }
#logo { display:none }
#home h1 { display:block }
address { display:none }

Testing it in Opera's "panel" in small-screen mode shows that it can scale down to a width of roughly 200px before a horizontal scroll bar appears). That brings up an adjacent point: never attempt to hide viewport scroll bars with rules like this:

html {
    overflow: hidden
}

That's a potentially destructive end-around. Your job is to adapt your layout to best avoid horizontal scrolling, but you can't expect to prevent it in every case. Shaving off content that overflows does not help matters.

As for rule #3, I've never done that. Traditionally, browsers have been less than proficient at scaling images (as opposed to image editors) and, of course, they have to download the large images before they can scale them. Furthermore, I've never had any compelling reason to do it. I use far more background images than IMG elements and those are easy to swap out (or eliminate) with the "handheld" (and sometimes "print") style sheet and it just takes a little planning to keep image elements from overflowing their containers, regardless of the resolution (remember rule #1.5). Experience trumps last minute speculation every time.

To sum up: RWD is just a buzzword, which describes an aggregation of techniques that predated it by at least a decade. Furthermore, materials describing RWD often make a wrong turn (at handheld media) that leads them into "Mobile First", polyfills, CSS expressions and other ill-advised practices. Somehow jQuery Mobile and Modernizr end up in the mix as well; the former is particularly ironic as jQuery by itself is far too large, bloated and generalized for competent mobile solutions. Add "Mobile" to it and you've certainly thrown the game away.

Consider that if you save 100K by suppressing large background images, you give 90K of it back just by including jQuery. Then the poor battery-powered mobile device has to parse and execute all of the old attempts at feature tests (mostly for IE 7-, a few more for IE 8) before the frameworks and calling code can initialize and finally present your application (or enhanced document). But I digress, monolithic, multi-browser scripts like jQuery are another story and harm more than just attempts at RWD. They've simply never been a good idea and are less so now that mobile users are so prevalent.

@Raynos
Copy link

Raynos commented Sep 23, 2012

Why media="screen and (max-device-width:40em)" and media="handheld" ?

@Raynos
Copy link

Raynos commented Sep 23, 2012

Oh of course. It's for handheld devices and for small screens on non-handhelds devices because of resizing.

@Raynos
Copy link

Raynos commented Sep 23, 2012

But I digress, monolithic, multi-browser scripts like jQuery are another story and harm more than just attempts at RWD

MyLibrary is monolithic and multi-browser ;)

@david-mark
Copy link
Author

My Library is monolithic, but cross-browser. It was the original dynamic API. ;)

@david-mark
Copy link
Author

"Oh of course. It's for handheld devices and for small screens on non-handhelds devices because of resizing."

Not exactly. In this example, the media query is using max-device-width (not max-width). If it used max-width, it would apply to changes in the viewport size.

Both are used because some mobile browsers do not support media queries. Browsers that support media queries will ignore the "handheld" media type and those that don't will ignore the media query.

@david-mark
Copy link
Author

As a side note, there is another, er school of thought that says skip this stuff and infer things like viewport size, scripting support, features, etc. from the arbitrary, optional (and possibly proxy affected) UA string. Skip that school entirely. People have been trying to make that work since the 90's (and it's certainly much harder now). The point that such inferences are inherently unreliable was conceded by turn of the century, but apparently that history has been lost too. :(

Another school (in the same neighborhood) says to fetch the screen dimensions with script; of course, the screen dimensions tell you nothing (e.g. could have multiple monitors). And regardless, layout should never rely on scripting. ;)

@Integralist
Copy link

I personally prefer the Mobile First route as otherwise in your example...

<link type="text/css" rel="stylesheet" href="/css/desktop.css" media="all">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="screen and (max-device-width:40em)">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="handheld">

...all devices (including mobile devices) will get the desktop style sheet (which will likely have styles and content that are irrelevant for smaller screens. You then add on top of that an additional style sheet just to override a lot of styles that weren't needed in the first place.

With Mobile First route you build your site to be responsive/adaptive and only write enough code for the design to work for the small screen. Then you load additional style sheets (x number of times depending on where your design breaks down) for larger devices. This way each device loads majority of styles which are actually needed.

@Integralist
Copy link

I personally prefer the Mobile First route as otherwise in your example...

<link type="text/css" rel="stylesheet" href="/css/desktop.css" media="all">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="screen and (max-device-width:40em)">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="handheld">

...all devices (including mobile devices) will get the desktop style sheet (which will likely have styles and content that are irrelevant for smaller screens. You then add on top of that an additional style sheet just to override a lot of styles that weren't needed in the first place.

With Mobile First route you build your site to be responsive/adaptive and only write enough code for the design to work for the small screen. Then you load additional style sheets (x number of times depending on where your design breaks down) for larger devices. This way each device loads majority of styles which are actually needed.

@Integralist
Copy link

I personally prefer the Mobile First route as otherwise in your example...

<link type="text/css" rel="stylesheet" href="/css/desktop.css" media="all">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="screen and (max-device-width:40em)">
<link type="text/css" rel="stylesheet" href="/css/handheld.css" media="handheld">

...all devices (including mobile devices) will get the desktop style sheet (which will likely have styles and content that are irrelevant for smaller screens. You then add on top of that an additional style sheet just to override a lot of styles that weren't needed in the first place.

With Mobile First route you build your site to be responsive/adaptive and only write enough code for the design to work for the small screen. Then you load additional style sheets (x number of times depending on where your design breaks down) for larger devices. This way each device loads majority of styles which are actually needed.

@david-mark
Copy link
Author

@Integralist
The handheld style sheets are typically tiny, overriding just a handful of rules. Small enough to inline if you want to save the extra request. Works for me! :)

@david-mark
Copy link
Author

@Integralist

I should also point out the one drawback mentioned with that pattern, though may not be a concern for all. And can add additional style sheets for higher resolution ranges with both. Didn't mean to imply that one is necessarily "right" for all contexts, but I prefer the traditional approach and think that modern mobile devices behave more like desktop browsers these days. Seems less and less devices download the narrowest "handheld" layout (which is just the primary layout with a few rules reversed). I always use device width for that one so that the majority of browsers (guesstimate of course) ignore it.

YMMV. You may not care if (for example) some NetFront or other set top box atrocity gets the most narrow layout (will likely depend on your target audience and just how narrow the "handheld" sheet is). Certainly there are other non-IE off-brand browsers that fail to support media queries, but those may not be a big concern either. I can see contexts where the "Mobile First" example may be preferable.

I suppose the main point of the article is to avoid all of the over-hyped accessories that seem to come with RWD (but clearly shouldn't). jQuery Mobile, Sencha Touch, (God forbid) Dojo Mobile, etc. "Polyfills", media query emulators for IE, etc. If a mobile pattern leads to such complications, it's time to reconsider the pattern. Then there's the sniff-and-redirect camp. It's amazing how much bad information is at your fingertips with Google. :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment