I posted about jQuery UI’s position feature years ago, but I was just thinking of how useful the collision detection part of that feature is. In a nutshell: you can position an element where you want them to go, but if it calculates that where you’re putting it would be offscreen or otherwise hidden, it will adjust the positioning to fix it.
Here’s an example from Disqus, where the default for this user popup is to open upwards, but if it would be hidden by the top of the screen, it opens downward instead.

I recently just did the same thing on CodePen, to ensure the settings dropdown area didn’t open below the bottom edge of the page, and instead opens upward.

Anytime an element opens directionally on a page, and you aren’t 100% sure that direction won’t be hidden, collision detection is a good idea.
Tooltips are a classic example. You might design a tooltip to open above and to the right of a link.
$("a[data-tooltip]")
.on("mouseenter", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.position({
my: "left bottom",
at: "left top",
of: $(this)
})
.show();
});
(p.s. wouldn’t it be nice if we could do tooltips with HTML in them somehow without JS?)

But if that link was near the top of the page, that could easily open above the edge and be pretty useless:

Also could be dangerous along an edge, depending on how it’s designed:

jQuery UI actually defaults to having collision detection on, and it will “flip”, meaning:
Flips the element to the opposite side of the target and the collision detection is run again to see if it will fit. Whichever side allows more of the element to be visible will be used.
You have to explicitly turn that off if you want. Collision has a few other values as well, including fit
which nudges the position until the element fits onto the page/area, or fitflip
which does flip first then fit as needed.
That would look like this, with jQuery UI position:
$("a[data-tooltip]")
.on("mouseenter", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.position({
my: "left bottom",
at: "left top",
of: $(this),
collision: "flipfit"
})
.show();
});
Now, if the tooltip would open and be hidden by the top or edge, it’ll flip or move to fit:

How does it work? Math!
I’m sure you can imagine how. JavaScript knows the dimensions and position of all elements, and the viewport itself. So it can do a little check like: if an element of this size was at this position, does that fit within this area?
If you didn’t want to use jQuery UI, you could surely roll your own. One thing that I might recommend if you do: add class names to the element when it does a flip or fit. That’s lacking right now in jQuery UI, and you might need those class names to effect other elements in the tooltip. Say, to make sure a pointer arrow points to the right place.
Simple Demo
The container the collision detection works against doesn’t have to be the viewport, it can be a specified container. That’s what’s going on here, just to demonstrate:
See the Pen collision detection by Chris Coyier (@chriscoyier) on CodePen.
And the JS that hides the tooltips too:
$("a[data-tooltip]")
.on("mouseenter", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.position({
my: "left bottom",
at: "left top",
of: $(this),
collision: "flip",
within: ".page-wrap"
})
.show();
})
.on("mouseleave", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.stop()
.fadeOut(function() {
$(this).removeAttr("style");
});
});
Is this live on Codepen? If so, it’s not working for me. I frequently have my windows resized to weird short sizes and can’t access the menus, so this would be amazing.
How recently have you tried it? It was a problem for a while, but is fixed now.
It should be working. Primarily for when the editors are in left or right mode and the settings would open below the bottom of the page, but there is room above. There are limits to what collision detection can do =). Feel free to hit up support if there is a place you think it should be working but isn’t.
Thanks Chris, I’ll shoot support a message.
How is this different than a hover event? In this application there does not seem too be a difference. In 3D CSS Collisions make more sense.
Collision detection relates to hover in that if a hover event reveals an element, but the position of that revealed element were to be hidden or cut-off, it’s nice to know that (collision detection) so you can move it somewhere it isn’t hidden or cut-off.
Always nice to be tipped-off or reminded of another ‘tool for the toolbox’. Thanks, Chris.
What if it’s inside an iframe that, by itself, is big enough so it need not to scroll, but it’s containing page is small enough that an element in said iframe may get partially hidden?
Actually, this thing is cool.! But, in the codepen, if we are resizing the window, popup( information) will always open at bottom side of that little setting icon!
I had tested in firefox.!
Maybe try a cache flush or something. Here’s Firefox for me: http://cl.ly/YUj4
Feel free to hit up support if there is a place you think it should be working but isn’t. Screencast and detailed browser info would be helpful.
Yup Chris..! Okay..! ( I will check with latest versions of chrome & IE too.!)
Hey Chris,
This is TJ from the jQuery UI team. Thanks for the writeup. Just as an fyi you can get can get the CSS class names you’re looking for with the
using
property relatively easily. Here’s an example of using that property to style arrows: http://jsfiddle.net/tj_vantoll/587n9/.I just rolled my own for some popups I had going on a site last week. I didn’t even know JQuery UI had this ability! Pretty cool beans when you want to set it and be done real quick :)
The more i look into this, the more i want another CSS rule for such absolute positioned elements, for example:
Whereas scaling of those items would be another fine feature in CSS… :-)
Another approach would be using a selector like :validate, for example:
That would be a really nice feature for all those GUI developers out there…
This turned out nicely on codepen (and I see you took care of the other thing too, thanks).