Unintentionally Blank

Phil Nash on the Internet, Web Standards and Accessibility

The DOM again - A Style Sheet Switcher

Aug 17, 2006

by Phil Nash

A comment a few days ago about the colours used on this site got me thinking. First of all I started considering what would be a nice colour to make my headings so that they were readable for everyone. Rather than stopping there and testing out some new colours, I kept thinking eventually deciding that a new design was the only way forward! Finally, thoughts of accessibillity crept into my head reminding me of Roger Johansson's high contrast layout (originally suggested on A List Apart by Joe Clark) and it all made sense.

If I build a stylesheet switcher into my site then I can keep this design and serve up as many other ones as I like, improving accessibility and keeping the bright blueness of my headings.

Of course, doing this would test and improve my scripting (my ultimate aim) so I got to work.

Weapon of Choice: Javascript

After enjoying a success with my font sizing script I decided on attacking this problem with javascript too. I had seen stylesheet switchers before, but wanted to build one myself to my own specification. My requirements:

  • List stylesheets in the head element using the link tag with rel="stylesheet" or rel="alternate stylesheet"
  • Switch stylesheets without a page reload
  • Persistant styling across the whole site
  • Use a dropdown box to select styles
  • Populate the dropdown box with stylesheet names from the title attribute of the link tag
  • Graceful degradation in browsers without script
  • Future proof javascript

Task 1: Find The Stylesheets

Since I was working with stylesheets defined using the link tag I needed to get all the link tags. Similar to my last DOM script, I used the function getElementsByTagName like so:

var links = document.getElementsByTagName("link");

However, there are more link tags in my header than just stylesheets, so I had to filter out the others.

var count = 0;
var stylesheetArray = new Array();
for (var i=0; i<links.length; i++) {
  type = links[i].getAttribute("type");
 if (type=="text/css") {
   stylesheetArray[count] = links[i];
    count++;
    }

The above code iterates through our array of link tags checking out the type attribute. If it matches "type/css" then it is a stylesheet and it is added to the array stylesheetArray as a counter keeps the indexing under tabs.

Task 2: Change the Stylesheet

Now I have an array with all the link tags containing stylesheet references, all I need to do is change which one is being used to style my content. A stylesheet can be deactivated by calling stylesheet.disabled = true; therefore setting disabled to false would activate a stylesheet. My method was to get the stylesheets using the function above (named getStyleSheets()) and iterate through them, setting disabled to true unless the title matched the parameter handed to the function.

function setStyleSheet(title) {
var stylesheets = getStyleSheets();
for (var i=0; i<stylesheets.length; i++) {
 stylesheets[i].disabled = true;
 if (stylesheets[i].getAttribute("title") »
== title) { stylesheets[i].disabled = false; } } }

Task 3: Persistent Styling

Of course, setting a different stylesheet for one page is all very well, but to experience a chosen style throughout the site we have to employ the use of cookies. As in my font sizing script, I am going to use the javascript cookie functions supplied by Quirksmode. Initially, we need to set a cookie everytime a user changes the stylesheet. This is achieved by adding the line createCookie('style',title,365); at the end of the function setStyleSheet(title) above. The cookie will be called style and it will save the title of the preferred stylesheet.

Now we need to read the cookie and find out what our users preferred stylesheet is, and serve up the default stylesheet if no cookie is found.

if (readCookie('style')) { title=readCookie('style'); }
will find out if a cookie exists and record the title. If no cookie was found we run the following code:

else {
 var stylesheets = getStyleSheets();
 for (var i=0; i<stylesheets.length; i++) {
   if (stylesheets[i].getAttribute("rel")»
.indexOf('alt')== -1) { title = »
stylesheets[i].getAttribute("title"); }

which iterates through our array of stylesheets finding out which ones use rel="alternate stylesheet" and which one is the default stylesheet using rel="stylesheet". The default stylesheet's title is recorded. Finally we set up an event so that the stylesheet is set when we load up the page.

window.onload = function() {
  var title = getPreferredStyleSheet();
 setStyleSheet(title);
}

The Script So Far

See the script in action.

Now, to switch stylesheets all you have to do is add your stylesheets to the head element of your page (making sure you declare type="text/css", rel="stylesheet" or rel="alternate stylesheet" and give them titles). You can download the script then upload it to your own server and add <script type="text/javascript" »
language="javascript" src="switcherpart1.js"></script>
to the head too. Then all you need to do is add links to the function to swap the stylesheet.

If you have two stylesheets with titles default and other respectively, then you can change the stylesheets about using the following links:

<a href="javascript:setStyleSheet('default')">Default</a>
<a href="javascript:setStyleSheet('other')">Other</a>

More To Come

That's all for today, enjoy swapping your stylesheets around with the code so far, I will tackle the remaining requirements (automatically populated drop down box and graceful degradation) in another post.

Update: see the remaining tasks finished off in Stylesheet Switcher part 2.

Unintentionally Blank is Phil Nash's thoughts on web development from 2006-2008. Any code or opinions may be out of date.