CSS-based liquid layout has proven successful during the reign of 800-pixel to 1024-pixel screens, but as we use a wider range of devices to access the web, we need more powerful and flexible ways of managing layout. If we want to serve devices whose viewports range from 240 pixels to about 1680 pixels—and with resolution ranging from 72 to 150 pixels per inch—we need a new method.
What’s the problem with liquid layouts?#section2
If you create a liquid layout optimized for a maximum width of 1024 pixels—limiting maximum line-lengths for your text to maintain readability— gaps will appear on a wider screens, and your carefully balanced layout will break. On a tiny-screened PDA, your text and images will be compressed into a crowded content sandwich. No designer wants that. If vector-based layouts were technically possible on a wide range of browsers, we could use a single generic layout that looked exactly the same on all screen sizes. Since that’s more fictional than feasible, we have to find another way.
So why don’t we just define layout and appearance for a series of screen-width ranges, then find a way to match these layouts with the user’s viewport size?
Switchy McLayout to the rescue#section3
Switchy McLayout lets you define the dimensions, information richness, and appearance of your content objects for set ranges of screen sizes. A news site, for example, could have one layout and appearance for wide screens, one for medium-sized screens, and another for PDAs. Images could shrink or even disappear according to the screen size, columns could come and go as needed to maintain readability, and you can achieve a more efficient use of the available space for each screen size.
This example news page uses Switchy McLayout. For purposes of demonstration, we’ve defined seven screen-size ranges and given each range its own layout that makes effective use of the available space. CSS used in examples is for demonstration only.
Figure 1: The progressive states of a news item’s appearance.
The page’s degradable, unchanging markup for the page contains all the items shown in the “extra wide” layout. As the viewport size diminishes, various kinds of content are changed. It’s like peeling an onion: every time the screen shinks, a layer is removed, until only the essential parts remain. The ranges and corresponding appearance defined for this example are:
Device | Screensize | Layout |
---|---|---|
PDA Vertical oriented | < 240 px | |
PDA Horizontal oriented | 240-320 px | |
Set top / TV | 320-640 px | |
Old CRT screen | 640-800 px | |
Common TFT screen | 800 – 1024 px | |
Wide screen | 1024 – 1280 px | |
Super-wide screen | > 1280 px |
Class switching#section4
Now that we’ve defined a range of layouts, we have to detect the user’s actual screen size and activate the appropriate group of styles. We’ll use a style-switching method that’s dependent on the class of the body
element.
JavaScript, our CSS assistant#section5
To monitor the user’s actual screen size and switch classes on the body-element, we use a little unobtrusive JavaScript. Through the onresize
event of the window
object, we obtain the windows/screen size. A ternary operator selects the appropriate layout and class name, and this class is added through the DOM to the classes already residing on the body
element. When JavaScript is not available, the layout degrades to an “old-school” liquid layout.
Note that different browsers use different event models. IE6, for example, fires the onresize
event in real-time, while Firefox only fires the onresize
event at the end of the actual resizing.
Progressive content compression#section6
Our second example shows how Switchy McLayout can help us make more efficient use of available screen space on different devices. In its raw form, the markup is a simple definition list with four items. On wide screens, all items and headers will be shown as four columns in a row. As available space decreases, the columns will be shown as two rows of two columns, then as a horizontal tabbed panel, then as a vertical tabbed panel, and finally as four rows in one column with a reduced font size.
Figure 2: The various states of progressive content compression
Taking it further#section7
We’ve used the screen size
property as an input for class switching. If you used other triggers to switch styles, you could check for screen height, presence of a scrollbar, font size, mouse position, color depth, and so on—and change your page’s appearance accordingly.
In conclusion#section8
The growing number of popular screen sizes and resolutions will challenge web designers to deliver their content in an appealing way for a wide range of devices. Switchy McLayout is a step toward a solution that meets this challenge.
Acknowledgments and alternatives#section9
While the technique presented above was developed independently, many related techniques have been introduced elsewhere. Richard Rutter collects a series of such techniques at Clagnut, and Kevin Hale presents a technique that achieves a similar result using a slightly different method at Particletree. Andy Clarke and James Edwards’ pioneering “Invasion of the Body Switchers” helped popularize the use of body
classes to alter layouts.
I´m thanks for this website i have more information fo webdesign and css learning and inspired.
I know the point of this article was the javascript, but I also want to use this resolution-based column remapping technique you used in example 2. I really want to use a form of this technique, but I am new to using css. I think this is a potential bug in your screen_med implementation and hopefully it is an easy fix. To see the bug, go to my example here:
http://www.mineisbetterthanyours.com/test/switchyBug/
All I have done is copy and paste the last paragraph to make body tab A longer. When you do this and view the page in screen_med, instead of the layout being A B on one line followed by C D on the next, the order becomes A B followed by another “line” which has blank space and then C on the right column, and then the D section wraps back onto a 3rd “line” and is on the left. Does anyone know how to fix this? I just want there to be 2 columns that properly follow each other without any weird space. Thank you.
Its also crucial that they do this without the css defining a fixed height of how tall each section is going to be… (although how tall is not what matters, it just matters when they aren’t the same height).
Your technique only makes sense combined with some other logic.
I am very interested in using a simplified version of this on the new (all css version) of my site, but I notice it doesn’t work in IE5. You always get a clientWidth of zero. I don’t know much jscript. Anyone know how to get round this?
Awesome post, awesome discussion. I got enlighted for my new project. @All: thanks!
It is not quite the same. But similar enough to be mentioned: Another possibility is to use a CSS
* container with overflow:hidden and fixed width combined with
* (sub)containers with fixed height. As many columns are displayed as possible (this means, part of the content won’t be visible on small screens.)