Create simple tooltips with CSS and jQuery – Part 2

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

Tags: , , ,
59 replies
« Older Comments
  1. Garett
    Garett says:

    Where are the css files for this tutorial? Do you have a downloadable demo with all of the files in a package? That would be very helpful for us not so advanced coders.

  2. Pavel
    Pavel says:

    Great job! Thank you!

    PS. I think that hard-coded width of a tooltip is not very good. But as we know, IE6 doesn’t understand max-width css property. This can easily be solved with javascript. Just add this line to the simple_tooltip() function:

    if(my_tooltip.width() > 450) my_tooltip.css{width:”450px”});

  3. Pavel
    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

  4. Sander
    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.

  5. daniel
    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!

  6. Alper
    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…

  7. oompa_l
    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

    • Nitrok
      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″);
      });

  8. Zé
    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

  9. Ali
    Ali says:

    Just exactly what I was looking for… but I noticed that it does not quite well work if your link has an image bounded with ALT tag, in that case the ALT tag is also displayed on IE. Any work around that?

Trackbacks & Pingbacks

  1. […] Kolejny pomysł na prosty tooltip (dymek z podpowiedzią) […]

  2. […] Tutorial Tutorial Page […]

« Older Comments

Comments are closed.