A Simple jQuery Stylesheet Switcher

Published April 2, 2009 by saurav.roy.

jQuery stylesheeet switcher

There are lots of reasons you might want to offer your users more than one CSS file for your website:

  • You want to offer a “stylish” low-contrast and an easy-to-read high-contrast version of your site.
  • You have many low-vision readers and want to give them easy access to a customized stylesheet with a larger typeface.
  • Your site is schizophrenic and you want to be able to change the look quickly.

Whatever the reason, it’s amazingly easy to create a function that swaps between multiple stylesheets using jQuery.

The first step of course is to build several different CSS files, which we’ll then swap between. Once that is done, we can dive into the XHTML and jQuery that makes the magic happen.

The XHTML

First, we need to create a set of links that will allow the user to swap between CSS files. You can make this as simple or as fancy as you’d like. For the sake of brevity, my links are simple:

<ul id="nav">
	<li><a href="#" rel="/path/to/style1.css">Default CSS</a></li>
	<li><a href="#" rel="/path/to/style2.css">Larger Text</a></li>
	<li><a href="#" rel="/path/to/style3.css">Something Different</a></li>
</ul>

Here I have three links, each with a “rel” attribute indicating which CSS file the link will load. Technically, I could have just as easily put this information in the “href” attribute, but I didn’t want to for one specific reason: if the user has JavaScript disabled and the CSS file is listed in the href, then clicking the link will send the user to the CSS file directly (not loading it like we intended). But our way, if JS is disabled, the user gets nothing at all: which is certainly preferable to the less savory alternative.

The jQuery

Like I promised, the jQuery is really simple:

$(document).ready(function() { 
	$("#nav li a").click(function() { 
		$("link").attr("href",$(this).attr('rel'));
		return false;
	});
});

This function waits until the document is loaded (generally an important step when interacting with the DOM), then attaches a click function to each of our nav anchors. The function basically says, “when someone clicks on this link, replace the link (stylesheet) tag’s href attribute with the contents of this link’s rel attribute.” The “return false” at the end just stops the browser from trying to follow the link.

Of course, you might have to get more detailed if you have more than one link tag, for example, but that’s easily done by giving the link tag a class (“changeme,” for argument’s sake), and writing something like this:

$("link.changeme").attr("href",$(this).attr('rel'));

And while this stylesheet switcher is already complete, we might want to give it some memory: after all, your users might get annoyed if they have to switch their styles back to their preferences every time they visit your site. For that, we’ll need to set a cookie. And to make that easier, I’ll use the jQuery cookie plugin (which I’ve talked about previously when building a popout ad).

With the plugin loaded, we can modify our jQuery thusly:

$(document).ready(function() { 
	if($.cookie("css")) {
		$("link").attr("href",$.cookie("css"));
	}
	$("#nav li a").click(function() { 
		$("link").attr("href",$(this).attr('rel'));
		$.cookie("css",$(this).attr('rel'), {expires: 365, path: '/'});
		return false;
	});
});

Now we have two statements. The first one checks as soon as the page is done loading to see if a cookie called “css” has been set. If so, it sets the stylesheet to be the one indicated in that cookie. Otherwise, it does nothing.

Our click function is much the same, except after we set the stylesheet, we also set a cookie. This cookie doesn’t expire for an entire year (and each time the user changes their stylesheet preferences, it would reset this timer), giving them a good 365 of CSS bliss.

Fine Tuning

There is one minor annoyance with this stylesheet switcher: there’s generally a flash of the “default” CSS when the user loads the page. That’s because the script waits until the document is “ready” before switching the link’s href. There is a way around this: moving the first “if” statement outside of the document ready function, like so:

if($.cookie("css")) {
	$("link").attr("href",$.cookie("css"));
}
$(document).ready(function() { 
	$("#nav li a").click(function() { 
		$("link").attr("href",$(this).attr('rel'));
		$.cookie("css",$(this).attr('rel'), {expires: 365, path: '/'});
		return false;
	});
});

Generally speaking, you don’t want to run any jQuery until your document is ready. However, so long as your jQuery comes after your link tag in your document structure, like shown below, this shouldn’t be a major concern:

<link rel="stylesheet" type="text/css" href="style1.css" />
<script type="text/javascript" language="javascript" src="jquery.js"></script>
<script type="text/javascript" language="javascript" src="jquery.cookie.js"></script>
<script>... your jQuery goes here...</script>

This means your jQuery will run before the document is done loading, and thus your link tag’s href will be swapped before your CSS has been applied. As I said before, it’s generally a bad idea to manipulate the DOM before document ready, but because we know the exact tag we want to manipulate and can place our jQuery below it in the DOM, we should be safe in this one specific instance.

Here’s an example if you would like to see this technique in action.

Share and Enjoy !

0Shares
0 0