Update (1): The CSS source had wrong formatted comments and the markup was using class instead of id, please update your sample code when you grabbed it earlier!

Update (2): Please find a working demo here: Hints demo

When building nifty UI solutions, always keep in mind that in order to make your target audience use your cool features, you must teach them. The iPhone is to a certain extend only intuitive because they have the marketing power to teach people on TV how to do pinches and swipes. Anyway, since most budgets are smaller, let’s try to achieve the same with contextual hints.

Contextual hints are basically help bubbles that pop up as soon as you are in a certain context. They can also serve as an application walkthrough or tutorial. If you build a todo list, the first hint you would show your users would be sticking on top of the “Create new todo” button, and would tell you something like “Why don’t you click here and create your first task?”.

I’m sure you got the idea, let’s build a very simple solution without any graphics (The downside: Will not look too good in IE..). First, we need to create the markup for the hint:

<div id="bubble">
	<span class="content"></span>
	<div class="pointer"></div>
</div>

Sweet. We just have the outer bubble element which has the id #bubble, a content div that will hold our text and a pointer div which we’ll transform to a nice triangle. Next, let’s do the CSS:

#bubble {
	background: rgba(255,255,255,0.9); /* use rgba to let the bubble shine through a bit */
	font-size: 1.2em;
	padding: 1em;
	width: 22em; /* the bubble needs a certain width since it's absolutely positioned */
	-moz-border-radius: 1em; /* give the bubble nice rounded corners */
	-webkit-border-radius: 1em; /* ...in both gecko and webkit */
	position: absolute;
	z-index: 100; /* give it a high value here to lie on top of all other stuff */
	opacity: 0; /* opacity must be set to zero at beginning (use filter: alpha(opacity=0) for IE) */
}

#bubble .pointer {
	position: absolute;
	bottom: -1em;
	left: 2em;
	width: 0;
	height: 0;
	border-style: solid;
	border-color: rgba(255,255,255,0.9) transparent transparent transparent; /* make sure only one border side is shown */
	border-width: 1em 2em 0em 1em; /* this is called a border slant and creates the shape of the triangle */
}
  

Obviously feel free to customize everything related to styling, font size etc. Next, we want it to see come all together by doing the JavaScript/jQuery work:

$.fn.hint = function(msg) {
	
	var offset = this.offset(), // generate the offset position of the hinted element
		bubble = $('#bubble'), // cache the bubble as jQuery
		pointer = $('.pointer', bubble), // cache the pointer of the bubble
		fadeDistance = 50; // the distance from where the bubble will fade in
	
	// append the message to the bubble, position it and slowly fade it in
	bubble
		.find('span.content').html(msg).end() // insert the new message
		.css({
			top: offset.top - bubble.outerHeight() - pointer.outerHeight() + this.outerHeight()/4 - fadeDistance, // the element offset minus the height of the bubble, minus the height of the pointer, plus one quarter of the height of the element to be on top of it, minus the fading distance
			left: offset.left + this.outerWidth()*0.75 - 42 // the element offset + 3/4 of the element's width to position the bubble at the right side, minus the pixel width to the edge of the triangle
		})
		.animate({
			opacity: 1, // fades it in
			top: '+='+fadeDistance+'px' // moves it in from the fade distance that we substracted above
		}, 600);
	
	// make sure the bubble goes away when clicking on the hinted element	
	return this.one('click', function() {
		bubble.animate({
			opacity: 0, // fades out
			top: '-='+fadeDistance+'px' // animate back the fade distance
		}, 300);
	});
	
};

That’s it. Now all you need to know is it’s usage, but you probably know it already:

$('#myButton').hint("Click here to make it explode.");

This will blend it your hint, and as soon as you click on the element, it will fade away again. Sweet, huh?

7 Comments

Paul Irish  on October 5th, 2009

Can a brother get a demo? :D

Jörn Zaefferer  on October 5th, 2009

Seconded! Your examples are missing a few details: http://jsbin.com/okima3/edit

Paul  on October 5th, 2009

Yep, you can! Check out the article once again, posted an update above :)

Ryno Burger  on October 5th, 2009

Thanks. Could come in handy. So simple but yet so useful.

ravi  on November 11th, 2009

Paul, this is great, thank you. any suggestions on how to make the bubble disappear after some interval. I could use a simple JavaScript setTimeout(), which hides the bubble (opacity = 0 as per above) if its not already hidden, but I was wondering if you had a more sophisticated/integrated/elegant way to do it!

ravi  on November 12th, 2009

Apologies for the multiple comments, but I realise that the above will only work for one bubble. I am rewriting the above using clone() to create bubble per call of hint(). If I get it working and if you are interested, I can post it here (and perhaps someone better versed in jQuery can review it).

Paul  on November 24th, 2009

Hi ravi, it’s indeed a very simple script. If you need a more advanced version, I would suggest you try out plugins like cluetip or Jörn’s tooltip plugin for jQuery, both of which are very configurable and should work in most situations. I only posted my solution because of it’s very low footprint.

Have a comment or question?