Unintentionally Blank

Phil Nash on the Internet, Web Standards and Accessibility

First Go With The DOM - Changing Font Sizes

Aug 02, 2006

by Phil Nash

While this post has some interesting JavaScript in, there are also a lot of mistakes. Please have a look at fontSizer v2.0 which is much, much better!

Accessibility matters. I am trying to make this site as accessible as I can in order to learn the methods and set an example. My most recent task has been to add the links you will see at the top right of the page, links to increase or decrease the font size. Initially I searched for a quick bit of code to do this, but none of the results gave me exactly what I wanted, so I decided to do it myself, thus immersing myself in the DOM for the first time.

My requirements were a script that changed the text size on a page without loading a different stylesheet or forcing a reload and that once the text size was altered this would persist throughout the site. I also wanted to continue using relative font size attributes (this site's font sizes are all done using ems so that IE users may resize using the browser controls). My searches found scripts that changed pixel sizes and only worked for the current page, so I got to work.

Task 1: Manipulate the DOM

This was my first time playing with the DOM, so I had to find the relevant javascript commands that would help. Anyone with any experience in this matter is already shouting out either getElementById() or getElementsByTagName(). I decided upon selecting my elements by the tag name as I was aiming to increase the text size across the board. Since this site is laid out using divs I used getElementsByTagName('div'). This made it really easy, as all I had to was iterate through the list of elements that I got, changing the font size for each of them as follows:

function setFontByTag(e, v) { var elements = document.getElementsByTagName(e); for(var i = 0; i < elements.length; i++) { elements.item(i).style['fontSize'] = v; } }

Task 2: Size the font

Now I have the function that will select all my elements I need to pass it a font size that won't become too big or too small too fast. I went through a lot of testing to see the effects of different ways of sizing the text and finally settled on this range of em values:

var sizes = new Array('0.9', '1', '1.1', '1.2', '1.3');

The standard size will be 1em, so I set a variable si (size index) to 1, such that sizes[si] = 1 too. All I needed to do then was set the function to increase or decrease si depending on an input (and limiting si so that it didn't extend beyond the size of the array). Voila:

var sizes = new Array('0.9', '1', '1.1', '1.2', '1.3'); var si = 1; function changeSize(inc) { if (!document.getElementsByTagName) {return false;} // If the browser doesn't support // getElementsByTagName then don't do anything if (inc == '1') { si+=1; if (si>4) size=4; } else if (inc == '-1') { si-=1; if (si<0) size=0; } setFontByTag('div', sizes[si]+'em'); }

Task 3: Persistent Styling

So now we have the two functions that increase or decrease the font size, using relative values. Now I wanted to ensure that a visitor using a larger text size didn't have to apply the function to every page they visit. Time to deal with cookies, another first. Thankfully there are a number of good references for setting cookies in javascript. I used Peter-Paul Koch's cookie code from QuirksMode. After adding the functions to my file I then added two more lines to the changeSize function. Right at the bottom I added:

createCookie('fs',si,30);

This set a cookie called fs, with the value of si and an expiry date in 30 days time. Then I added the line:

if(readCookie('fs')) { si = parseInt(readCookie('fs')); }

as the first line of the function changeSize, so that if the size had already been changed it would remain persistent.

These two lines dealt with creating and maintaining the cookie and current size of the text on one page, but reloading or navigating somewhere else still needed to be sorted.

I wrote this small function, to initialise the page correctly if the cookie fs was present:

 function init() {
if(readCookie('fs')) { si = parseInt(readCookie('fs')); }
if (!document.getElementsByTagName) {return false;}
setFontByTag('div', sizes[si]+'em');
}

This code was then run using the onLoad command of the body element which resized the text after the page had loaded, but made for an interesting effect whilst it did so. This wasn't my aim, so I had to come up with a different approach. Eventually I left javascript behind entirely and turned to PHP.

Since I was changing the size of the text in each div, I figured that adding a css style, for the generic div, to the page if the cookie was set would work without any headaches.

<?php if(isset($_COOKIE['fs'])) { ?>
<style type="text/css">
<!--
div { font-size:
<?php $arr = array('0.9', '1', '1.1', '1.2', '1.3');
echo $arr[$_COOKIE['fs']]; ?>em; }
// -->
</style>
<?php } ?> 

This worked and thus after adding the links;

<a href="javascript:changeSize(1)">+A</a> |
<a href="javascript:changeSize(-1)">-A</a>

the code was complete.

Please test out the functionality yourself, if there are any problems with it let me know. If you have any tips or other thoughts too, feel free to comment.

Finally, if you want to use this code yourself, here is the code: Download fontsizer.

Edit: I don't think the link was working, sorry! Things are fixed now, you can download the fontsizer if you want to have a go with it.

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