This page explains how to use JavaScript for stylesheet switching and text resizing, as well as covering cookie management.

Web Technology:Controlling style and text with JavaScript
Control the page:
Show table of contents,
Change page style,
Adjust text size
Introduction
T
C
F
<

Allowing readers to control the look of the page has a number of advantages. First and foremost is accessibility. Wired Magazine has done a redesign of their site in the two years or so, one of the features they added was the ability to control the size of text on screen. This is useful for all the viewers with poor vision. Allowing changes to the complete style has some advantages as well. Multiple different layouts could be created to cater to different audiences.

Stylesheet switching

<

There are multiple ways to change the current page style. A List Apart posted a discussion on this some time ago. The reason to roll my own was that I needed toggle functionality. Meaning that as long as you click the C control at the top of the page the stylesheets will keep cycling through a predefined list. There are other differences between the two implementations as well.

var stylelist = new Array(); stylelist[0] = "projecttree.css"; stylelist[1] = "alternate.css"; var stylepath = "./css/"; var defaultstyle = 0; function togglestyle(sheetid, sheetname){ var linkelement; if(sheetid){ for(var i = 0; (linkelement = document.getElementsByTagName("link")[i]); i++){ if(linkelement.getAttribute("rel").indexOf("style") != -1 && linkelement.media == "screen"){ if(linkelement.href != stylelist[sheetid]){ linkelement.href = stylepath + stylelist[sheetid]; } } } }else if(sheetname){ for(var i = 0; i < stylelist.length; i++){ if(sheetname == stylelist[i]){ togglestyle(i, null); break; } if((j+1) == stylelist.length){ togglestyle(defaultstyle, null); break; } } }else{ for(var i = 0; (linkelement = document.getElementsByTagName("link")[i]); i++){ if(linkelement.getAttribute("rel").indexOf("style") != -1 && linkelement.media == "screen"){ for(var j = 0; j < stylelist.length; j++){ exp = new RegExp(stylelist[j]); var result = exp.exec(linkelement.href); if(result == stylelist[j]){ linkelement.href = stylepath + stylelist[(++j%stylelist.length)]; break; } } } } } return; }
Example 1

First we setup the global variables this includes the list of stylesheet names that will be toggled between, the path to the stylesheets and the default stylesheet selection. The togglestyle method takes two parameters neither of which is required. If sheetid is not null, this function will set the current stylesheet to the value stored in the stylelist array under that index. The first for loop looks at all HTML elements of type link, and then just the ones that have their media attribute set to screen. If you are not sure what these are, reference the "CSS style" section of the Simple website templates article. Once we find the element that meets those criteria, and we are only expecting one, we will set the href attribute to point to the new location.

If the sheetname variable is passed to the function instead, we will determine the index of the stylesheet that was passed in the stylelist array, provided that it exists in the first place, and if it does, we will call the same function again passing the sheetid parameter instead.

If both parameters are null, we will attempt to match the currently loaded stylesheet against the stylelist array. After determining its index, we will load the next stylesheet in the array wrapping around the end with the help of the modulo function.

Changing text size

<

There are at least two ways of getting this accomplished. You can use the stylesheet switching technique above to alternate between stylesheet with different text sizes, or you can control the text size through JavaScript directly. The latter solution is presented here. A derivative of the code below is executed when you click the F control.

var maxtextsize = 15; var mintextsize = 12; function togglefontsize(offset){ var fontsize = parseInt(document.getElementById('page').style.fontSize); if((fontsize + 1) <= maxtextsize){ fontsize++; } else{ fontsize = mintextsize; } if(offset){ fontsize = (mintextsize + parseInt(offset)); } document.getElementById('page').style.fontSize = (fontsize) + "px"; return; }
Example 2

Because JavaScript cannot easily access CSS information that is not included in-line with the HTML code, we define upper and lower limits of the text size. The togglefontsize function will rotate through the available values. Optionally you can pass the offset variable to this method, this will come in useful for restoring the font size settings from cookies. The first line of the method attempts to read the current CSS font-size value. This may return undef. If that happens, the next if statement will fail and font will be set to the minimum size. Unless the offset variable was passed, in which case font-size will become minimum incremented by the offset. Lastly, we set the fontsize for the page. This code assumes that the container element for the page has id "page". Keep in mind that if any child elements of page define their own font sizes, those will not be altered after this function executes.

Browser cookie access with JavaScript

<

Before we can store preferences we need some basic code to deal with cookies, much in the same way that code for URL parameter parsing was done.

function parsecookie(){ var cookie_pairs = new Object(); cookie_pairs.names = new Array(); cookie_pairs.values = new Array(); var cookie = document.cookie; if(cookie == "") { return null; } var pairs = cookie.split(";"); for(var i = 0; i < pairs.length; i++){ var pos = pairs[i].indexOf('='); if(pos == -1){ continue; } var cookie_name = pairs[i].substring(0,pos); var cookie_value = pairs[i].substring(pos+1); cookie_pairs.names[i] = cookie_name; cookie_pairs.values[i] = cookie_value; } return cookie_pairs; }
Example 3

The above code will read all the cookies that the browser is willing to return and store them in an object after the name, value pairs have been parsed. After initializing the storage objects, we will read the cookies from the browser, if there are none, we return null. Otherwise we split the cookies around a semicolon that is used to separate them. Then in the for loop we will further separate the cookies into name, value pairs by splitting the cookie string around the equal sign. After which we will store the name and the value of the cookies in name and value array respectively with the same index. Lastly we will return the parsed cookies object to the caller.

function getcookieparam(cookie_pairs, name){ if(cookie_pairs == null){ return null; } exp = new RegExp(name); for(var i = 0; i < cookie_pairs.names.length; i++){ var result = exp.exec(cookie_pairs.names[i]); if(result == name){ return cookie_pairs.values[i]; } } }
Example 4

The function in example 4 will return the values of a cookie by cookie name. Because we stored the names and the values at the same index in the arrays we can do this simply by iterating over the names array comparing stored cookies to the name that was provided. If a match is made, the associated value will be returned.

Using cookies to store preferences

<

Now that cookie management basics are in place we can use them to store visitor preferences for stylesheet and text size. The easiest way to do this would be to store the array index for each of those values, so first we need to determine the font-size offset and the stylesheet name index in the stylelist array. Below is the code to determine the font-size offset.

function getfontsize(){ var fontsize; var textsize = parseInt(document.getElementById('page').style.fontSize); if(textsize){ fontsize = "" + Math.abs(textsize - mintextsize); } else{ fontsize = 0; } return fontsize; }
Example 5

Here we simply read the current font-size of the element with id "page", if we cannot determine what it is, we assume that the text is at its minimum size so the offset is zero. Next we need to determine the array index of the currently selected stylesheet.

function getstyleid(){ var linkelement; for(var i = 0; (linkelement = document.getElementsByTagName("link")[i]); i++) { if(linkelement.getAttribute("rel").indexOf("style") != -1 && linkelement.media == "screen"){ break; } } for(var j = 0; j < stylelist.length; j++){ exp = new RegExp(stylelist[j]); var result = exp.exec(linkelement.href); if(result == stylelist[j]) { return j; } if((j+1) == stylelist.length){ return defaultstyle } } }
Example 6

In code sample 6, we first iterate over all the link elements in the document looking for the one that stores the stylesheet reference for onscreen display, once we find it, we stop looking. Next we look for the name of that stylesheet in the stylelist array, when we find it, we return it, if we do not find it, we simply return the default stylesheet index.

Now that our preference values are ready to be stored, we should package them in a cookie and attach it to the request.

function storestylepref(){ var fontpref = getfontsize(); var stylepref = getstyleid(); var pref = stylepref + "," + fontpref; var date = new Date(); date.setTime(date.getTime()+(30*24*60*60*1000)); var expires = "expires="+date.toGMTString(); document.cookie = "site_pref=" + pref + ";" + expires; return; }
Example 7

Above we get the current stylesheet and text size preferences, separate them with a comma, and add them to a cookie that is set to expire in 30 days. The call to the storestylepref function should be put into the onunload attribute of the body tag of the page.

Once we stored our preferences, we now need to apply them the next time the user visits.

function loadstylepref(){ var pref = getcookieparam(parsecookie(), "site_pref"); if(pref){ var prefs = pref.split(","); togglestyle(prefs[0], null, 0); togglefontsize(prefs[1], 0); } return; }
Example 8

The loadstylepref function is simple, it builds on all the code we have written thus far. After being called, this method will attempt to locate a cookie by the name "site_pref", if it exists it will attempt to use the values stored in it to restore the stylesheet and text size preferences. First we split the value around the comma we used to separate the stylesheet index from the font-size offset and then we simply call the togglestyle and togglefontsize with the first and second values of the resulting array. The call to the loadstylepref function should be made from the onload attribute of the body tag of the page. The complete working implementation of this code is being used by this site at /js/style.js

More JavaScript samples
<

More useful code samples are provided in the Common JavaScript examples and More common JavaScript examples articles on this site.