Sep 01, 2009

Simple jQuery Text Resizer

I have done JavaScript text resizers a couple of different ways before, but I think I found my favorite way on a recent project. In previous projects, I have messed around with determining the current font size and adjusting it appropriately. But, in my opinion, simplifying things has made it a much better implementation.

If you want to skip right to the demo, feel free.

View Demo

Disclaimer

Let me first say that I have started to size text in pixels and soft serving EMs to IE6. There are tons of different font sizing techniques you can use, but this is what is working for me. So use whatever technique you please, and adjust as needed.

Another thing: I hate text resizers. In my opinion, there is no reason to duplicate browser functionality. I feel the same about back and print links, but sometimes the functionality is requested, so I have to build it.

Concept

The idea is very simple: you click on the text size you want, and a class is added to the body to indicate which size the user has selected. Then, we take advantage of that body class when we are writing our CSS to size the different elements appropriately.

Code

Let’s first start as we always should, by creating the markup:

<ul class="resizer">
 <li class="small"><a href="#">A</a></li>
 <li class="medium"><a href="#">A</a></li>
 <li class="large"><a href="#">A</a></li>
</ul> 

jQuery

The markup was simple enough, so let’s get started on the jQuery. First, we want to execute our code when the document is loaded, and then add an event when one of the resizer links are clicked:

$(document).ready(function() {
 $('.resizer a').click(function() {

 });
}); 

Next, we want to get the class of the parent of the link that has been clicked, remove any of the resizer classes from the body, and add the new one:

$(document).ready(function() {
 $('.resizer a').click(function() {
  var textSize = $(this).parent().attr('class');
  $('body').removeClass('small medium large').addClass(textSize);
 });
}); 

We also don’t want to regular action of the link to be followed, so we need to return false:

$(document).ready(function() {
 $('.resizer a').click(function() {
  var textSize = $(this).parent().attr('class');
  $('body').removeClass('small medium large').addClass(textSize);
  return false;
 });
}); 

I also think it is important to remember what text size a user has selected while browsing the site, so we will take advantage of the jQuery Cookie plugin to help us with that. We will set a cookie that denotes which size the user has selected:

$(document).ready(function() {
 $('.resizer a').click(function() {
  var textSize = $(this).parent().attr('class');
  $('body').removeClass('small medium large').addClass(textSize);
  $.cookie('TEXT_SIZE',textSize, { path: '/', expires: 10000 });
  return false;
 });
}); 

Finally, we just need to add a check to the beginning of the script, so that if that cookie is set, we add that size as a class to the body:

$(document).ready(function() {
 if($.cookie('TEXT_SIZE')) {
  $('body').addClass($.cookie('TEXT_SIZE')); 
 }
 $('.resizer a').click(function() {
  var textSize = $(this).parent().attr('class');
  $('body').removeClass('small medium large').addClass(textSize);
  $.cookie('TEXT_SIZE',textSize, { path: '/', expires: 10000 });
  return false;
 });
}); 

CSS

Now is where we get to the really powerful part of doing the text resizing like this: the CSS. We can start by simply stating our text size when it is in the small/default state:

body { font: 12px/18px Arial, sans-serif; } 

Then, we just need to make a simple adjustment for the medium and large sizes:

.medium { font-size: 16px; line-height: 22px; }
.large { font-size: 20px; line-height: 26px; } 

So you can just carry through this idea for the rest of the elements that have been assigned a font size:

h1 { font-size: 30px; line-height: 36px; }
.medium h1 { font-size: 34px; line-height: 40px; }
.large h1 { font-size: 38px; line-height: 44px; }
h2 { font-size: 24px; line-height: 30px; }
.medium h2 { font-size: 28px; line-height: 34px; }
.large h2 { font-size: 32px; line-height: 38px; }
h3 { font-size: 18px; line-height: 24px; }
.medium h3 { font-size: 22px; line-height: 28px; }
.large h3 { font-size: 26px; line-height: 32px; } 

View Demo

The idea is very simple, and it really separates the presentation and behavioral layers. So what do you think? Do you have another technique that you like?

Categories