Implementing a Style Selector
This tutorial will demonstrate one way to allow the user to select a style for the given web page by indirectly selecting an external style sheet. The general idea is to allow the user to choose a particular style by picking from a drop down selection menu or by simply clicking a link. The way it is done is by using JavaScript to dynamically specifying which style sheet will be enabled according to which style the user has selected. So, the variations among the different selectable styles might affect any aspect of the page that can be manipulated through style sheets. You can see how this works by selecting a theme for this page. Keep in mind that this page is a basic demonstration and that this method could be used much more extensively to create some very cool effects. In addition to doing a cool trick, this is a way for users to personalize your page by selecting a theme or style. We assume that you know how to use style sheets and how to write HTML.
Style Sheet Precedence
There are three possible ways that a linked style sheet can relate to a page: as persistent, preferred or alternate. The category that a style sheet fits into will determine how and when the style sheet will be applied, particularly when there are other style sheets present. Please read the descriptions below. All links should be declared within the HEAD tag.
This is what the link tag will look like for your average external style sheet:
<link rel="stylesheet" type="text/css" href="default.css" />
Persistent
A persistent style sheet is what we've all probably used. If you wanted to declare just one style sheet you might want to use the LINK tag for a persistent style sheet because it contains the minimum amount of information necessary. It only defines three attributes and is formatted as above. A persistent style sheet is always enabled. You use a persistent style sheet if you want certain style attributes to always be applied. You would declare those style attributes that you wanted to be applied every time in the persistent style sheet. Then, having a persistent style sheet as your base, you could declare the other attributes that you wanted to be changeable in separate style sheets. You'll find out more about that next. Just remember that persistent style sheets are always enabled.
Preferred
A preferred style sheet is applied by default. In addition to any persistent style sheet, one preferred style sheet is enabled when a page is rendered. The persistent style sheet takes precedence, so if a particular attribute of a particular tag is declared in both the persistent and the preferred style sheet, the declaration in the persistent style sheet will take precedence. Multiple preferred style sheets can be declared in which case the first one listed will be rendered. After the page loads the user can select any other preferred style sheets that were declared.
To declare a preferred style sheet a title attribute is needed and the tag looks like this:
<link rel="stylesheet" type="text/css" href="default.css" title="default" />
Alternate
Alternate style sheets are not loaded by default and must be selected by the user in some way. Just like secondary preferred style sheets, alternate style sheets will not be loaded by default. The purpose of having alternate style sheets is to explicitly make sure that it will not load by default.
To declare an alternate style sheet you simply add the word alternate in front of the word stylesheet in the rel attribute:
<link rel="alternate stylesheet" type="text/css" href="style2.css" title="style2" />
Using JavaScript to Enable and Disable Active Style Sheets
Okay, what good is being able to declare all of these different style sheets if only one or the combination of two will be enabled when the page loads? Where do I go from there? Well, Mozilla and Netscape actually allow you to select style sheets through the View tab. IE doesn't have that capability. But wouldn't it be nice if the different style options were right on your actual page so that everyone would know that they had the option? That's where using JavaScript and parts of the DOM comes in. For this page, the JavaScript we implemented is in a separate .js file called styleswitcher.js. We tell the browser that we will use this file with the following tag:
<script type="text/javascript" src="styleswitcher.js"></script>
Like the LINK tags, this belongs within the HEAD tag.
As you can see for this page we've used links to select the active style sheet. Let's look at the function that sets the active style sheet. But first we will look at the A tag that calls the function:
<a href="#" onclick="setActiveStyleSheet('default'); return false;">Default</a>
The tag is very simple. We simply have an anchored link that doesn't link to anywhere but will call setActiveStyleSheet when the onclick event is signaled with the title of the stylesheet as the parameter. Recall what the tag for the preferred style sheet looked like.
Now let's look at the actual function in JavaScript that changes the active style sheet. I don't think I need to discuss how a for loops and functions work so I will speak generally about what this function is doing.
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
First, the outer for loop will go through the array of LINK tags and assign each LINK tag to the variable a so that we can check it out.
The first if statement checks to see if the string style can be found in the rel attribute of current LINK tag. If the indexOf("style") function returns -1 then the string "style" wasn't found in the rel attribute and we're not concerned with this LINK tag. The if statement also checks to see if the title attribute has been assigned any value. If the getAttribute("title") returns false then the title attribute wasn't specified for the tag and this isn't a preferred style sheet.
Notice that we haven't implemented any persistent style sheets and we won't refer to any from here. Simply using one preferred style sheet and multiple alternate style sheets is easier. Next we want to clear the slate by disabling the tag. This will disable any style sheet that is currently enabled. If this is the style we want, we will next re-enable it.
The next if statement will compare the title of the LINK tag with the title parameter that was passed by the onclick event that called this function. If this is the LINK tag that corresponds to the anchored link that was clicked by the user, we want to enable it.
That's it. The page will be updated and the user will see the new style for the page. Next, let's talk about extracting the title from the active style sheet's LINK tag so that we can use it to create a cookie. We will also talk about what to do in case there is no cookie for this site on the user's computer: loading the preferred style sheet.
Getting the Active Style Sheet
You might be saying, "Wait, I thought we already set the active style sheet. What do we need to get it for?" Well, when we want to save the style settings with a cookie, we have to know the name of the active style sheet so that when the user comes back we can enable that same style sheet again. This function will simply return the name of the active style sheet to the calling function. See Style Storage for more details on cookies.
function getActiveStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
}
return null;
}
This function works similarly to the setActiveStyleSheet function that we talked about. It begins by looping through all of the LINK tags with the for statement.
The first condition of the if statement then checks to see if this is a LINK to a style sheet. The second condition checks to see if the title attribute was specified. If it was then this is a preferred or an alternate style sheet.
The last condition of the if statement checks if this was the tag that was enabled. If this and the other two conditions were met, then we want to return the title attribute, a string, to the calling function. This will be something like style1 or style2. See more in the Style Storage section. If no preferred or alternate style sheet is found, this function returns null.
Getting the Preferred Style Sheet
What do we do if the user's never been here and there is no cookie to tell us which style sheet to use? What style sheet do we use? Well, we'll simply find out which style sheet is preferred and load that one. Look at the following function:
function getPreferredStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")
) return a.getAttribute("title");
}
return null;
}
Again, this thing works similarly to the previously described functions. The for loop goes through all of the LINK tags.
The if statement first checks to make sure this is a style sheet. It then checks to make sure this is not an alternate style sheet. Remember that the LINK tag for an alternate style sheet has the keyword "alternate" in it. If the string "alt" is not found in the rel attribute, then the indexOf("alt") function will return -1 and the condition will be satisfied. Lastly, the if statement checks to see that there is a title attribute specified, as there is for a preferred style sheet.
If all of these conditions are satisfied, then this is in fact the preferred style sheet and we want to return its name to the calling function. If no preferred style sheet was found, we simply return null. Again, see Style Storage for the rest of the story on cookies and remembering the user's preferred style.
Well, there you have it! Now you have a way to tell your visitors, "Hey, I remember you!" Have fun!