dynamic resolution + prototype
February 27th, 2008
You may have heard of the Dynamic CSS resolution switcher from Particletree, it's a neat bit of js that allows you to specify different css files depending on the browser resolution.
We love this script, but we had problems running it with Safari, and we are using prototype, so we wanted to make use of its goodness for the browser independent stuff.
So, if you're already using prototype, the following script achieves the same effect as the original particletree script. It also uses the dom:ready event, which fires after the dom is loaded, but before the screen is drawn, so you shouldn't see any 'twitch'.
Example
In the following example, we have three stylesheets that correspond to browser widths as follows:
thin up to 1020 wide 1021...1400 widest above 1400
For non js users we want to default to 'wide' (the middle one). In order for this to work properly, we disable all of the non-default stylesheet links.
In your html
In your html you need to link to the three stylesheets, give them each a title attribute, and disable the ones you don't want non-js users to see.
<link title="wide" href="/stylesheets/wide.css" rel="stylesheet" type="text/css" /> <link title="thin" disabled="true" href="/stylesheets/thin.css" rel="stylesheet" type="text/css" /> <link title="widest" disabled="true" href="/stylesheets/widest.css" rel="stylesheet" type="text/css" />
And link to the script, we'll call it dynamic_css.js
<script src="/javascripts/dynamic_css.js" type="text/javascript"></script>
The script
This is the script, it uses the title attribute of the stylesheets to disable or enable them. It is run when the dom is ready, and when the browser width changes.
// DYNAMIC RESOLUTION SWITCHER
// Originally from ParticleTree
// Simplified with Prototype by Ian White of Argument from Design 2008
// include prototype.js (>=1.6) before this file
// you need to edit this function as per your situation
function applyDynamicLayout() {
var width = document.viewport.getWidth();
if (width <= 1020 ) { applyStylesheet("thin") }
if (width > 1020 && width <= 1400) { applyStylesheet("wide") }
if (width > 1400) { applyStylesheet("widest") }
}
// you shouldn't need to edit past here
function applyStylesheet(title) {
var i, stylesheet;
for(i=0; (stylesheet = document.getElementsByTagName("link")[i]); i++) {
// is it a stylesheet with a title attribute?
if(stylesheet.getAttribute("rel").indexOf("style") != -1 && stylesheet.getAttribute("title")) {
stylesheet.disabled = true;
if (stylesheet.getAttribute("title") == title) {
stylesheet.disabled = false;
}
}
}
}
//Run applyDynamicLayout function when window is ready and when it resizes.
Event.observe(document, 'dom:ready', applyDynamicLayout);
Event.observe(window, 'resize', applyDynamicLayout);
That's it!
That's it, it works for us in Safari, Opera, FF and IE 6 or greater.
Also, you can have as many stylesheet links as you like with the same title. For example, let's say you have some IE6 specific kludges for the 'thin' layout. You would do this:
<!--[if lt IE 7]> <link title="thin" disabled="true" href="/stylesheets/thinie6.css" rel="stylesheet" type="text/css" /> <![endif]-->
1 Response to “dynamic resolution + prototype”
Sorry, comments are closed for this article.
Marcos Kuhns Says:
Thanks for posting this. The fact that you have to set stylesheet.disabled to true & then back to false for things to work in Safari was really throwing me off. I just thought I would suggest an even slicker implementation that really shows off Prototype's power.March 10th, 2008 at 06:20 PM
function applyStylesheet(title) { $$('link[type=text/css][title]').each(function(stylesheet) { stylesheet.disabled = true; if (stylesheet.title == title) { stylesheet.disabled = false; } }); }Gotta love css selectors in Prototype.