Create simple tooltips with CSS and jQuery – Part 2

CSS Tutorials, Javascript, Tutorials Nov 03, 2008 53 Comments

In a recent tutorial I taught you how to create simple transparent tooltips with a few lines of CSS and jQuery. Today we will build some more advanced tooltips, based on the aforementioned tutorial.

These tooltips will act a little bit smarter than our basic version. The script will skip links with empty or missing title tags, but more important: the tooltips will try to stay in the browser viewport.

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 ;)

53 Responses to “Create simple tooltips with CSS and jQuery – Part 2”

  1. Reply Pavel says:

    Correct line should be:
    if(my_tooltip.width() > 450) my_tooltip.css({width:”450px”})
    I made a small mistake in the previous comment

  2. Reply Pavel says:

    And don’t forget to remove with and max-width properties from .tooltip selector, if you have any.

  3. Reply bookvalue says:

    very nice, thank you

  4. Reply Brad says:

    Great job! Thank you for sharing!!!

  5. Reply Sander says:

    The tooltip isn’t coming up. Can anyone tell me why? I had included:

    jquery version 3.6.2

    tooltip.js

    the .css

    And the link was the same as in the example page.

  6. Reply Sander says:

    Can anyone upload the whole pack that I can download?

    Thanx.

  7. Reply Destiny Lenczyk says:

    [..] A little unrelated, but I quite simply liked this site post [..]

  8. Reply as_you_2007 says:

    Great,much thanks!!

  9. Reply daniel says:

    Hi

    this is something what I’m looking for but with popup relative to the position of the browser border this is good example:

    http://www.istockphoto.com

    the preview pop up stays always within browser anyone have the idea where to find this script

    regards!

  10. Reply Alper says:

    I think you should use this technique to show Post/Page names in aviasliders when user hover the small dots ;)
    Just an idea…

  11. Reply Britteny Cappelletti says:

    Hi, truly a wonderful online site. Thank you for making the effort to publish so many entertaining articles ;D

  12. Reply oompa_l says:

    I am implementing this on my site and I had it all working until I tweaked something in my tooltip.js file

    $(document).ready(function(){
    simple_tooltip(“#imageFrame img”,”tooltip”);
    simple_tooltip(“#GFAID a”,”tooltip”);
    simple_tooltip(“#GFAID span a”,”tooltip”);
    });

    how do you chain multiple functions together? I want to affect different elements on the page with the same tooltip

    • Reply Nitrok says:

      You have to make a new class for every element in css.

      For example I used tooltips in my link titles (class tooltip) and image titles (class tooltip2) and here is css for that:

      .tooltip, .tooltip2 {
      position:absolute;
      z-index:999;
      left:-9999px;
      background-color:#1a1a1a;
      padding:5px;
      width:auto;
      }

      Then in the js file i simply wrote this:

      $(document).ready(function(){
      simple_tooltip(“a”,”tooltip”);
      simple_tooltip(“img”,”tooltip2″);
      });

  13. Reply says:

    This is fantastic but….i can´t put this on blogger.

    Is my fault or it´s because it doesn´t work on blogger at all?

    thank you

Leave a Reply