This is a follow-up to last week’s post, Should we design for wider screens?. In this post I’ll demonstrate with a simple example how easy it is, with CSS and a bit of jQuery, to make layouts that adapt to the many different screen sizes out there.
If you’re feeling impatient, jump straight to the demo!

Example HTML

At the top level, my example HTML page has a #wrapper div, which contains a #header, #main div containing all the interesting stuff, and a #footer. The main section has #content, #primary, #secondary and #tertiary divs for the different content areas of my page. The first two content areas, #content and #primary are wrapped up in an additional #container div, but your own markup may obviously differ.

<body class="normal>
<div id="wrapper">
	<div id="header"> ... </div>
	<div id="main">
		<div id="container">
			<div id="content"> ... </div>
			<div id="primary"> ... </div> 
		</div>
		<div id="secondary"> ... </div>
		<div id="tertiary"> ... </div>
	</div><!-- #main -->
 
	<div id="footer"> ... </div>
</div><!-- #wrapper -->
</body>

Prepare your styles

The basic idea here is to have different CSS styles for each width. The styles could be changed directly through jQuery, but that would quickly result in a lot of messy code. Instead, we’ll use jQuery only to change one class attribute. Initially I’ve added the class ‘normal’ to the body element to ensure a sensible default for browsers with JavaScript disabled, but we’ll also need styles for ‘wide’, ‘slim’ and ‘narrow’. This is easy to do with CSS descendant selectors:


#wrapper { margin: 0 auto; }
#header {overflow: hidden;}
#container,#content,#primary,#secondary,#tertiary
  {float:left;}
#footer {clear:left;width:100%;}

/* Wide ( over 1100px ) */
.wide #container {width:60%;}
.wide #content {width:66%;}
.wide #primary {width:34%;}
.wide #secondary,.wide #tertiary {width:20%;}

/* Normal ( over 800px ) */
.normal #container {width:50%;}
.normal #secondary,.normal #tertiary {width:25%;}

/* Slim ( over 600px ) */
.slim #container{width:66%;}
.slim #secondary,.slim #tertiary {width:34%;}

/* Narrow ( under 600px ) */
.narrow #secondary,.narrow #tertiary {width:50%;}
.narrow #secondary {clear:both;}

Unfortunately versions 7 and older of Internet Explorer deal differently with percentage widths compared to most other browsers, and can result in some funny behaviour. I see two primary ways to deal with it: either feed IE 6 and 7 it's own rules (e.g. a tested, fixed-width layout) or just make sure that the percentages never add up to 100 %. A nice explanation of this annoying feature can be found over at OJTech.com.

The jQuery

First of all I need to include jQuery, and perhaps the easiest way is to use Google’s jQuery for this. The main bit is a function, checkWidth() that (you guessed it) checks the width of the browser window and sets the body class attribute accordingly. The code below should be pretty self-explanatory.


	function checkWidth () {
		if ($(window).width() > 1400) {
			$('body').attr('class','superwide');
			$('#title').text('Wide ('+$(window).width()+')');
			}
		else if ($(window).width() > 1100) {
			$('body').attr('class','wide');
			$('#title').text('Wide ('+$(window).width()+')');
			}
		else if ($(window).width() > 800) {
			$('body').attr('class','normal');
			$('#title').text('Normal  ('+$(window).width()+')');
			}
		else if ($(window).width() > 600) {
			$('body').attr('class','slim');
			$('#title').text('Slim ('+$(window).width()+')');
			}
		else {
			$('body').attr('class','narrow');
			$('#title').text('Narrow ('+$(window).width()+')');
			}
		}

In addition to this, all I need is some code that will tell the browser when to run the checkWidth() function.

	$(document).ready(function(){

		// check the window size when page loads
		checkWidth();

		// check on resize
		$(window).resize(function() {
			checkWidth();
		});

	});

That's it! View the finished demo.

After starting to write this post, I read the latest issue (#200) of .net magazine and noticed a mention of a very cool way to do a similar trick using only CSS media queries! Media Query demo by Bruce Lawson. Haven’t tried it out yet, but I definitely will.

Hope you liked the post, feel free to tweet it, or leave a comment below.


Experimenting in HTML5 and CSS3

I decided to experiment with some of the new elements in HTML 5 and built my blog theme from scratch (with the help of the Carrington framework though). I’m now rolling article, section, header, footer and other stuff. Because IE needs a Javascript hack to enable support for these elements, I wouldn’t consider doing this in any client work, but hey, this is MY blog!

If you see subtle gradients here and there, congratulations: you’re running a recent build of Safari, Chrome or Firefox. In all versions of IE everything should still look just fine, even IE6. I haven’t done thorough checking yet though!

My other aims with this theme were to create a very readable blog, with clearly visible titles and separation of content. I hope I succeeded, although this is obviously a work in progress, just like any other website out there.