Client Side Style Adaptation

In the first post of this series I talked in general terms about using client side techniques for style adaptation and server side for content adaptation. That's the approach I take on this site and I described the techniques I use for PHP Image Adaptation in previous article. Here, I want to focus on the style adaptation which is done client side.

In adapting a page's content to the available screen size I'm essentially following Ethan Marcotte's Responsive Web Design techniques. In summary:

Try it out. If you're reading this on a small screen (presumably a mobile), you'll see the single column layout. If you're on a desktop, you'll see the multi-column layout. Resize your browser window and you'll see it switch from one to the other … assuming you're not using Internet Explorer 8 or older, in which case you'll just see the desktop design.

Actually, if you resize your browser on the home page, you'll see two changes. First there's a switch to a two column layout with the Diary headlines and Twitter updates side by side and the "Elsewhere on the Web" box below them. Make the window a little wider and there's enough room to get all three in a line.

The single column layout

It's worth pointing out a couple of features of the single column layout.

A screenshot of this Web site's homepage in a narrow viewport.

First of all, you don't have to zoom in or out on your mobile. The text is the right size without the user having to do anything. That's because the viewport is set to the width of the device. If you want chapter and verse on the viewport then by all means look it up, but as a practical guide, just make sure you include this meta element in all your pages:

<meta name="viewport" content="width=device-width" />

To repeat something I like to repeat at every possible opportunity: if a user has to zoom to navigate your site, that shows they're using a very smart device to browse a badly engineered site. It's a very good hack that the device and browser manufacturers have had to introduce to make the desktop Web browsable on mobile - but it's not something anyone should have to actually use in my opinion.

Secondly, the 'top matter' (my name and the 3 links) take up just 2 lines. Admittedly they're big lines, but without any vertical scrolling you can see actual page content even on older, small mobile devices. That's important. If the top matter fills the screen and doesn't change as you navigate from one page to another, how do you know you've changed page?

The first two links point to the most important pages on the site (the home page and diary, which is the closest I get to having a blog). The third link, "More" just jumps to the rest of the navigation which is at the bottom of the page.

This layout is defined in the site's base stylesheet which is the default so every browser on every device gets it.

<link rel="stylesheet" href="/css/20110825.css" type="text/css" />

Nothing out of the ordinary there (although you'll have to wait until the final part in this series to find out why the stylesheet has a date in its name), but now I use CSS Media Queries to invoke a second stylesheet if the viewport is at least 600px, i.e. with this link element:

<link rel="stylesheet" href="/css/twocol.css" type="text/css" media="only all and (min-width:600px)" />

Again, you may want to read up on the syntax or just copy, paste and forget. The additional stylesheet overrides just the relevant definitions in the base stylesheet to create the 2 column layout. Things like font style, colours and so on are unaffected - we defined those already in the base styleshee which is still active.

Finally, there's a link element that calls a third stylesheet for viewports wider than 800px with a similar link element:

<link rel="stylesheet" href="/css/threecol.css" type="text/css" media="only all and (min-width:800px)" />

The number of style definitions in this three column stylesheet is very small indeed - there's not a lot that needs doing. You may find this very simple demo useful too - again, resize your desktop browser to see the effect.

One thing to point out though, unlike either of the others, the three column stylsheet does set a maximum width of 850px for the HTML body element and centres it. The effect is that:

What About Internet Explorer?

Versions of Internet Explorer below version 9 (only available on Windows 7) don't support media queries. Therefore if we just set up the stylesheets as discussed then users of IE would only ever see the single column layout. Therefore we have to choose which layout we want IE users to see and use the conditional comment system to force that behaviour, irrespective of screen size. As old versions of IE are more or less confined to the desktop world, I chose to invoke both the stylesheets. However, IE Mobile is not to be ignored, especially with the Nokia/Microsoft deal, and thankfully we can test for that as well so we end up with:

<!--[if lt IE 9 & !IEMobile]>
  <link rel="stylesheet" type="text/css" href="/css/twocol.css" />
  <link rel="stylesheet" type="text/css" href="/css/threecol.css" />

Why Not Put All The Styles and Media Queries In One Stylesheet?

It's tempting to put all your styles, including those for wider viewports, into the one stylesheet. After all, that reduces the number of HTTP requests which is something that Mobile Web Beat Practice explicitly encourages. The reason for not doing so is what we've just seen - Internet Explorer. You can't use the IE conditional mechanism if all the styles are in one file.

If you don't want to provide the media query-dependent stylesheets to IE users then, OK, put the media queries and styles that they invoke into one sheet. I have considered doing something of a hybrid here: putting the base styles in one stylesheet and both the two and three column styles in a second. That way, IE users would see the 2 column layout (on any screen) but my guess is that IE users will have wider screens and that the full 3 column layout is more appropriate.

Not Pixel Perfect, No Fixed Widths

The very simple design of this site means that I don't need to worry whether it looks exactly the same on different screens or that it looks exactly so on a particular device. I've seen many designers tie themselves in knots trying desperately to make sure it looks exactly like this on a iPhone and like this on an iPad (it's always those two devices they worry about; everyone else is an afterthought or a no-thought-at-all-'cos-Apple's-cool. Gah!). Do you really need to know exactly how wide the screen is so you can determine exactly how to use every pixel? If you do, then, OK, Responsive Web Design won't help you, but in most cases I'd say it does a very good job of allowing you to handle classes of device with ease.

One Little Cheat

I've talked exclusively about adapting the style, not the content. My working assumption is that whatever content is sent to the device, be it tiny mobile or giant plasma screen, will be displayed. The previous article talked about server-side techniques for adapting content so this is not an unreasonable assumption.

However … there is one little bit of code for which I make use of display:none and that's on the "More" link at the top of the mobile page. That is an in-page hyperlink to #secondary which is the id of the rest of the navigation that goes at the bottom of the page on mobile and immediately below the primary navigation if there's room for the 2 column layout (so it looks like one continuous list). That "More" link is hidden on the wider layout. The "More" you see at the end of the secondary navigation block links to another page called "More" (where I stick stuff I can't find a home for elsewhere on the site). So I cheat a little, however, in my defence, the "More" link that takes the display:none style only does so on wide screens, not mobile, and look, it's just this much code:

<li class="mobile"><a href="#secondary">More …</a>

Let me off?