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.
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.
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:
- UI Core
- Slider
- Klaus Hartl's Cookie plugin
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:
- 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 .
- I have also linked directly to JQuery and our custom made UI file.
- 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 =

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=
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.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.














User Comments
( ADD YOURS )Tony September 4th
1st
( )steve September 4th
WOW - that’s something very, very, very cool!
thx for this tutorial!
( )Dainis Graveris September 4th
Wow, demo looks just great - never thought jquery can do something like this too!
( )Craigsnedeker September 4th
NO!!! NOT MATH
I think this is awesome!
( )Ben Griffiths September 4th
Great tutorial, and a fantastic way to show how jquery can be used to help usability as well as create snazzy effects - thanks
( )curtis allen September 4th
nice tutorial, keep up the good work.
( )sds March 3rd
asasd
( )Kurt Cruse September 4th
@Toni
Sweet comment, congratulations. Maybe later you can build a huge RSS feed and check it every 9 seconds so you can do it 3 more times today and well then you’ll be the coolest guy ever. Ever.
On a more applicable note - great tutorial! Love this site.
( )James September 4th
There is a small bug in the code. Although you can move the slider to either extremity of the rule, if you use the “+” and “-” buttons you can only get to the penultimate setting that is 9 or 22 points before it no longer moves and gives you the “Isn’t 8/23 points big/small enough for you?”
So perhaps you need to check your Math?
( )Nate September 4th
Very cool. Thanks for sharing.
( )Jason September 4th
Great article! I love seeing more of jQuery stuff, as Im just beginning to use it myself (albeit a bit late to the party I admit!). Also, I do believe James is correct in that it appears to be a bug - since you use the +/- and it maxes at 22 and mins at 9 (but the message says you are at 8 or 23). Very minor sure, but worth noting
( )Matt Fairbrass September 4th
Beautiful, brilliant tutorial with rewarding results. It’s nice to see accessibility can be addressed with jQuery, whilst maintaining a high level of design on the UI front. Shall be using in the future for my own development purposes.
( )Seab September 4th
not work in IE6?
( )Richard, Peacock Carter September 4th
Nice tutorial!
By the way, in Opera 9.27 (Win XP), clicking the ‘+’ when the value is at ‘22′ doesn’t increase the value to 23, but does display the ‘
( )Current Font Size: Isn’t 23 big enough?’ message.
CSS:Jockey September 4th
WOW!! this one is really cool.
( )This will embed well the background selection on my site. I am sure I am gonna use it..
L2 September 4th
Doesn’t work in IE7.
Well I guess some people check before they submit there tutorial and some don’t.
( )L2 September 4th
Delete above, now it works but with the ‘+’ symbol I only get to 22 to, and it messages “Current Font Size: Isn’t 23 big enough?”
( )Shane September 4th
@Kurt - as I read that first comment, I wanted to be the first to comment on how futile that first comment was
I like the tutorial quite a bit. It’s refreshing to see jQuery being used for something other than a slidey panel or fade-in/-out div.
Nice work.
( )Jake Holman September 4th
Painfully explained to the detail tutorial, just how it should be
Thanks!
( )insic September 4th
WOW very nice tutorial. thanks you
( )insic September 4th
Just a follow up. Where is the part two of the php5 framework series.
( )Drew Douglass September 4th
You guys have done it again, thanks for the stunning tutorial.
Best Regards,
Drew Douglaaa
( )Connor September 4th
Glad you guys like it…
( )mark September 4th
I dont know much about jQuery so I have a question. It seems that start/stop/slide functions are events that are fired when the slider changes state. If that is the case, why do you run the selector everytime the event is fired.
$(’#slider_caption’)
Wouldn’t it be more efficient to make a reference to the element outside of the event and then use the reference?
( )Make Design, Not War September 4th
Oh, that’s hot. Beautiful application of this technique - definitely something I’ll be checking back on in the future. I love it when accessibility solutions are as brilliant as this. Thanks for the well written tutorial on it.
( )Sean Nelson September 4th
So useful. I’ll have to give this a try.
( )Chris Papadopoulos September 4th
Very cool trick. Bookmarked. I’m surprised at how fluid the transition between sizes appears.
But honestly, I hope I almost never see this in the wild. Websites should be designed with legible text size from the beginning. Creating additional sliders and buttons to change the text size is a time-consuming fix to a fundamental flaw.
Where this might be really appropriate is in specialized web applications. Say you print custom t-shirts and you want to have a quick tool to allow a user to pick how big his t-shirt text is. In this type of context a slider would be a really nifty solution.
But I really dislike this type of approach for major content areas on a blog or news site.
( )Rijalul Fikri September 4th
Very useful article. Surely will try this sometime. I personally like small text, but not my reader
( )Shane September 4th
@Chris - legible text size is difficult to define. What is legible to me may not be legible to people who have sight issues.
We shouldn’t be using pixels to specify our font sizes, so that the text is resizeable using default browser text resize functionality. Having said that, lots of government sites do feature text resize buttons (perhaps three links with different sized ‘A’ characters on them) to help users. Therefore, this is an extension of that. Perhaps so many different sizes is over-the-top in the real world, but this is a demo. Nobody’s going to put a great big slider at the top of the page either, are they?
As an aside, when I visit CSS-driven sites, I often change the text size as a matter of course, just to see how the design copes. You’d be surprised how many that break with overlapping and disappearing text because the designer assumed the text size would never change
( )Guillaume September 5th
Very useful tip! I really appreciate the way you create tutorials, so well detailed!
( )cheese September 5th
Demo doesn’t do anything for me (IE6)
( )Lamin Barrow September 5th
Very nice.. the only downside IMO of-course is that is that it you have to use the jquery UI for this becasue it kid of heavy (201 Kb Minified)
( )Connor September 5th
Er…Lamin, compressed it is 9.20 kb. Do you mean the entire library uncompressed?
( )Braden Keith September 5th
Man that turned out nice
( )Christopher Webb September 22nd
James brings up a great point. The way the current code stands, you’ll never really get 8 or 23 because the code dictates less than or greater than. If you really wanted the messages to match the values, correct the code to read:
if (newFontSize >=
{
( )if (newFontSize http://www.twitter.com/conspirator
Christopher Webb September 22nd
For what it’s worth, the demo doesn’t work for some reason because it points to the latest version of jQuery. When I downloaded the demo and pointed it to my local version of jQuery (1.2.6), it worked like a charm. Great tutorial!
( )Buck Wilson October 4th
You could have at least given me credit for the jQuery code & art if you’re going to rip off my tutorial.
http://www.keepthewebweird.com/creating-a-nice-slider-with-jquery-ui/
the JavaScript is nearly a line for line. You didn’t even change the variable names.
( )Connor October 5th
Hi Buck,
Sorry for any misunderstanding. I thought I had emailed you. And I did link to it up above. If you look in step 4, you can see that I said:
( )Well I was lucky to find this amazing screencast (with a link). 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:
GM October 27th
This code works great in FireFox, but it does work at all in IE7
( )aa November 19th
This code works great in FireFox, but it does work at all in IE7
( )Omair Rais January 15th
The slider is very handy for me.
Thanks
( )Omair Rais
http://www.omairarts.com
Radoslav Stankob January 16th
For slider like this I make different css styles - text-size-1, text-size-2, … and only change them one element.
( )tomgary January 19th
What pretty slider !
( )Thak you !
soking January 19th
Nice!
( )Netflash January 21st
It’s a great effect but you should have checked in IE7. It’s not working correctly. Dragging the slider does nothing. Only works if you use the + and - buttons.
( )Greg Johnson January 30th
The same is true for FireFox 3 Netflash.
( )MrH2o February 24th
Like the others already told you, doesn’t work on FF 3
( )Any upcoming fix?
Braunson March 15th
Found a bug in chrome. When clicking the minus and plus it works, but then moving the bar itself, it dosn’t work.
( )Surfmaster May 15th
Same problem while testing under Firefox 3.0.10
( )Harley Alexander April 4th
That’s not just chrome..
( )MarcusT April 13th
Unfortunately there’s a couple of serious problems with this demo/implementation… if you click and drag the slider nothing happens (FF3)… if you click “+” repeatedly the animations queue up and the balloon flashes for quite some time after it’s reached the end…
( )Roy Green April 22nd
Under my testing, clicking and dragging the slider does not work under:
Chrome 1.0.154.53
( )Firefox 3.0.8
IE8 (or IE8 compatibility mode) 8.0.6001.18762
Safari 3.2.2
st3ph May 7th
So bugged …
( )jam June 25th
dude, let me praise you for such good implementation, but it sliding the slider does not work in opera 10, ff 3.5 and ie8 8.0.7100.0, i tested in all, but the plus and minus works, the implementation is great, does not look like problem in your code, the slider function is not called in these browsers maybe, looks at it if get time
( )billowschen July 2nd
thank you! i just want to find it
( )