A Simple jQuery Stylesheet Switcher

August 25th, 2009 | by admin |

jQuery stylesheeet switcher

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

  • You want to offer a “styl­ish” low-​​contrast and an easy-​​to-​​read high-​​contrast ver­sion of your site.
  • You have many low-​​vision read­ers and want to give them easy access to a cus­tomized stylesheet with a larger typeface.
  • Your site is schiz­o­phrenic and you want to be able to change the look quickly.

What­ever the rea­son, it’s amaz­ingly easy to cre­ate a func­tion that swaps between mul­ti­ple stylesheets using jQuery.

The first step of course is to build sev­eral dif­fer­ent 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 cre­ate a set of links that will allow the user to swap between CSS files. You can make this as sim­ple 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 indi­cat­ing which CSS file the link will load. Tech­ni­cally, I could have just as eas­ily put this infor­ma­tion in the “href” attribute, but I didn’t want to for one spe­cific rea­son: if the user has JavaScript dis­abled and the CSS file is listed in the href, then click­ing the link will send the user to the CSS file directly (not load­ing it like we intended). But our way, if JS is dis­abled, the user gets noth­ing at all: which is cer­tainly prefer­able 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 func­tion waits until the doc­u­ment is loaded (gen­er­ally an impor­tant step when inter­act­ing with the DOM), then attaches a click func­tion to each of our nav anchors. The func­tion basi­cally says, “when some­one clicks on this link, replace the link (stylesheet) tag’s href attribute with the con­tents of this link’s rel attribute.” The “return false” at the end just stops the browser from try­ing to fol­low the link.

Of course, you might have to get more detailed if you have more than one link tag, for exam­ple, but that’s eas­ily done by giv­ing the link tag a class (”changeme,” for argument’s sake), and writ­ing some­thing like this:

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

And while this stylesheet switcher is already com­plete, we might want to give it some mem­ory: after all, your users might get annoyed if they have to switch their styles back to their pref­er­ences every time they visit your site. For that, we’ll need to set a cookie. And to make that eas­ier, I’ll use the jQuery cookie plu­gin (which I’ve talked about pre­vi­ously when build­ing a popout ad).

With the plu­gin loaded, we can mod­ify 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 state­ments. The first one checks as soon as the page is done load­ing to see if a cookie called “css” has been set. If so, it sets the stylesheet to be the one indi­cated in that cookie. Oth­er­wise, it does nothing.

Our click func­tion 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 pref­er­ences, it would reset this timer), giv­ing them a good 365 of CSS bliss.

Fine Tun­ing

There is one minor annoy­ance with this stylesheet switcher: there’s gen­er­ally a flash of the “default” CSS when the user loads the page. That’s because the script waits until the doc­u­ment is “ready” before switch­ing the link’s href. There is a way around this: mov­ing the first “if” state­ment out­side of the doc­u­ment ready func­tion, 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;
	});
});

Gen­er­ally speak­ing, you don’t want to run any jQuery until your doc­u­ment is ready. How­ever, so long as your jQuery comes after your link tag in your doc­u­ment struc­ture, 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 doc­u­ment is done load­ing, and thus your link tag’s href will be swapped before your CSS has been applied. As I said before, it’s gen­er­ally a bad idea to manip­u­late the DOM before doc­u­ment ready, but because we know the exact tag we want to manip­u­late and can place our jQuery below it in the DOM, we should be safe in this one spe­cific instance.

Here’s an exam­ple if you would like to see this tech­nique in action.

You must be logged in to post a comment.