v0.11
update: smart hover box is no longer being updated or supported. Thanks to everyone for all the feedback on this project.
Update: we have released a new version of smart hover box!
Update: thanks to some feedback, found and fixed an IE bug that threw an error the first time you hovered over an element.
Smart Hover Box is a simple Mootools 1.2 function that spun off of mootime, my mootools 1.2 javascript timepicker. I liked the smart positioning, so decided to take the idea a bit further. With the Smart Hover Box you can add a hover html elements to any other element by adding a single id.
Imagine your web design has a single set of instructions that you want to hover:
- create your hover control and give it the id “instructions”
- then add the id “instructions_smarthbox” to a div containing the instructions.
That is all you have to do. Just add the id “id_suffix” to the element you want to hover, where “id” is the id of the control element. You can even define your own suffix to match your css style.
Demo
Check out a live demo of the Smart Hover Box v0.1 here.
Features
- create a hover box out of any html element
- smart positioning will always show hover box in window quadrant with the most space
- optional close button by adding a user defined class to any element
- user defined x and y hover element offset
- user defined timeout after mouseleave event
Installation
Install mootools 1.2, then copy and paste the code before the </head> tag in your html file, or save it as a .js and pull it in.
- Download mootools 1.2, in my opinion, the best javascript library around.
- Upload the Smart Hover Box code between script tags (<script type=”text/javascript”> </script>), before the end of the head tag in your html (or)
- Save the javascript code below as smarthoverbox.js (or whatever you like) and link to in the head tag (<script src=”/js/smarthoverbox.js” type=”text/javascript”>)
Configuration
Javascript
To add hover boxes to your website, all you have to do is call the Smart Hover Box function, and define the following parameters: delay, x offset, y offset, the smart box suffix, the close button class name.
Here is the Smart Hover Box javascript:
var smartHoverBox = function(boxTimer, xOffset, yOffset, smartBoxSuffix, smartBoxClose) { var smartBoxes = $(document.body).getElements('[id$=' + smartBoxSuffix + ']'); var closeElem = $(document.body).getElements('.' + smartBoxClose); var closeBoxes = function() { smartBoxes.setStyle('display', 'none'); }; closeElem.addEvent('click', function(){ closeBoxes() }).setStyle('cursor', 'pointer'); var closeBoxesTimer = 0; smartBoxes.each(function(item){ var currentBox = item.getProperty('id'); currentBox = currentBox.replace('' + smartBoxSuffix + '', ''); $(currentBox).addEvent('mouseleave', function(){ closeBoxesTimer = closeBoxes.delay(boxTimer); }); item.addEvent('mouseleave', function(){ closeBoxesTimer = closeBoxes.delay(boxTimer); }); $(currentBox).addEvent('mouseenter', function(){ if($defined(closeBoxesTimer)) $clear(closeBoxesTimer); }); item.addEvent('mouseenter', function(){ if($defined(closeBoxesTimer)) $clear(closeBoxesTimer); }); item.setStyle('margin', '0'); $(currentBox).addEvent('mouseenter', function(){ smartBoxes.setStyle('display', 'none'); item.setStyles({ display: 'block', position: 'absolute' }).setStyle('z-index', '1000000'); //coordinates and size vars and math var windowSize = $(window).getSize(); var windowScroll = $(window).getScroll(); var halfWindowY = windowSize.y / 2; var halfWindowX = windowSize.x / 2; var boxSize = item.getSize(); var inputPOS = $(currentBox).getCoordinates(); var inputCOOR = $(currentBox).getPosition(); var inputSize = $(currentBox).getSize(); var inputBottomPOS = inputPOS.top + inputSize.y; var inputBottomPOSAdjust = inputBottomPOS - windowScroll.y var inputLeftPOS = inputPOS.left + xOffset; var inputRightPOS = inputPOS.right; var leftOffset = inputCOOR.x + xOffset; if(halfWindowY < inputBottomPOSAdjust) { item.setStyle('top', inputPOS.top - boxSize.y - yOffset); if (inputLeftPOS < halfWindowX) { item.setStyle('left', leftOffset); } else { item.setStyle('left', (inputPOS.right - boxSize.x) - xOffset); }; } else { item.setStyle('top', inputBottomPOS + yOffset); if (inputLeftPOS < halfWindowX) { item.setStyle('left', leftOffset); } else { item.setStyle('left', (inputPOS.right - boxSize.x) - xOffset); }; }; }).setStyle('cursor', 'pointer'); }); };
To add the function to your web page:
window.addEvent('domready', function() { smartHoverBox( 1000, //delay before vanishing 30, //x offset 0, //y offset '_smarthbox', //smart hover box suffix 'smarthbox_close' //hover box close class ); });
HTML
<span id="instructions">instructions</span> <div id="instructions_smarthbox"> <ul> <li>Step one</li> <li>Step two</li> <li>Step three</li> </ul> </div>
Download
Download Smart Hover Box
*Including the mootools 1.2 core, the ‘Smart Hover Box’ javascript file, and a simple html file.
Notes
You may have to set body {margin:0} for the offset to register correctly in IE (a bug in IE’s position reporting).
If you have any problem with flickering boxes on reload, try setting the boxes to display: none in the css.
Currently, only a single instance of the function is supported, though you may have as many hover boxes with the same parameters as you like.
You can use this however you like, and please drop me a comment letting me know if you use it in your web development project and what you think. I also welcome any suggestions on how to make it easier to use, as well as feature requests.
Thanks and I hope you find it useful.

This work is dedicated to the Public Domain.
Tags: free download, interface design, javascript, mootools, Mootools 1.2, mootools plugins
[...] Smart Hover Box for Mootools 1.2 [...]
Nice…
Have you heard or seen anyway of getting a “thought bubble” effect where an arrow points to what you are hovering over and dynamically moves depending on the direction of the hoverbox?
hmm… I’m not sure if i follow exactly what you mean. Could you point to an example?
[...] Link: http://www.consideropen.com/blog/2008/08/smart-hover-box-for-mootools-12/ [...]
sad it’s not working with smoothscroll (mootools) activated..
Bummer, I never tried it in combination with smoothscroll. Do you have an example set up so I can take a look?
Hey Troy,
I think Yukon may be referring to something like this http://www.dynamicdrive.com/dynamicindex5/dhtmltooltip.htm, which is what I’m looking for as well. I’ll see if I can incorporate this and let you know what I come up with. Thanks for the great bit of code.
I followed that link, it looks like that lets you add html tooltips like these, the only difference I noticed was in the implementation. Hmmm… I am thinking that Yukon was talking more about the pointer on the thought bubble moving around. Not sure though. Tai, I would love to see what you come up with, drop us a note.
I do not believe this
Which part?
thanks for the great script! too bad i can’t get it to run alongside with mocha ui…didn’t find the problem yet, the hoverboxes seem to stick at the bottom of the page, outside the viewport…
If you can provide a link i’ll take a look.
Hey Troy,
Yeah, the implementation on that was pretty antiquated, but I just wanted to point out how the tooltip follows the cursor. Not sure if that was what Yukon was referring to but that’s what I meant. Anyway, I took a crack at it, so try this out. Basically you replace the event:
$(currentBox).addEvent(‘mouseover’, function(){ … }
with the following:
$(currentBox).addEvent(‘mouseover’, function(event){ $(document).addEvent(‘mousemove’, trackMouse) });
$(currentBox).addEvent(‘mouseout’, function(){ $(document).removeEvents(‘mousemove’) });
var trackMouse = function(event){
event = new Event(event);
smartBoxes.setStyle(‘display’, ‘none’);
item.setStyles({ display: ‘block’, position: ‘absolute’ }).setStyle(‘z-index’, ‘1000000′);
// coordinates and size vars and math
var windowSize = $(window).getSize();
var windowScroll = $(window).getScroll();
var boxSize = item.getSize();
// Keep the hover box within the viewport vertically
if (event.client.y + yOffset + boxSize.y + padding > windowSize.y) {
var top = windowSize.y + windowScroll.y – boxSize.y – padding; // abuts bottom
} else if (event.client.y + yOffset windowSize.x) {
var left = windowSize.x + windowScroll.x – boxSize.x – padding; // abuts right
} else if (event.client.x + xOffset < padding) {
var left = windowScroll.x + padding; // abuts left
} else {
var left = event.page.x + xOffset;
}
item.setStyle(‘top’, top);
item.setStyle(‘left’, left);
}
I know that I shouldn’t be creating a new Event, but for some reason I couldn’t get bindWithEvent working right and was lazy. Please refactor if you have the time. Also, I added an argument called padding which determines how close to the edge the hovers can go, so there is a slight change in the function call:
smartHoverBox(
1000, //delay before vanishing
20, //x offset – recommend positive
-20, //y offset
10, //minimum padding between hoverbox and edge of screen
‘_smarthbox’, //smart hover box suffix
’smarthbox_close’ //hover box close class
);
Hey Troy,
I am finding an issue which probably has more to do with MooTools (and my limited experience with it) than your script but maybe you have some ideas. It seems that MooTools cannot add events to elements that don’t exist yet (makes sense, right?). Using domready functions will solve this for static content by ensuring that code won’t fire until after the code is rendered. However, let’s say you have a function that writes some HTML out with Javascript after the page is loaded – say, on some button click – and you want smartHoverBox to register events for those new elements. Any ideas?
Ok, answered my own question. The solution is to only call the smartHoverBox after the code which generates new elements (duh!). Unfortunately there are several points where this happens so it seems unavoidable to make that function call multiple times.
Ah, interesting. I’m sure there is a way around this. Maybe we could turn this into a class and have a “give this object hover functionality” method.
I keep getting a script error in IE7 on “mouseenter”. The error code points to LINE: #13 CHAR: 52 saying “closeBoxesTimer” is undefined. The sample DIV element I inserted onto the page displays ok, but the error only happens when mousing in. No problems in Firefox. Obviously, I’m new to javascript so any advice would be helpful and appreciated. Did I miss a configuration setting somewhere? Here’s the temp page with the test DIV. http://beseenmedia.net/
The test DIV is in the middle-left edge under the logo. Thanks!
Hey John, I checked out the link and wasn’t able to find the example or reproduce the error in IE7 either. Let me know if this is something you have fixed or if you still need some help.
@12 & 13 – Tai, you are right, the code does not feature a “add element” function. I’ll make note of that for the next version, thanks.
Troy, great script, however I was viewing your demo at http://www.consideropen.com/demos/smart-hover-box/ using IE7 v7.0.5730.13 and noticed the javascript error being produced that John was talking about. Any news on this?
Line: 13
Char: 52
Error: ‘closeBoxesTimer’ is undefined
Code: 0
URL: http://www.consideropen.com/demos/smart-hover-box/
I see what you are taking about, not sure how i missed that. I think what’s happening is that “closeBoxTimer” just needs to be declared, i’ll do some experimenting and post once I find something. Thanks all for pointing this out.
That was a quick fix…however trying to click the hyperlink in the hover box example or even holding the cursor over the div to keep the box open seems to not work as well as it did before. Any ideas, maybe just adjusting the timer?
I see what happened… again, an IE only problem. Gimme a few.
Update: thanks all, was able to get rid of that IE error, turned out I needed to add a conditional if $defined to the clear events, as well as create the “closeBoxesTimer ” var outside the each loop. Thanks much!
I read this now I was thinking it was me because I did remove a lot code to make it work in a WYSIWYG webbuilder.
Line: 13
Char: 52
Error: ‘closeBoxesTimer’ is undefined
Code: 0
URL: http://www.consideropen.com/demos/smart-hover-box/
I did get the warning in firefox and put the word closeboxtimer in this line.
var smartHoverBox = function(boxTimer, xOffset, yOffset, smartBoxSuffix, smartBoxClose, closeBoxesTimer) {
Troy the new update das not hover the tooltip in webbuilder maybe you use the old code with closeboxtimer in the first line.
Sorry I`am not a coder if I may wrong about this.
Eddy.
Ah, that makes sense. Glad you were able to make it work
People tested the old hoverbox code with( closeBoxesTimer in the first line)in IE6,avantbrowser10.5, firefox 2.0, Opera 9.5, Firefox 3, IE7,
Avantbrowser 11.7 built 7, Firefox 2.0, Opera 9.25 and GoogleChrome 0.2.149.
all seems ok,maybe you like to now this.
Hi Troy, excellent work, well done and many thanks
I can’t seem to getting it working properly though. It all works fine except that when you first go to the page the hoverbox is not hidden. It only goes after rolling over it or refreshing the page.
Any ideas as to what causes this? I’ll upload the site if you need to see it (although I built it years ago and my old code is embarrassing
)
[...] on Fri 21-11-2008 25 Awesome tutorials for web designers Saved by greglemon on Thu 20-11-2008 Smart Hover Box for Mootools 1.2 Saved by Leidarodriguez on Mon 17-11-2008 Mootools plugins you don’t want to miss! Saved by [...]
[...] Smart Hover Box for Mootools Tags: Hover Box, Hover Box in Mootools, Smart Hover Box [...]
I am having a strange problem with Firefox and the hover. If the hover overlaps a textarea, and the user moves the mouse from/off the hover onto the textarea, the hover doesn’t go away like it should.
I found a jquery fix, but not sure how to apply this fix to the hover with mootools.
Here is the jquery fix for the firefox bug.
// workaround for Mozilla bug: not firing mouseout/mouseleave on absolute positioned elements over textareas and input type=”text”
var handleHover = function(e)
{
var t = this;
// next two lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
var p = (e.type == “mouseover” ? e.fromElement : e.toElement) || e.relatedTarget;
while ( p && p != this )
{
try { p = p.parentNode; } catch(e) { p = this; }
}
if ( p == this )
{
if ( $.browser.mozilla )
{
if ( e.type == “mouseout” )
{
t.mtout = setTimeout( function(){doHover(e,t);}, 30 );
}
else
{
if (t.mtout) { t.mtout = clearTimeout(t.mtout); }
}
}
return;
}
else
{
if (t.mtout) { t.mtout = clearTimeout(t.mtout); }
doHover(e,t);
}
};
Hello and thanks so much for a great script. I was wondering if there was anyway for me to add timing to the mouse enter event ie. so that when you hover there is a delay. Thanks so much for a great script I was trawling the web for ages before I found it.
Sarah