jQuery Tooltips - a walkthrough...
8/08/2011
Introduction
Following on in the same theme here, another thing that a lot of people seem to want to be able to do is tooltips. Basically programmable alt tags if you ask me, except a lot of browsers don't show alt tags by default so a cool alternative if you need to use them. So here we go, this time in plugin format too, jQuery tooltips.
The basic markup
Again, we'll need to start here with a basic bit of markup and CSS to get us going, so firstly let's stick a few elements in the page.
<a href="#" title="I'm a tooltip!">This hyperlink will be tooltipped...</a>
<a href="#" title="It is now!">...is tooltipped a word?</a>
Sweet. As for the CSS, bare with me on the below, I'll explain some of it in due course. We're going to actually cheat a little bit here, by all means if you want to create transparent background images etc. go for it, but I utilise the ':before: and ':after' CSS selectors here to give us something pretty cool instead.
a {display:inline-block; position:relative;}
.tooltip {position:absolute; display:none; background:#666; padding:5px 10px; color:#fff; border-radius:15px; font-size:0.8em; box-shadow: 0px 0px 10px #5c5c5c;}
.tooltip:after {content:""; display:block; position:absolute; bottom:-5px; left:20px; width:0; border-width:5px 5px 0; border-style:solid; border-color:#666 transparent; opacity:0.9;}
.tooltip-bottom:before {content:""; display:block; position:absolute; top:-5px; left:20px; width:0; border-width:0 5px 5px; border-style:solid; border-color:#666 transparent; opacity:0.9;}
.tooltip-bottom:after {content:""; display:none;}
Also - feel free to change any of the styling here, it's just something to get you going. Before moving on let me explain the selectors used above briefly just in case they look completely alien. These can be used to insert/style content before or after the element that you specify the selector on, and by using certain styles you can create the old school CSS shaped everyone loves. The above will create a little arrow positioned at the top/bottom of the tooltip element, and it's a pretty neat trick I use quite a lot.
So we've got some markup in place, some CSS there already, let's get on.
jQuery me up bro!
Awesome. Let's start by just putting the plugin together with the basic structure it needs, and also by declaring what we're working with and also the tooltip itself.
(function ($) {
$.fn.tooltips = function (options) {
var tooltipsSettings = {
}
if (options) {
$.extend(tooltipsSettings, options);
}
var tooltipSelector = this;
var tooltip = $('<div class="tooltip"></div>').insertAfter(tooltipSelector);
}
})(jQuery);
Simples. So above, we have out plugin code with no defaults, wrapped around a tooltip selector which will be the trigger for the tooltip, and also we're creating the tooltip itself to insert into the DOM.
Whatever elements we call the tooltip plugin on will become "this" and essentially they and their attributes will be what drives the tooltip itself. Cool, let's add some variables for everything we're using here.
(function ($) {
$.fn.tooltips = function (options) {
var tooltipsSettings = {
}
if (options) {
$.extend(tooltipsSettings, options);
}
var tooltipSelector = this;
var tooltip = $('<div class="tooltip"></div>').insertAfter(tooltipSelector);
tooltipSelector.each(function () {
var offsetLeft = $(this).position().left;
var offsetTop = $(this).position().top;
var currentTooltip = $(this).next();
var currentSelector = $(this);
});
}
})(jQuery);
So above we've started a jQuery each function for each of the matched elements that come back. Usually I would personally use a normal javascript for loop as it is MUCH more performant, but this gives ease of reading/learning ability.
Within that loop we've declared a set of variables which are going to be reset for each element on the page that requires a tooltip. We've got offsetLeft which calculates the current position of the tooltip trigger on the page, we'll need to know this along with offsetTop to be able to accurately position the tooltip to be close to it's trigger. We're also setting currentTooltip and currentSelector to variables again for performance reasons and to make it easier to work out where we are within the function. all of the above will come into play help us create the tooltips in an easy way. So we've got the plugin setup, our tooltips being created and any variables we're going to need - let's get into the code that makes it work..!
(function ($) {
$.fn.tooltips = function (options) {
var tooltipsSettings = {
}
if (options) {
$.extend(tooltipsSettings, options);
}
var tooltipSelector = this;
var tooltip = $('<div class="tooltip"></div>').insertAfter(tooltipSelector);
tooltipSelector.each(function () {
var offsetLeft = $(this).position().left;
var offsetTop = $(this).position().top;
var currentTooltip = $(this).next();
var currentSelector = $(this);
offsetTop = offsetTop - 28;
if (offsetTop < 0){
offsetTop = -offsetTop
currentTooltip.addClass('tooltip-bottom');
}
currentTooltip.css({'left': offsetLeft + 'px','top': offsetTop + 'px'}).html(currentSelector.attr('title'));
currentSelector.hover(function () {
currentTooltip.addClass('visible').css({
'opacity':'0.9'
}).stop().fadeIn();
},
function () {
currentTooltip.removeClass('visible').stop().fadeOut();
});
});
}
})(jQuery);
Ok, we made quite a jump there so let me slow it down and explain a couple of things about the above code. Firstly you'll notice we are setting the offsetTop variable to be itself minus 28. This is to ensure that the tooltip appears above our trigger rather than right on top of it, if you are working with different CSS line-heights or font-sizes, you may need to adjust this accordingly but for the most part it should be good. Secondly we've got an interesting if statement that may look slightly out of place? Let me explain. We have to cater for the circumstance that there may be an element at the very top of the screen that you want to stick a tooltip on. If the element is at the very top, the tooltip has a negative top position so it will actually display off of the screen. All we're doing here is saying, if the tooltip has a negative top position, reset the position to be a positive number (this is done by re-declaring the variable to itself but with an extra '-' sign at the start as you can see). By making it the same value but positive, it will move the tooltip to the correct amount below its trigger instead. Also you'll notice at the same point we add the 'tooltip-bottom' class, if you reference against the CSS again, you'll see this hides the previous arrow and actually creates an arrow before the element this time, and always switches it to point in the correct direction. Quick, simple way of avoiding this problem.
The next part of the code is hopefully quite self explanatory! We're setting the top and left positions on the tooltip itself and then positioning it based on those from the trigger element, so it will appear nicely just to the top (or bottom). Also in this line if you missed it is probably the most important part of the plugin, where we get the text for the tooltip from. The act of jQuery chaining has made me miss certain things before myself, but you'll see .html(currentSelector.attr('title')); at the end - we're grabbing the title element of the trigger and setting the tooltip text to be this. This makes it way easy for you guys to literally just add an attribute to your elements and then call the plugin.
After this - uber simple hover function to show and hide the tooltip based on hover of the triggers..!
Is that it..?
Yeh, that's it! It's mega easy to create something like this using jQuery and especially how quick it is to throw together a plugin to handle it for you too. Once you have this, all you need to do is this:
$(document).ready(function(){
$('a').tooltips();
});
And then the plugin will be called on any anchor elements on the page!
...no I meant is that it, no options or anything?
Dude, come on, I just painstakingly went through the process of creating something like this and took you through every step, I'm sure if you want to stick some defaults in there like click or hover to be the trigger, or what attribute to use on the element, you can manage it ;)





Lavinia
2011-10-17A bit surprised it seems to smpile and yet useful.