Advertisement

Use the jQuery UI to Control the Size of Your Text

by

JQuery's UI can add so much to a web page. There are many different widgets that the UI provides. One up and coming star, is the slider. In this tutorial, I will show you how to use a slider to control the text size of an article on a page. This lets the user control exactly the size that suits them, and is also a pretty impressive feature to have on a site!

The slider portion of this tutorial reproduces a technique originally created by Buck Wilson.

Our Goal

We will eventually want our page to look something like this:

Behavior:

  • When the slider is dragged, a bubble will fade in, telling the current size.
  • The text "current text size" will also appear with the current text size next to it.
  • We will also attempt to make the text increase one px or decrease one px on the click of the plus or minus sign.

preview

Step 1: Getting the Necessary Javascript Files

Obviously we need JQuery, but we're also going to need some UI files to extend JQuery. We can get a UI file that is custom to our needs at the JQuery UI Build Your Download page.

JQuery UI Download Page

As you can see, there are some really great sounding effects there! As tempting as it may be though, we don't need all of these effects to achieve the desired product. All we need is:

Step 2: The HTML

For this tutorial, I'm not going to waste time explaining the basics of HTML, and creating a layout using it and CSS. If you'd like to learn more about that, there are other tutorials here like my Top Panel tutorial or Collis' Tabbed Content tutorial.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Nettuts Slider</title>
<!--[if lt IE 7]>
<script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE7.js" type="text/javascript"></script>
<![endif]-->
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="scripts/jquery.ui.js"></script>
<script type="text/javascript" src="scripts/cookie.js"></script>
</head>
<body>
<div id="header">
  <div class="slider_container">
    <div class="minus"></div>
    <div class="slider_bar">
      <div id="slider_caption"></div>
      <div id="slider1_handle" class="slider_handle"></div>
    </div>
    <div class="add"></div>
  </div>
</div>
<div id="text">
  <h1>Text Size Slider</h1>
  <div id="font_indicator">Current Font Size: <b></b> </div>
  <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularized in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p>
</div>
</body>
</html>

So you'll notice several things:

  1. The PNG fix for IE 5.5 and 6. I've linked directly to the google code page. This means I will have to end every transparent PNG with a -trans.png .
  2. I have also linked directly to JQuery and our custom made UI file.
  3. I have put the necessary tags for the slider in the #header

NOTE: For the slider to work, we need to have a bar and a handle.

Step 3: The CSS

Here is the CSS to make that page look a little bit better. This page is pretty simple, and therefore the CSS is pretty simple as well:

body {
	background: #373737;
	text-align: center;
	margin: 0px;
}
#header {
	width: 700px;
	height: 200px;
	background: #48887d url(images/header.jpg);
	margin-left: auto;
	margin-right: auto;
	position: relative;
}
.slider_container {
	position: absolute;
	height: 25px;
	top: 170px;
	left: 165px;
}
.minus {
	background: url(images/minus-trans.png) no-repeat;
	height: 9px;
	width: 25px;
	overflow: hidden;
	float: left;
	cursor: pointer;
}
.slider_bar {
	background: url(images/bar-trans.png) no-repeat;
	height: 9px;
	width: 316px;
	float: left;
	margin: 0px 5px;
	position: relative;
}
.add {
	background: url(images/add-trans.png) no-repeat;
	height: 25px;
	width: 23px;
	float: left;
	position: relative;
	top: -5px;
	cursor: pointer;
}
.slider_handle {
	background: url(images/selector-trans.png) no-repeat;
	height: 25px;
	width: 12px;
	position: absolute;
	top: -8px;
}
#slider_caption {
	background: url(images/caption-trans.png) no-repeat;
	height: 45px;
	width: 38px;
	overflow: hidden;
	position: absolute;
	top: -50px;
	margin-left:-10px;
	padding: 5px 0px 0px 0px;
	font-family: "Myriad Pro";
	color: #36665d;
	font-weight: bold;
	text-align: center;
}
#text {
	font-family: Helvetica, Arial, sans-serif;
	width: 655px;
	background: #f9f9f9;
	margin-left: auto;
	margin-right: auto;
	padding: 20px 20px 20px 25px;
	position: relative;
}
#text p {
	font-size: 12px;
	text-align: left;
	color: black;
}
#text h1 {
	text-align: left;
	margin-left: 20px;
}

p{
font-family: Arial, Helvetica, sans-serif;
color: #CCCCCC;
}

#font_indicator{
position: absolute;
right: 100px;
top: 50px;
font-size: 10px;
display: none;
}

Again, I'm not going to go into great detail with the CSS either. If you still need more help with that, be sure to check out those two tutorials I mentioned above. If you do have any questions, be sure to let me know in the comments.

Notice that all of the png images that have alpha transparency have a -trans.png ending.

Step 4: Basic Slider Effects

When I was first learning about the slider effect, I Googled it to research a little bit more about it and how it works. Well I was lucky to find this amazing screencast. It had a really neat effect too; a caption that appeared to display the position of the slider, on top of the slider. Unfortunately, they stopped there. We're going to use a variation of their JQuery code as a jumping off point:

$(function() {


	$('#slider_caption').hide();
	var captionVisible = false;
	$('.slider_bar').slider({
		handle: '.slider_handle',
		startValue: 26,
		minValue: 0,
		maxValue: 100,
		start: function(e, ui) {
			$('#slider_caption').fadeIn('fast', function() { captionVisible = true;});
		},
		stop: function(e, ui) { 
			if (captionVisible == false) {
				$('#slider_caption').fadeIn('fast', function() { captionVisible = true;});

				$('#slider_caption').css('left', ui.handle.css('left')).text(Math.round(ui.value * 15/100 + 8 ));

				$("div#text p").animate({fontSize: ui.value * 15/100 + 8 }).fadeIn("slow");
			}
			$('#slider_caption').fadeOut('fast', function() { captionVisible = false; });
			
		},
	
		slide: function(e, ui) {
			$('#slider_caption').css('left', ui.handle.css('left')).text(Math.round(ui.value * 15/100 + 8 ));

			$("div#text p").css({fontSize: ui.value * 15/100 + 8 }).fadeIn("slow");
		}
	});

Some Key Ideas:

  • First, we hide the caption with Javascript. This makes the caption visible if Javascript is disabled for just a little bit more accessibility.
  • As you can see, we now have a .slider modifier and several sub items as well:
    • startValue : This specifies the position that the handle starts at
    • minValue : This specifies the minimum value that the handle will go to
    • maxValue: This specifies the maximum value that the handle will go to
    • start: This allows us to tell JQuery what to do when the user starts sliding the bar
    • stop: This specifies what happens when the slider is let go of
    • slide: This specifies what happens when the slider is being slid
    • handle: This allows us to specify what will be the handle
  • We also assign a variable that will help us know, when stop: occurs, whether the caption is visible or not, and then perform an action based on that conclusion.
  • We also had to put a limit on the font sizes possible, so we limited the slider value possibilities to between 8 and 23. We did this by performing basic math on the value of the slider. (multiplied it by 15/100 and added 8 )
  • This equation resulted in decimal place sizes, so we had to round it the Math.round
  • Notice also, the method by which we made the caption stay on top of the handle. We made the css left value of the caption equal to the handle.
  • Notice that on the stop: I have the text size animated, while on the slide, I have the css size constantly changing. This might seem counter-intuitive, that on slide: I wouldn't animate it, but by the essence of gradually sliding and enlarging the size it does the same thing. If I were to animate instead of just changing the css, it would be choppy and unresponsive.


Step 5: Adding the Text Caption

$(function() {


	$('#slider_caption').hide();
	var calloutVisible = false;
	$('.slider_bar').slider({
		handle: '.slider_handle',
		startValue: 26,
		minValue: 0,
		maxValue: 100,
		start: function(e, ui) {
			$('#slider_caption').fadeIn('fast', function() { calloutVisible = true;});
			$('#font_indicator').fadeIn('slow');
		},
		stop: function(e, ui) { 
			if (calloutVisible == false) {
				$('#slider_caption').fadeIn('fast', function() { calloutVisible = true;});
				$('#font_indicator').fadeIn('slow');
				$('#slider_caption').css('left', ui.handle.css('left')).text(Math.round(ui.value * 15/100 + 8 ));
				$('#font_indicator b').text(Math.round(ui.value * 15/100 + 8 ));
				$("div#text p").animate({fontSize: ui.value * 15/100 + 8 }).fadeIn("slow");
			}
			$('#slider_caption').fadeOut('fast', function() { calloutVisible = false; });
			$('#font_indicator').fadeOut('slow');
			
			
		},
	
		slide: function(e, ui) {
			$('#slider_caption').css('left', ui.handle.css('left')).text(Math.round(ui.value * 15/100 + 8 ));
			$('#font_indicator b').text(Math.round(ui.value * 15/100 + 8 ));
			$("div#text p").css({fontSize: ui.value * 15/100 + 8 }).fadeIn("slow");
		}
	});



Key Ideas about #font_indicator

  • We added the same fade in and fade out effects in the same spots as the caption
  • We left out the css left position though
  • Notice that we have a <b> tag within the div#font-indicator. This not only makes the number stand out more, but allows us to just put the current slider handle value as text into it. If we just appended to the end of the div, every font size value would just pile up at the end.

Step 6: Giving the Plus and Minus Actions

This just wouldn't be a functional design, if we didn't give the plus and minus signs actions on click. This code might be a little bit sloppy and not perfectly efficient, but it gets the job done. This project required a surprising amount of math, which explains some of the wacky numbers that end up being used.

Without further ado, here is the rest of the javascript, I'll explain it afterward:

	  $(".add").click(function(){
    var currentFontSize = $('#text p').css('font-size');
    var currentFontSizeNum = parseFloat(currentFontSize, 10);
    var newFontSize = currentFontSizeNum+1;
	if (newFontSize < 24) {
    $('#text p').css('font-size', newFontSize);
	$('#slider_caption').css('left', newFontSize*19.75 - 158).fadeIn('fast').text(Math.round(newFontSize )).fadeOut();
	$('.slider_handle').css('left', newFontSize*19.75 - 158);
	$('#font_indicator').fadeIn('slow');
	$('#font_indicator b').text(Math.round(newFontSize ));
	$('#font_indicator').fadeOut('slow');
	}
	else{
	$('#font_indicator').fadeIn('slow');
	$('#font_indicator b').text("Isn't 23 big enough?");
	$('#font_indicator').fadeOut('slow');
	}
    return false;
  });
  	  $(".minus").click(function(){
    var currentFontSize = $('#text p').css('font-size');
    var currentFontSizeNum = parseFloat(currentFontSize, 10);
    var newFontSize = currentFontSizeNum-1;
	if (newFontSize > 8) {
    $('#text p').css('font-size', newFontSize);
	$('#slider_caption').css('left', newFontSize*19.75 - 158).fadeIn('fast').text(Math.round(newFontSize )).fadeOut();
	$('.slider_handle').css('left', newFontSize*19.75 - 158);
	$('#font_indicator').fadeIn('slow');
	$('#font_indicator b').text(Math.round(newFontSize ));
	$('#font_indicator').fadeOut('slow');
	}
	else{
	$('#font_indicator').fadeIn('slow');
	$('#font_indicator b').text("Isn't 8 small enough?");
	$('#font_indicator').fadeOut('slow');
	}
	return false;
  });

Some Key Notes:

  • If you know basic Javascript syntax, this should be pretty self evident.
  • I assign an initial variable to get the current font size.
  • I then convert it to an integer
  • I then create another variable that is one value higher.
  • I place a limit between under 24 and above 8, by using an if else statement.

Math Time

Adjusting the handle and caption to react to the plus and minus click was a real challenge. What I ended up doing, was figuring out the width of the bar (316px), and dividing that between the 16 possible font sizes (8-23) to figured out how much space each increment took.

316/16 =

19.75

To be safe, I then needed to figure out the starting spot for the font size. I knew this wasn't exactly 12, because I modified it slightly with the 15/100 + 8. So I took the starting value of the handle (26) and multiplied it by that:

26*15/100 + 8=

11.9

I figured that, since it was rounded it would be twelve anyway.

So I figured that the handle would be the [font size*19.75 - 158 (The first 8 sizes)]px.

Just thought that I'd give you a glimpse into my weird and over complicated math ;) .There's probably much easier ways to do it, but I guess this is my logic.

Step 7: Cookie Time, reading the cookie

For dealing with cookies I used Klaus Hartl's excellent cookie plugin. You can view the basic syntax of the plugin in the link I provided. The challenge, was to find a spot that would reliably set the cookie. I ended up setting it when the browser refreshes or changes the page. This way, it only does it when necessary and realiably too. First we add the code to the top of the javascript file to read the cookie:

var startSize = $.cookie('fontSize');
var startSize = parseFloat(startSize, 12);

$('#text p').css('font-size', startSize);

What I Did:

  • I first read the cookie and sent it to the variable startSize
  • I then changed that variable into an integer
  • I then added that number to the default css of the text

Step 8: Setting The Cookie

As I mentioned above, we need to set the cookie when the page is exited. We do this by using the following code:

  window.onbeforeunload = leaveCookie;

function leaveCookie()
{
			var FontSize = $('#text p').css('font-size');
   			var IntFontSize = parseFloat(FontSize, 10);
			$.cookie('fontSize', IntFontSize);
}

What I Did:

  • NOTE: This JS is outside of the JQuery $(function() {});
  • First, I activated a function when the browser left the page
  • Then I converted the text size into an integer
  • Then I put this into the cookie

That's It!

Hope you found this tutorial useful! Please excuse my programming logic, I don't always think so efficiently :P. If you have any questions or comments please feel free to let me know in the comments!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.