Build a Better Tooltip with jQuery Awesomeness

Browsers will automatically display a tooltip when you provide a title attribute. Internet Explorer will also use the alt attribute. But, in this tutorial I’m going to show you how to quickly write a jQuery plugin that will replace the typical browser tooltip with something a little flashier.

One of the great tools we have in our web development goodie-bag are tooltips. A tooltip is a box that appears when you hover your cursor over an element like a hyperlink. It provides supplementary information about that element. For example, a link with little or no text (an icon) may become confusing. Provide an extra sentence or two within a tooltip to explain to your users what will happen if they click on it.

Before You Start

This tutorial would probably fit in the category of Intermediate. The instructions assume that you have at least a basic understanding of HTML/CSS, slicing techniques and jQuery.

If you need a refresher on jQuery, here are a few recommended sites:

Just so you have a clear idea of the files involved in this tutorial, here is what the file structure should look like by the time you are done.

The file structure

Here’s a rundown of what each file/folder is:

  • Images folder contains the following images:
  • – – tipTip.png – created in Step 2
  • – – tipMid.png – created in Step 2
  • – – tipBtm.png – created in Step 2
  • index.html – – created in Step 3
  • style.css – created in Step 3
  • jquery-1.3.1.min.js – download this here
  • jquery.betterTooltip.js – – created in Step 5

First, Get a Little Creative

Open up Photoshop, or your software of choice, and whip up an awesome looking tooltip. Rather than designing on a plain white background, it may help to draw up your tooltip on a background similar to that of your site. That way it will blend in seamlessly. For the most part, there is no right or wrong way to complete this step. Just use your imagination and creativity.

Initial Tooltip Design

Step 2 – Slice and Dice Your Tooltip

For this particular design, you will need to slice the tooltip into 3 different images. This particular design will need a PNG to preserve transparency. 1) The top piece. 2) A thin 1 pixel slice that will repeat vertically in the middle. 3) The bottom piece. The 4th part of the diagram below shows the three pieces after they were cut out.

Place these image files into a folder named “images”.

Slice up the tooltip

Note: Internet Explorer does NOT like PNG transparency. Even IE 7 only partially supports it. If you animate a PNG with JavaScript, any area with transparency will turn black momentarily while in movement. I’m using this design knowing full well it will have issues in IE that are hard to work around.

Step 3 – Write the HTML/CSS Markup

With the images sliced, we can move on to the HTML and CSS markup. This will be the easiest part of the whole tutorial.

The HTML

This HTML markup will soon be moved into an external JavaScript file, so just type this in whatever is most convenient and can be referred to later.

  1. <div class=“tip”>
  2. <div class=“tipMid”></div>
  3. <div class=“tipBtm”></div>
  4. </div>

There are three div tags. Two nested inside a parent. The first div, “tip” will be used to hold everything together and display the top portion of the tooltip, tipTop.png.

“tipMid” will eventually hold the text that the tooltip will display. It will also have tipMid.png repeating vertically inside it.

“tipBtm” is solely there to display the bottom portion of the tooltip, tipBtm.png.

Inside of index.html, add a bunch of filler text and some elements with their title attributes filled out. Such as:

  1. <a href=“#” title=“This is the tooltip text”>This is a link</a>

In the head of index.html, you will need to link to the stylesheet and the two JavaScript files.

  1. <link href=“style.css” rel=“stylesheet” type=“text/css” media=“all” />
  2. <script type=“text/javascript” src=“jquery-1.3.1.min.js”></script>
  3. <script type=“text/javascript” src=“jquery.betterTooltip.js”></script>

The CSS

The CSS used for this tooltip is relatively simple, just add the following to style.css

  1. .tip {
  2. width: 212px;
  3. padding-top: 37px;
  4. display: none;
  5. position: absolute;
  6. background: transparent url(images/tipTop.png) no-repeat top;}
  7. .tipMid {background: transparent url(images/tipMid.png) repeat-y; padding: 0 25px 20px 25px;}
  8. .tipBtm {background: transparent url(images/tipBtm.png) no-repeat bottombottom; height: 32px;}

Let me explain the above.

The wrapping element, .tip, is used to hold everything together. It has a top padding of 37 pixels. That’s the height of the image in the background. The padding will push the child elements down to reveal the image behind. It also has a position absolute so that we can move it around on top of the page content.

The other two classes simply have a background image and, in the case of .topMid, padding to give the content that will be placed inside, some room to breathe.

Step 4 – Why a Plugin?

jQuery is pretty cool by itself. But the real magic is in extending it with a plugin. When you put your code into a plugin, you are making it reusable. That way you can build up a code library and never write the same code twice.

Here is the tooltip plugin in its entirety:

  1. $.fn.betterTooltip = function(options){
  2. /* Setup the options for the tooltip that can be
  3. accessed from outside the plugin              */
  4. var defaults = {
  5. speed: 200,
  6. delay: 300
  7. };
  8. var options = $.extend(defaults, options);
  9. /* Create a function that builds the tooltip
  10. markup. Then, prepend the tooltip to the body */
  11. getTip = function() {
  12. var tTip =
  13. “<div class=’tip’>” +
  14. “<div class=’tipMid’>” +
  15. “</div>” +
  16. “<div class=’tipBtm’></div>” +
  17. “</div>”;
  18. return tTip;
  19. }
  20. $(“body”).prepend(getTip());
  21. /* Give each item with the class associated with
  22. the plugin the ability to call the tooltip    */
  23. $(this).each(function(){
  24. var $this = $(this);
  25. var tip = $(‘.tip’);
  26. var tipInner = $(‘.tip .tipMid’);
  27. var tTitle = (this.title);
  28. this.title = “”;
  29. var offset = $(this).offset();
  30. var tLeft = offset.left;
  31. var tTop = offset.top;
  32. var tWidth = $this.width();
  33. var tHeight = $this.height();
  34. /* Mouse over and out functions*/
  35. $this.hover(function() {
  36. tipInner.html(tTitle);
  37. setTip(tTop, tLeft);
  38. setTimer();
  39. },
  40. function() {
  41. stopTimer();
  42. tip.hide();
  43. }
  44. );
  45. /* Delay the fade-in animation of the tooltip */
  46. setTimer = function() {
  47. $this.showTipTimer = setInterval(“showTip()”, defaults.delay);
  48. }
  49. stopTimer = function() {
  50. clearInterval($this.showTipTimer);
  51. }
  52. /* Position the tooltip relative to the class
  53. associated with the tooltip                */
  54. setTip = function(top, left){
  55. var topOffset = tip.height();
  56. var xTip = (left-30)+“px”;
  57. var yTip = (top-topOffset-60)+“px”;
  58. tip.css({‘top’ : yTip, ‘left’ : xTip});
  59. }
  60. /* This function stops the timer and creates the
  61. fade-in animation                          */
  62. showTip = function(){
  63. stopTimer();
  64. tip.animate({“top”: “+=20px”, “opacity”: “toggle”}, defaults.speed);
  65. }
  66. });
  67. };

Step 5 – Write the Plugin

Now that you’ve seen what the code looks like, it’s time to dissect it. To get started, create a .js file and name it jquery.betterTooltip.js to make it compliant with jQuery plugin standards.

Inside that .js file, include the following code:

  1. $.fn.betterTooltip = function(){
  2. });

This creates a public function that can be invoked from the head of a document or another external .js file. To invoke your plugin, you need to call the follow line from within a $(document).ready page event.

  1. $(document).ready(function(){
  2. $(‘.tTip’).betterTooltip();
  3. });

The above line will attach the plugin to every element with the class name of “tTip”. Likewise, you could attach it to any element of your choosing.

Expose the Plugin Settings

In order to prevent having to modify the plugin for every project it’s important to expose some of the variables and settings so they can be tweaked from outside the plugin itself. The ultimate goal would be to never touch the plugin, just adjust its settings. To do this, add the following to that first chunk of code:

  1. $.fn.betterTooltip = function(options){
  2. /* Setup the options for the tooltip that can be
  3. accessed from outside                      */
  4. var defaults = {
  5. speed: 200,
  6. delay: 300
  7. };
  8. var options = $.extend(defaults, options);
  9. });

This allows the settings “speed” and “delay” to be modified when the plugin is invoked like this:

  1. $(‘.tTip’).betterTooltip({speed: 600, delay: 600});

These are completely optional. If not specified, the plugin will use the default values.

Inject the Tooltip Markup

Remember that HTML you typed up for the tooltip? It will now make its official appearance. In this chunck of code, the jQuery “prepend” content manipulation is used to inject the tooltip immediately after the opening body tag. This way we can make sure that the tooltip is positioned on top of everything.

  1. /* Create a function that builds the tooltip
  2. markup. Then, prepend the tooltip to the body */
  3. getTip = function() {
  4. var tTip =
  5. “<div class=’tip’>” +
  6. “<div class=’tipMid’>” +
  7. “</div>” +
  8. “<div class=’tipBtm’></div>” +
  9. “</div>”;
  10. return tTip;
  11. }
  12. $(“body”).prepend(getTip());

The $(this).each function

This is one of the most important and useful aspects of a jQuery plugin. The $(this).each function loops through each page element that is associated with the plugin when it was evoked. In this case it’s all elements with the “tTip” class. When it loops through each element it applies the properties and methods that you specify.

  1. $(this).each(function(){
  2. var $this = $(this);
  3. var tip = $(‘.tip’);
  4. var tipInner = $(‘.tip .tipMid’);
  5. var tTitle = (this.title);
  6. this.title = “”;
  7. var offset = $(this).offset();
  8. var tLeft = offset.left;
  9. var tTop = offset.top;
  10. var tWidth = $this.width();
  11. var tHeight = $this.height();
  12. /* Mouse over and out functions*/
  13. $this.hover(function() {
  14. tipInner.html(tTitle);
  15. setTip(tTop, tLeft);
  16. setTimer();
  17. },
  18. function() {
  19. stopTimer();
  20. tip.hide();
  21. }
  22. );

This is fairly simple. The top half consists of a bunch of properties for the height, width, x & y position and even the title attribute value of the “tTip” elements. I’m using the jQuery offset() CSS method to grab the top and left position. There is also a hover function assigned to each “tTip” class that calls methods on mouse over and out. These methods will be described further down in the tutorial.

One important part of the $(this).each function is this line of code here that removes the title attribute:

  1. this.title = “”;

The whole point of this tooltip is to swap the generic tooltip with a better eye catching version. If you don’t remove the title attribute, which the browser uses to generate the generic tooltip, you will get duel tooltips. Like this:

Avoid duel tooltips

Delay the Fade-in Animation of the Tooltip

  1. /* Delay the fade-in animation of the tooltip */
  2. setTimer = function() {
  3. $this.showTipTimer = setInterval(“showTip()”, defaults.delay);
  4. }
  5. stopTimer = function() {
  6. clearInterval($this.showTipTimer);
  7. }

These two methods, setTimer and stopTimer are used to create a delay from when the user hovers their cursor over the element with the “tTip” class and when the tooltip makes its appearance. This is important to avoid annoying users. I’m sure we all share the frustration when we accidentally hover over one of those pop-up ads that are hidden in the content of sites.

The setTimer method creates a setInterval object that calls “showTip()” after the allotted time has passed. In order for setInterval to not loop infinitely, the method stopTimer is called to stop the setInterval object.

Position the Tooltip

  1. /* Position the tooltip relative to the class
  2. associated with the tooltip                */
  3. setTip = function(top, left){
  4. var topOffset = tip.height();
  5. var xTip = (left-30)+“px”;
  6. var yTip = (top-topOffset-60)+“px”;
  7. tip.css({‘top’ : yTip, ‘left’ : xTip});
  8. }

The hover function inside the $(this).each loop, that was created earlier, calls setTip(). Its purpose is to position the tooltip directly above “tTip” element. This is done prior to the fade-in animation.

Tooltip Fade-in Animation

  1. /* This function stops the timer and creates the
  2. fade-in animation                          */
  3. showTip = function(){
  4. stopTimer();
  5. tip.animate({“top”: “+=20px”, “opacity”: “toggle”}, defaults.speed);
  6. }
  7. });
  8. ;

Last but not least, the showTip() function. This uses jQuery’s animate() UI effect to fade the tooltip in while simultaneously sliding it down.

Wrapping it Up. . .

Once you are done and happy with your results, you can move your plugin from the basic HTML page full of filler text to the real world and put it to use.

This is a very basic example of what a tooltip plugin can do. The fun part now will be to make it more robust. There are all sorts of ways to expand this plugin. A needed enhancement would be detecting the location of the tooltip in relation to the boundaries of the browser window and displaying the tooltip accordingly so it doesn’t get cut off.

Thanks for reading this tutorial. I hope it shed some light on how you can use jQuery to enhance your website’s interface.

Let the comments begin! I want to hear what you think. Does this technique actually help users get around easier, or is it just another annoyance?

Source Nettuts

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: