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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(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 EDIT: I’ve managed to lose the demo at some point in time. Anyway a better and more flexible way of doing this is CSS3 Media Queries, and you should use them.
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.
Leave a comment