Create simple tooltips with CSS and jQuery

Your Ad Here

CSS tooltips are very popular in modern web design and contrary to popular belief it is really easy to create them, especially with one of the all so popular javascript frameworks.

Before I started to delve deeper into this topic, I thought you have to use at least a plugin, but to get some basic tooltips all you need are about 10 lines of CSS and jQuery Code.

This Tutorial will teach you how to create such tooltips with some basic CSS and jQuery.

Creating jQuery Tooltips: the CSS

First of all take a look of what we are going to create (hover over the link block and don’t care about the background, it’s only for better demonstration of the tooltip transparency)

First of all lets take a look at the structure of this tool tip: A typical link will look something like this:
<a href="#" title="This is a small Tooltip with the Classname 'Tooltip'">Link</a>

We will later use javascript to extract the title and put it into a [p] and a [div] container:
<div class="tooltip">
    <p>This is a small Tooltip with the Classname 'Tooltip'</p>
</div>

The CSS for our soon to be terrific tooltips looks something like this:
.tooltip{
    position:absolute;
    z-index:999;
    left:-9999px;
    background-color:#dedede;
    padding:5px;
    border:1px solid #fff;
    width:250px;
}

.tooltip p{
    margin:0;
    padding:0;
    color:#fff;
    background-color:#222;
    padding:2px 7px;
}

The Position has to be absolute since as soon as our Javascript is enabled it will set the top and left property of the div to display it next to our mouse cursor.
For now we set the left property to -9999px to move the tooltip out of the view port. The rest of the CSS is only for styling purpose.
Creating jQuery Tooltips: the jQuery Code, short and simple
Lets take a look at the whole script, I will give a step by step explanation afterwards:
function simple_tooltip(target_items, name){
 $(target_items).each(function(i){
		$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
		var my_tooltip = $("#"+name+i);

		$(this).removeAttr("title").mouseover(function(){
				my_tooltip.css({opacity:0.8, display:"none"}).fadeIn(400);
		}).mousemove(function(kmouse){
				my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
		}).mouseout(function(){
				my_tooltip.fadeOut(400);
		});
	});
}
$(document).ready(function(){
	 simple_tooltip("a","tooltip");
});

This may look intimidating, especially if you are new to jQuery but its really simple. First of all we create the function:
function simple_tooltip(target_items, name){
}

The target item is a variable we will define when calling the script.For example: to append the tooltips to all links in container #maincontent you would enter “#maincontent a”. The name defines the css class we use to style the tooltip. We use variables here for flexibility purpose so you can add diverent tooltips with different stylings.
function simple_tooltip(target_items, name){
  $(target_items).each(function(i){
     // generates code for each tooltip
  });
}

This each loop will generate the code for every item that is found by our script. The variable i which we are passing in the function will be automatically incremented by jQuery after each iteration. This way we will be able to give the tooltips unique ids.
function simple_tooltip(target_items, name){
$(target_items).each(function(i){
	$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
	});
}


This line creates the html code for each tooltip. They all get the same Classname but different ids. The title is added inside of the div and p container
function simple_tooltip(target_items, name){
$(target_items).each(function(i){
	$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");

         var my_tooltip = $("#"+name+i);

        });
}


This line selects the tooltip via jQuery and saves it to a variable for later use
function simple_tooltip(target_items, name){
 $(target_items).each(function(i){
	$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
         var my_tooltip = $("#"+name+i);

                $(this).removeAttr("title").mouseover(function(){

		}).mousemove(function(kmouse){

		}).mouseout(function(){

		});

        });
}


This is the basic construct of our functions centerpiece. First of all we select the current link with $(this). Then the title attribute is removed since we don’t want to display the “normal” tooltip that every browser displays when hovering over links.
Then we prepare 3 functions:

The mouseover function is called when you first hover over the link
The mousemove function is called when we move the mouse while hovering over the link
The mouseout function is called as soon as the mouse leaves the link

As you can see we pass a parameter in mousemove: this parameter is very important since it stores the position of the mousecursor!
$(this).removeAttr("title").mouseover(function(){
			my_tooltip.css({opacity:0.8, display:"none"}).fadeIn(400);
		}).mousemove(function(kmouse){
			my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
		}).mouseout(function(){
			my_tooltip.fadeOut(400);
		});

Now we define whats happening when the different functions are called:
On mouseover we set some css values for the tooltip: we define the transparency and set the display to none. Then the div slowly fades in because of the fadeIn call.

On mousemove we constantly set the positioning values left and top to align the tooltip next to the cursor. the X and Y coordinates are called via .pageX and .pageY. We also add a little offset of 15 px so the tooltip is not directly below the cursor

On mouseout we simply call fadeOut to hide the tooltip
$(document).ready(function(){
	 simple_tooltip("a","tooltip");
});

Last thing we do is: we call the script as soon as the document is loaded. As mentioned earlier parameter 1 is the selector and parameter 2 is the classname of our tooltip. This way you can create multiple designs for your tooltips.

The code we just created can be modified in various ways. I have used a modified version for images in a lately created showcase wordpress theme for Themeforest.net.

Thats is, have fun creating your own sleek tooltips ;)

Update:

Suggested by my readers here is a version of the script that checks if the link has a tittle:
function simple_tooltip(target_items, name){
$(target_items).each(function(i){
		$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
		var my_tooltip = $("#"+name+i);

		if($(this).attr("title") != ""){ // checks if there is a title

		$(this).removeAttr("title").mouseover(function(){
				my_tooltip.css({opacity:0.8, display:"none"}).fadeIn(400);
		}).mousemove(function(kmouse){
				my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
		}).mouseout(function(){
				my_tooltip.fadeOut(400);
		});

		}
	});
}

$(document).ready(function(){
	 simple_tooltip("a","tooltip");
});


So before we start here is a working example.

Lets have a look at last weeks results:
function simple_tooltip(target_items, name){
 $(target_items).each(function(i){
		$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
		var my_tooltip = $("#"+name+i);

		$(this).removeAttr("title").mouseover(function(){
				my_tooltip.css({opacity:0.8, display:"none"}).fadeIn(400);
		}).mousemove(function(kmouse){
				my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
		}).mouseout(function(){
				my_tooltip.fadeOut(400);
		});
	});
}

$(document).ready(function(){
	 simple_tooltip("a","tooltip");
});

We will leave the $document.ready function untouched and make modifications just to the simple_tooltip function. The first improvement is an if statement which checks if the title attribute is set correctly:
function simple_tooltip(target_items, name){
$(target_items).each(function(i){
		$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
		var my_tooltip = $("#"+name+i);

                if($(this).attr("title") != "" && $(this).attr("title") != "undefined" ){

		$(this).removeAttr("title").mouseover(function(){
				my_tooltip.css({opacity:0.8, display:"none"}).fadeIn(400);
		}).mousemove(function(kmouse){
				my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
		}).mouseout(function(){
				my_tooltip.fadeOut(400);
		});

                }
	});
}


Rather simple, now for the tricky part :)
All upcoming code impovements will take place during the mousemove event so I will only display this part for now:
.mousemove(function(kmouse){
	my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
})


Until now the tooltip was always aligned next to the mouse cursor with an offset of 15px. To check if the tooltip would cross the viewports borders we first need to know where the viewports borders are.
Since we align the tooltip at the top right of our mouse we need to know the top edge and the right edge of the browser. Thanks to jQuery this is mere child’s play:
.mousemove(function(kmouse){

    var border_top = $(window).scrollTop();
    var border_right = $(window).width();

    my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
})

The top of the viewport is 0 if you didnt scroll down; if you did scroll down it is 0 + the amount of pixels you scrolled. This value is returned by scrollTop().

To get the right border we just have to ask for the current windows width.

Since we need a little more flexibility we will create variables for the left and top position of our tooltip, as well as a variable for the offset.
.mousemove(function(kmouse){

    var border_top = $(window).scrollTop();
    var border_right = $(window).width();
    var left_pos;
    var top_pos;
    var offset = 15;

    my_tooltip.css({left:left_pos, top:top_pos});
})

Next thing we do is the math to calculate where to position the tooltips:
if(border_right - (offset *2) >= my_tooltip.width() + kmouse.pageX){
	left_pos = kmouse.pageX+offset;
} else{
	left_pos = border_right-my_tooltip.width()-offset;
}

This if statement basically checks if the width of the tooltip plus the x-position of your mouse is smaller than the vieport. If thats the case the tooltip wouldn’t overlap the vieports border and therefore can be aligned next to the mouse.

If thats not the case the tooltip will stay at a fixed x-position.
if(border_top + (offset *2)>= kmouse.pageY - my_tooltip.height()){
	top_pos = border_top +offset;
} else{
	top_pos = kmouse.pageY-my_tooltip.height()-offset;
}

This if statement is the same for the top border. The combined script looks like this:
function simple_tooltip(target_items, name){
 $(target_items).each(function(i){
		$("body").append("<div class='"+name+"' id='"+name+i+"'><p>"+$(this).attr('title')+"</p></div>");
		var my_tooltip = $("#"+name+i);

		if($(this).attr("title") != "" && $(this).attr("title") != "undefined" ){

		$(this).removeAttr("title").mouseover(function(){
					my_tooltip.css({opacity:0.8, display:"none"}).fadeIn(400);
		}).mousemove(function(kmouse){
				var border_top = $(window).scrollTop();
				var border_right = $(window).width();
				var left_pos;
				var top_pos;
				var offset = 15;
				if(border_right - (offset *2) >= my_tooltip.width() + kmouse.pageX){
					left_pos = kmouse.pageX+offset;
					} else{
					left_pos = border_right-my_tooltip.width()-offset;
					}

				if(border_top + (offset *2)>= kmouse.pageY - my_tooltip.height()){
					top_pos = border_top +offset;
					} else{
					top_pos = kmouse.pageY-my_tooltip.height()-offset;
					}	

				my_tooltip.css({left:left_pos, top:top_pos});
		}).mouseout(function(){
				my_tooltip.css({left:"-9999px"});
		});

		}

	});
}

$(document).ready(function(){
	 simple_tooltip("a","tooltip");
});

Our script grew a little bigger during this tutorial, but is nevertheless, very lightweight with only 43 lines of code and already can do more than some of the jQuery tooltip plugins out there ;)
 

Comments (3)

RSS Collapse / Expand
+
+1
This is a pretty nice tooltip script. One thing I didn’t like about it AT FIRST was that I thought I’d have to provide a title attribute for every link on my page or I’d get an empty tooltip box when hovering over a link.

I discovered I could change the script slightly to include a class attribute on the anchor and that would limit the effect to only the ones that I had supplied the class for. The new class was “_tooltip” to keep it separate from the existing “tooltip” class.

Then I took it a step further and styled different tips adding 2 more classes “_tooltip2? and “_tooltip3?.

The only modifications to the script above come at the very end …

$(document).ready(function(){
simple_tooltip(”a._tooltip”,”tooltip”);
simple_tooltip(”a_tooltip2?,”tooltip2?);
simple_tooltip(”a._tooltip3?,”tooltip3?);
});

and of course I have to modify my css accordingly:
.tooltip, .tooltip2, .tooltip3 {
position:absolute;
z-index:999;
left:-9999px;
background-color: #dedede;
padding:5px;
border:1px solid #fff;
width:150px;
}
.tooltip p, .tooltip2 p, .tooltip3 p {
margin:0;
padding:0;
color:#fff;
padding:2px 7px;
}
.tooltip p {
background-color:#C16C29;
}
.tooltip3 p {
background-color: green;
}
avatar

ChrisAkaDiddy

  • 20 March 2009, 11:16
+
0
Hi,

I would love to use your tool tip, but I cannot figure out how to customize it. I’d like the tool tip to always be centered and above the link.

I’ve messed with the javascript and the positioning but cannot get it correct.

Any thoughts? Thank you in advance!
avatar

hovahh

  • 20 March 2009, 11:17
+
0
Great work on this. I’m looking to use this on list items — which works for the most part — unfortunately it seems to lose track of the mouse position when hovering over input elements inside the list. Any suggestions to fix this?

hovahh: I havn’t tested this but I believe this will solve your problem, in the line:

left_pos = kmouse.pageX+offset;

Changing offset to half of the tooltip’s width should center it on the mouse.
avatar

Tyler

  • 20 March 2009, 11:20

Only Registered and authorized users may post comments