Home page of Africa Tour 2008, created by guys from Stylishmedia is a good example of how simple solutions can also be effective. In this tutorial I will recreate (in my own way) their effect using World map.
As I said, the effect is more than simple – each continent is marked with a "pin balloon" (I couldn't think of a better name) and when you hover the balloons they get larger. This is something that many of us have done many times, I'm sure of it. However, this example has a trick: balloons grow diagonally starting at the anchor point (anchor point is the little triangle that comes out of the balloon).
So, we have three tasks:
- to anchor each balloon properly
- to position each balloon properly
- to add the hover effect
Anchoring and positioning
Each balloon will be a div with a background image, absolutely positioned inside the relatively positioned World map. This is the HTML structure that we need.
<div id="map">
<div id="america"></div>
<div id="europe"></div>
<div id="africa"></div>
<div id="asia"></div>
<div id="australia"></div>
<div id="southAmerica"></div>
</div>
And the css:
#map { width:669px; height:351px; background-image:url('map.jpg'); position:relative;}
#map div { width: 120px; height:60px; position:absolute; cursor:pointer; background-repeat:no-repeat;}
This part is simple. Each balloon will be 120x60px, absolutely positioned.
Now, let us examine the image below. We want to anchor the balloon to the center of the North America. That is in the position x = 150px, y = 120px. Simplest way to position an element is to set its top and left values. To do that, we have to subtract the width and height of the balloon image from the x and y of the anchor point. In case of North America, our positioning point will be x = 30px, y = 60 px.
But there is more. We want our anchor point to remain fixed while the balloon grows in the opposite direction. In order to achieve this we need to position the background image properly. Div named #america will have "background-position:right bottom" and that will assure that anchor point will not move.
#america { background-image:url('america_small.png'); top:60px; left:30px; background-position:right bottom;}
This allows us to simply show another image on hover:
#america:hover {background-image:url('america_big.png');}
Let us examine the next example: Africa's balloon is flipped horizontally in comparison to North America's balloon. This only means a different background image position.
The image will be positioned to the left and bottom:
#africa{background-image:url('africa_small.png'); top:160px; left:360px; background-position:left bottom;}
Other balloons can be anchored using the same approach. Now, let's see the full CSS code:
#map { width:669px; height:351px; background-image:url('map.jpg'); position:relative;}
#map div { width: 120px; height:60px; position:absolute; cursor:pointer; background-repeat:no-repeat;}
/* Right-anchored baloons */
#america { background-image:url('america_small.png'); top:60px; left:30px; background-position:right bottom;}
#america:hover {background-image:url('america_big.png');}
#europe{background-image:url('europe_small.png'); top:50px; left:240px; background-position:right bottom;}
#europe:hover {background-image:url('europe_big.png');}
#southAmerica{background-image:url('southamerica_small.png'); top:190px; left:110px; background-position:right bottom;}
#southAmerica:hover {background-image:url('southamerica_big.png');}
/* Left-anchored baloons */
#africa{background-image:url('africa_small.png'); top:160px; left:360px; background-position:left bottom;}
#africa:hover {background-image:url('africa_big.png');}
#asia{background-image:url('asia_small.png'); top:60px; left:480px; background-position:left bottom;}
#asia:hover {background-image:url('asia_big.png');}
#australia{background-image:url('australia_small.png'); top:200px; left:540px; background-position:left bottom;}
#australia:hover {background-image:url('australia_big.png');}
As I said at the beginning, effective doesn't always mean complicated. Now, where can this effect be used? Primarily on maps (world maps, region maps or city maps). You can use it to pinpoint any location, from town to your company's headquarters, for example. I can't see any other usage, can you?
Hello,
excuse me but I thought that your blog is under CC.
P.s. But why I can’t to traduce it in Italian?
Pretty cute and could be really useful somewhere too.
Just one thing: You could have used CSS sprites (http://www.alistapart.com/articles/sprites/) to change the background-image. The image needed to be loaded when I hovered the balloon, which took a while, showing me a short "blink".
Another thing: You misspelled "balloon" on your example page ;) .
ziosteve: It would be the same as if you buy a book, translate it and publish it without permission. It’s just protected by copyright.
Marco: Sprites, of course, what was I thinking about! Ah, I always misspell something :)
[quote]Pretty cute and could be really useful somewhere too.[/quote]
:D
Simple and useful, Cool ;)
Nice example Janko! Does :hover works on IE6? In this case we should use JS or some HTX libraries…
that is what makes your blog so special, always useful stuff.
keep up the good work Janko ;)
Pretty cool trick Janco. :)
and I agree with Marco, you should have used sprites.
Davide, mohamadreza, Marwan: thank you guys!
Sergejus: I think it’s not working in IE6, some JavaScript would be needed.
aravind: I agree with you and Marco, I totally overlooked it. Thanks for commenting!
Cool idea Janko~
May I make a suggestion for the IE6 issue?
You can use something like <a href="#" id=""></a> instead of the <div id=""></div>, this way IE6 can rely on the :hover w/out using any javascript :-)
Nice effect. I think I’m gonna try this. Thanks!
Soh Tanaka: Thanks for the IE6 tip!!
BIll: Thkx ;)
Nice, easy and useful.
You should try using CSS Sprites to prevent the images from ‘jumping’ when you hover over them.
[b]@Marco[/b]: Yes, i was thinking about sprites right away as well – definitely the right solution for this.
[b]@Janko[/b]; Wouldn’t it be an idea to position the inner divs according to the anchor point, so that you position #america with bottom:XXpx; right:XXpx;?
That definitely strikes me as more logical, and it would make it possible to resize the hitarea/inner div size according to the background size.
Evan: Of course :)
Laust: That could be good solution if anchor points are always in the bottom-right corner. However anchor points could be placed anywhere, like in the case of Africa. It also could be positioned top-right, why not? It’s easier to calculate from a known point and that is 0,0. And the only thing that we know for sure is that top right corner of the map is 0,0 – size could vary.
@Janko:
As to which corner the balloon pin’s acnhor is positioned, then the css would have to vary as well (i know this is high maintenance, but the css is pixel-based anyway, so i guess the map size won’t vary that much. If all sizes varies in relation to each other you could use percentages.)
with africa you’d have to use bottom:XXpx;left:XXpx;, but that would still make more sense in relation to what you’re trying to achieve, at least in my mind.
Yes it would offset everything if you decide to increase your map’s height with 10px, but if you do that, i think you’d change the maps content, and would have to reposition everything anyway, even if you use top/left consistently.
There is a delay, would you recommend prefetching the images so there is no delay on the initial hover?
Laust: Hm, still think that having one "measurement" point is more practical and consistent. It’s easier to calculate from 0,0 for any balloon. Then you don’t have to worry where the anchor point is (if you pull images from the database, for example) but rather always position it using top:XXpx and left:XXpx.
TG: Actually I should’ve use css sprites in this example, like Marco suggested first :)
Nice little titbit, although surely using an unordered list would be much cleaner, as it is a menu or sorts. Apply the map as a background to the ul and each balloon being a link in a list item…
Nice Post Buddy. Thanks. http://tutorialfeed.blogspot.com
Good example.
One thing I would change would be the divs. I would change them to links, like below then you can get the :hover effect working on IE6. No need for Java.
<a href="#"><span style="visibility: hidden;">europe</span></a>
Harry: UL, why not! :)
Rakesh: thanks.
Craig: Agree, as Soh Tanaka mentioned :)
Janko – at the end of your article, you said:
[quote]Now, where can this effect be used? Primarily on maps (world maps, region maps or city maps). You can use it to pinpoint any location, from town to your company’s headquarters, for example. I can’t see any other usage, can you? [/quote]
Well, how about this – Let’s say you have a picture of a crowd of people, each of which needs to be identified when you hover over their face – that would be an excellent use for this type of pin balloon.
I previously created a website a year or so ago with this requirement using a simple text popout, but always disliked the look (changing client requirements made it start out one way and end up another way). See the page at
http://agreatdayinindy.com/Indy2008.aspx
I think I may have to do some tweaking if I get the time!
Thanks for the cool tut. Another way to get rid of the flicker on hover would be to load all the css images with jquery. I do this on my blog and it works great and makes the next page open faster. Here is the page with the jQuery preload plugin: http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/
You can see it in action of my blog’s sidebar. The images on the twitter & delicious H2 headers is a css :hover, but because all the images are loaded with jQuery it has no flicker or delay between images.
非常不错.. 我喜欢
Just like Marco mentioned, sprites would have made it perfect because it ‘flickers’ a bit right now. But besides that nice article!
Great post. Very nice tutorial.
It looks really nice! Great idea! I agree, that using a sprite would be even better. And if you would like to improve it you should also preload the images.
its really nice post thanks
Do not use a dozen of unsemantic div! Just use a UL with list-items positioned absolutely.
Nice, but it would’ve been better if the image tip and rollover effect was done properly…meaning they should really be one image so there isn’t any image flicker while hovering over for the first time. Other than…pretty cool.
Thanks everyone!
RobBohn: Nice idea!
Montana Flynn, Aaron, George Lucy: Totally agree, it should be done, preferably with css sprites.
Helen: At first I was thinking to do it using UL, but I gave up. Can’t explain why :)
I agree with the comments on the slight flicker the first time that the balloon is hovered over … but the part I like the most is a simple one – the balloon can expand top right or to top left according to how you set it up and the requirements for the position of the marker.
As you said "effective doesn’t always mean complicated" and in this instance a small additional thought makes the visual impression more effective.
Only downside – looks to take a long time to implement.
simple functionality implemented nicely
Very nice tutorial will help a lot
Thanks,
Its good to use…
Should check for some pre-load options aswell, the first time you hover it kinda feels buggy.
Nice stuff tho.