Friday, July 10, 2009

Graceful 3 column to 2 column to 1 column degradation using CSS

I have been wanting to update my blog profile from rounders3 to something a bit more malleable for some time now.

This week I finally got around to it. You can see the results on this blog. It now degrades gracefully from 3-column to 2-column to 1-column mode.

If you are running the latest Safari/Opera/Firefox/Chrome, you can see it in action - just resize the browser window and the layout goes from 3 column, to 2 columns (with the Twitter/Archives sections moving below the profile) to 1 column (with the footer replaced with a helpful message)

This works on all browsers - except IE of course. Older browsers may require the page to be refreshed.

Also, in Print mode, the columns disappear and the footer is replaced with copyright text.

This is all done using CSS 3 Media Queries. These are not supported in Internet Explorer - even v8. Get The Facts - "Firefox and Chrome have more support for emerging standards like HTML5 and CSS3, but Internet Explorer 8 invested heavily in having world-class, consistent support for the entire CSS2.1 specification." Remember?

How did I actually do this? I started off with the instructions given here. They point out that you can use a CSS left and right float to get a three column layout. They also point out an important fact - in the absence of a float, elements will be displayed in the order they are mentioned. Also, clear can be used to ensure that there are no floating elements next to a given element.

Besides this, we have Media Queries. These allow you to specify your display type (for e.g. print for a printer, handheld for a mobile device etc) as well as query on other things such as screen resolution or browser window size/aspect ratio.

Normally you would expect the iPod to respond to handheld, but unfortunately, Apple ignores the handheld tag. In its place, they ask you to query on screen resolution instead.

Finally a couple of things: if your default specification for an object attempts to float to the left, you can override and move it to the right using the CSS !important qualifier. Also, if two rules with !important are triggered at the same time, the one which occurs first is given priority.

Armed with all this, I could write the following to move to two column mode if the browser Window has less than 1000px (view source on this page to see this code). Notice how I changed the margins to accommodate less space required on the right of main-wrap1 in two column mode.
@media only screen and (max-width: 1000px) {
.sidebar-wrap-left {
margin:15px 0px 0px 20px !important;
}
.sidebar-wrap-right {
clear: both !important;
margin:15px 0px 0px 20px !important;
float:left !important;
}
#main-wrap1 {
margin:15px 20px 0px 290px !important;
}
}
This comes below the above for 600-1000 (Note the overlap):
@media print, handheld, only screen and (max-width: 600px) {
.sidebar-wrap-left {
display: none !important;
}
.sidebar-wrap-right {
display: none !important;
}
#main-wrap1 {
margin:15px 20px 0px 20px !important;
}
}
There were a few more tweaks required. For example, the Footer actually has three different messages inside, one each triggerring on Print, sub-600 and Everything Else. Also, the Google Search box in the header (another addition from my side) is layouted using floats - meaning it doesnt play well with the blog layout by default. I had to add the following to get it working (it had a nonsense tab bar on top that I hated)
#uds-searchControl .gsc-resultsbox-visible {
clear:none !important;
}

#uds-searchControl .gsc-tabsArea {
display:none !important;
}
None of this would have been possible without the amazing Firebug extension - its an invaluable tool for use while designing web pages, allowing you to add/view/remove attributes from an element at the same time showing all the CSS attributes (inherited or direct) applicable to an element.

Not surprisingly, the iPod Touch's browser supports media queries. But, it sticks to the 600-1000 rule no matter what. I was pleasantly surprised to find that my 5800's browser also supports media queries. In retrospecitve, since it does Flash too, maybe I shouldnt have been surprise. The 5800 uses sub-600 in portrait/landscape mode and 600-1000 in landscape fullscreen mode (after refresh - using Older/Newer Posts button.) The 5800's UI fails its back end engine as usual - there is no way to refresh the page while in fullscreen mode. Nokia has been taking quite a beating recently by the way. I don't think they deserve it - the 5800/N97 are pretty decent phones, it just that they suddenly have to compete in a field of handheld computers (which is essence is what the iPhone/Palm Pre etc. are - whatever you may choose to call them)

Lastly, I have been having a lot of trouble with FF 3.5 - it seems VERY slow now, much slower than FF3. Most of my friends have switched to Chrome - maybe I will do so too. People are recommending unusual steps to deal with it - from optimizing FF3.5's SQLite databases to clearing out your Temp Folder, Recycle Bin and Temporary Internet Files - it seems its a bug. Mozilla have to get their act together - Chrome will soon have extension support, and the plight of Nokia and Sony should teach them that people have no brand loyalty in the tech domain.
Post a Comment