Introduction
Many web pages can benefit from an ability for the user to change the font size dynamically. This article describes a method to build web pages that provide that functionality using HTML and JavaScript.
Background
Quite often, I find myself using the Ctrl-Plus shortcut (in Internet Explorer) to increase the size of a web page font. Unfortunately, that shortcut increases the size of all web page components (e.g., figures, text boxes, etc.), some of which I do not want increased.
Providing the ability to increase the font size of only selected portions of the web page text requires some relatively advanced JavaScript interaction with the Document Object Model that underlies all web pages. But once mastered, developing the method is relatively straightforward.
Using the Code
The pertinent directory structure of my website is:
GGGustafson
CSS
CSS.css
Images
favicon.ico
Lenna.png
Melitta_teapot.png
Utah_teapot.png
ValidXHTML10.png
Scripts
control_font_size.js
cookies.js
next_page.js
Default.html
Note that I am hosting my site on Microsoft Office Live (MSOL). MSOL expects web pages to be ASPX or HTML pages. For this article, I will be using an HTML page in the DynamicFontSize
downloadable source. However, if the reader uses Visual Studio to build web site pages, choose ASPX pages. Once a new page is defined, you may, if desired, delete the aspx.cs and designer.cs pages that are automatically generated by Visual Studio. You may also change the web page extension from .aspx to .html (replying "Yes" in the following dialog box).
The variable_font Class
To limit text font sizing to specific HTML elements, we need a mechanism to identify those text elements that we want to allow to be resized. I chose to assign a class named variable_font
to each element that was to participate in resizing.
First, in the CSS file, define a selector for variable_font
.
.variable_font
{
font-size:13pt;
}
This rule assigns the default font size for all elements to which the class applies. Note that the value chosen here should be the same as that chosen for the DEFAULT_FONT_SIZE
global variable declared at the top of the control_font_size
script.
Then assign the class to each element that will participate in the text font sizing. For example:
<p class="variable_font" ></p>
This class may be applied to any element that allows a font size attribute (e.g., input
, p
, td
, span
, etc.).
Initialization
On window load, the initialize_font_size
function must be invoked. For our purposes, I'll simply attach it as the body onload
event handler.
<body onload="initialize_font_size('CSS.css', '.variable_font');">
The initialize_font_size
function is found in the control_font_size
script:
function initialize_font_size ( css_sheet_name,
selector )
{
if ( document.styleSheets && css_sheet_name && selector )
{
var done = false;
var found = false;
var i = 0;
var sheet_rules;
var sheets = document.styleSheets;
var the_rules = new Array();
css_sheet_name = css_sheet_name.toLowerCase ( );
i = 0;
done = ( i >= sheets.length );
while ( ! ( done || found ) )
{
var sheet_name = sheets [ i ].href.substring (
sheets [ i ].href.lastIndexOf ( '/' ) + 1 ).
toLowerCase ( );
if ( sheet_name == css_sheet_name )
{
the_rules = sheets [ i ].cssRules || sheets [ i ].rules;
found = true;
}
else
{
i++;
done = ( i >= sheets.length );
}
}
if ( found )
{
found = false;
i = 0;
done = ( i >= the_rules.length );
while ( ! ( done || found ) )
{
found = ( the_rules [ i ].selectorText.toLowerCase ( ) ==
selector.toLowerCase ( ) );
if ( found )
{
variable_font_rule = the_rules [ i ];
}
else
{
i++;
done = ( i >= the_rules.length );
}
}
}
if ( variable_font_rule )
{
var cookie = read_cookie ( COOKIE_NAME );
var font_size = DEFAULT_FONT_SIZE;
if ( cookie )
{
font_size = parseInt ( cookie, 10 );
}
variable_font_rule.style.fontSize = ( font_size ) + "px";
create_cookie ( COOKIE_NAME, font_size.toString ( ), 0 );
}
}
}
If the document includes at least one CSS style sheet and the two required arguments are provided, the initialize_font_size
script:
- Initializes the global variable
variable_font_rule
to point to the CSS rule that controls the font size for all elements that are declared as "class='selector'
" in the cascading style sheet named 'css_sheet_name
' (note that the invoker supplies the actual values for 'css_sheet_name
' and 'selector
'). - If the global variable
variable_font_rule
is successfully initialized (i.e., is not undefined or null
), reads a cookie named COOKIE_NAME
to determine the new font size. If the cookie does not exist, the new font size is set to the value specified by the global variable DEFAULT_FONT_SIZE
. - Sets the font sizes of all affected web page elements to the new font size by simply setting the
style.fontSize
of variable_font_rule
to the new font size. - Writes the new font size to the cookie named
COOKIE_NAME
.
The string
containing the name of the cascading style sheet file name must include the extension, and the string
containing the selector (class name) found in the specified cascading style sheet must include the selector prefix (i.e., '.' for classes).
Mouse Click Resizing
I think that the easiest way to indicate to a user that text resizing is available is to present a visual clue on the web page. To that end, following NPR as a guide, the phrase 'text size' followed by differently sized letter 'A's is used. Additionally, a title that appears when the mouse hovers over the letter is included to make the action taken on a mouse click more obvious.
The HTML that triggers mouse click text sizing (shown to the right in the figure that appears at the top of this article) is encapsulated in a <div>
.
<div class="textsize">
text size
<a class="small"
href="javascript:void(0);"
onclick="reduce_font_size()"
title="Reduce font size">
A
</a>
<a class="big"
href="javascript:void(0);"
onclick="restore_font_size()"
title="Restore default font size">
A
</a>
<a class="bigger"
href="javascript:void(0);"
onclick="increase_font_size()"
title="Increase font size">
A
</a>
</div>
This font sizing implementation requires three functions, reduce_font_size
, restore_font_size
, and increase_font_size
, all found in the control_font_size
script file. All three require that initialize_font_size
has been successfully invoked, that is, the global variable variable_font_rule
has been successfully initialized. Also, each of these functions requires cookie support found in the cookies script file.
function reduce_font_size ( )
{
if ( variable_font_rule )
{
var cookie = read_cookie ( COOKIE_NAME );
var font_size = DEFAULT_FONT_SIZE;
if ( cookie )
{
font_size = parseInt ( cookie, 10 );
}
if ( font_size > MINIMUM_FONT_SIZE )
{
font_size--;
variable_font_rule.style.fontSize = ( font_size ) + "px";
create_cookie ( COOKIE_NAME, font_size.toString ( ), 0 );
}
}
}
function restore_font_size ( )
{
if ( variable_font_rule )
{
var font_size = DEFAULT_FONT_SIZE;
variable_font_rule.style.fontSize = ( font_size ) + "px";
create_cookie ( COOKIE_NAME, font_size.toString ( ), 0 );
}
}
function increase_font_size ( )
{
if ( variable_font_rule )
{
var cookie = read_cookie ( COOKIE_NAME );
var font_size = DEFAULT_FONT_SIZE;
if ( cookie )
{
font_size = parseInt ( cookie, 10 );
}
if ( font_size < MAXIMUM_FONT_SIZE )
{
font_size++;
variable_font_rule.style.fontSize = ( font_size ) + "px";
create_cookie ( COOKIE_NAME, font_size.toString ( ), 0 );
}
}
}
The global constants used in the control_font_size
script are:
var COOKIE_NAME = "SAVED_VARIABLE_FONT_SIZE";
var DEFAULT_FONT_SIZE = 13;
var MAXIMUM_FONT_SIZE = 24;
var MINIMUM_FONT_SIZE = 8;
The cookies script provides support for the font sizing scripts. A cookie is set to preserve the user's desired font size from web page load to web page load.
function create_cookie ( name, value, days )
{
var expires = "";
if ( days )
{
var date = new Date ( );
date.setTime ( date.getTime ( ) +
( days * 24 * 60 * 60 * 1000 ) );
expires = "; expires=" + date.toGMTString ( );
}
document.cookie = name + "=" + value + expires + "; path=/";
}
function read_cookie ( name )
{
var cookie = null;
if ( document.cookie.length > 0 )
{
var cookies = document.cookie.split ( ';' );
var name_with_equal = name + "=";
for ( var i = 0; ( i < cookies.length ); i++ )
{
var a_cookie = cookies [ i ];
a_cookie = a_cookie.replace ( /^\s*/, "" );
if ( a_cookie.indexOf ( name_with_equal ) === 0 )
{
cookie = a_cookie.substring ( name_with_equal.length,
a_cookie.length );
break;
}
}
}
return ( cookie );
}
function erase_cookie ( name )
{
create_cookie ( name, "", -1 );
}
The <script></script>
blocks that I include to implement dynamic font sizing are:
<script type="text/javascript"
defer="defer"
src="Scripts/control_font_size.js"></script>
<script type="text/javascript"
defer="defer"
src="Scripts/cookies.js"></script>
<script type="text/javascript"
defer="defer"
src="Scripts/next_page.js"></script>
I place the <script></script>
blocks before the </body>
tag. I add defer="defer"
to the <script>
include blocks to ensure that the HTML loads completely before the scripts are loaded. Note that the "defer" attribute of the <script>
tag is currently implemented only by Internet Explorer. I expect other browsers to implement this standard attribute in the future. Of course, all of the scripts can be combined into one script file. Then that single script file can be included.
Keyboard Font Sizing
The user may be provided font sizing keyboard shortcuts:
- '+' - increases font size
- '-' - decreases font size
- ' ' - restores font size to default
The shortcuts are processed by the on_keyup
event handler found in the control_font_size
script file. Again, cookies are used to "remember" the last font size set by the user.
function on_keyup ( e )
{
var code = (window.event) ? event.keyCode : e.keyCode;
switch ( code )
{
case 109 :
case 189 :
reduce_font_size ( );
break;
case 107 :
case 187 :
increase_font_size ( );
break;
case 32 :
restore_font_size ( );
break;
default :
break;
}
}
This event handler is registered by attaching it to the document.onkeyup
event. In the control_font_size
script file, this is accomplished by the statement:
document.onkeyup=on_keyup;
The expiration date of the cookie is set to zero so that the cookie exists only for the duration of the session. The cookies script was developed from JavaScript found at Peter-Paul Koch's cookies web page.
References
Cookie functions contain source code for the cookies script.
Browsers Tested
Opera operates somewhat strangely, so I am unwilling to include it as a successfully tested browser.
History
- 11/15/2010 - Revised article to address reader's comments, to correct typographic and logic errors, and to test the paradigm on common browsers
- 12/6/2010 - Minor revisions to document; added browser versions of browsers used for testing