Style Sheet Switcheroo

2 June 2006 | Tutorials | 8 Comments

From the creator of "15 Days of jQuery" (me):

The first time I saw a style sheet switcher I was either reading A List Apart or Simple Bits, both excellent sites you should visit if you are serious about design.

Since then, I’ve seen many different methods for allowing a visitor to switch a stylesheet with a click of a mouse. But recently I came across a short example of how to do it with jQuery.

I want to show you this example and walk you through it because it not only gives another fine example of the short code you can write with jQuery but also too illustrate some of the more advanced features of the jQuery javascript library.

First, The Code

$(document).ready(function()
{
        $('.styleswitch').click(function()
        {
                switchStylestyle(this.getAttribute("rel"));
                return false;
        });
        var c = readCookie('style');
        if (c) switchStylestyle(c);
});

function switchStylestyle(styleName)
{
        $('link[@rel*=style]').each(function(i)
        {
                this.disabled = true;
                if (this.getAttribute('title') == styleName) this.disabled = false;
        });
        createCookie('style', styleName, 365);
}

What I’ve left out of the demonstration are the functions you’ll see later for creating and reading the cookies.

Familiar Ground

$(document).ready(function()
{
        $('.styleswitch').click(function()

The beginning of the code tells jQuery “As soon as possible, get all elements with the class name of styleswitch and fire off a function when the element is clicked”.

So far so good.

When these chosen elements are clicked the switchStylestyle function will be called. So that’s where we turn our attention next.

What In The World?

The first time I really looked closely at this I was stumped:

        $('link[@rel*=style]').each(function(i)
        {

After searching the web and coming up empty handed I contacted John Resig, the creator of jQuery, and asked him for some hints.

He directed me to some pages on the jQuery site that explain some of the more advanced ways that jQuery can be used to find and manipulate elements on a page.

If you read the short explanations and examples here you’ll soon see that this mysterious line of code tells jQuery “Find all link elements with a rel attribute containing the string ’style’”.

Huh?

Let’s look at how we would create a page with one main stylesheet and two alternate ones:

 <link rel="stylesheet" type="text/css" href="styles1.css"
  title="styles1" media="screen" />
  <link rel="alternate stylesheet" type="text/css" href="styles2.css"
  title="styles2" media="screen" />
  <link rel="alternate stylesheet" type="text/css" href="styles3.css"
  title="styles3" media="screen" />

Notice how all of the links to the stylesheets have a rel attribute with “style” somewhere between the quotation marks.

So, in short, this code is telling jQuery to target all of the stylesheet links in the page.

What Next?

The each() function loops through each of the stylesheet links and performs the operations spelled out in the next few lines of code:

                this.disabled = true;
                if (this.getAttribute('title') == styleName) this.disabled = false;

“Disable every stylesheet link but then un-disable any link where the “title” attribute is the same as the value passed to the switchStylestyle function”

That’s a mouthful too, but it’s really not that tough.

What we’re doing is matching the rel attribute of the links on our page (the clickable links for switching the stylesheets) with the title attribute of the stylesheets (and alternates) available to us.

When one of the clickable links is clicked, a function is called, which finds all the stylesheets, disables all of them, and then turns one back on… the one where the title of the stylesheet link matches the rel attribute of the link clicked.

Whew!

Full Code and Demos

Since Kelvin Luck already created the code, no need for me to replicate it here.

Demo

Code - I won’t link directly to the zip, since that’s sometimes seen as rude. Go to this page and at the bottom is a link to the zip.

Compare to Other Code

I believe ol’ Kelvin got his inspiration from this site where you’ll see that to do this without jQuery is a little bit more complicated and you don’t get all the benefits of Kelvin’s code - namely the long term memory of stylesheet chosen.

Technorati Tags: , , , , , ,

Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.

Subscribe

Email Updates:
Email:
RSS Feed:

RSS information | Email Policy | RSS to Email by Aweber

8 Comments

  1. Sam said on 18 Jun 2006 at 6:51 pm:

    Thanks for taking time to post these examples. Here’s my 2-cents on further code reduction:

    Replace
    this.disabled = true;
    if (this.getAttribute(’title’) == styleName) this.disabled = false;

    With

    this.disabled = this.getAttribute(’title’) != styleName;

  2. v said on 19 Jun 2006 at 7:53 pm:

    Doesn’t work in Safari.

  3. joon said on 23 Oct 2006 at 11:30 am:

    Is $(document).ready(function().. absolutely necessary in this case? In Safari the default style sheet is rendered for a split second then the chosen style is loaded on each page load.

    If it’s possible, let the browser execute as it’s being read. Me (big noob) has to test it out.

    Thanks for the tutorials.!

  4. nic said on 3 Apr 2007 at 7:50 pm:

    How would you modify this code to load a specific style sheet based on an attribute in the ? I’ve been mucking around in the code and I’ve gotten totally confused.

    Thanks for all the tutorials, you’ve gotten me hooked on jquery.

  5. nic said on 3 Apr 2007 at 7:51 pm:

    it’s supposed to say… based on an attribute in the body tag.

  6. Jack said on 4 Apr 2007 at 11:49 am:

    Should be easy enough, just grab the class or attribute of the body tag, and pop that into the mix.

    This is an untested quickie based on an id:

    $(’body’).each(function(){
    switchStylestyle(this.id);
    });

    But I also think that you can perform the same or similar without the use of javascript by putting a class name and/or id in the body tag of your document, and then putting the appropriate rules in your css

    body#one p { color: black; }
    body#two p { color: red;}

  7. nic said on 4 Apr 2007 at 7:32 pm:

    Jack,

    Thanks for the example, that’s exactly what I needed.

    I’ve been doing the tutorials on jQuery and I literally know 200% more than when I wrote that first question. The problem I’m trying to solve is that we want to have an individual style for multiple users on the same set of pages.

    For example two people visit page Cranberry, if user A came from page Apple they would have the Apple style loaded, and if user B came from page Banana they would have the Banana style loaded.

    If someone visited Cranberry straight up they would see the default theme.

    We already had this system in place using an onLoad script, but I wanted to switch over to jQuery.

  8. Mike said on 26 Apr 2007 at 12:42 pm:

    Oops, forgot to mention one thing. In the line that generates the random number:

    var randNum = Math.floor(Math.random() * 4);

    Change the number you are multiplying by, in this case 4, to the number of alternate stylesheets you have listed, or one more than the last ‘title’ number. In my case I have 4 alternate stylesheets numbered 0 through 3, so I multiply by 4.

Leave a Reply

You can follow the discussion through the Comments feed. You can also pingback or trackback from your own site.