">
Photograph of the interior of Notre Dame basilica, Old Montreal, Quebec, Canada

Old Montreal

The site of the original French settlement, turned into a walled and fortified city in 1721.
Photograph of ring-tailed lemur

Biodome

Originally constructed as a velodrome and judo dojo for the 1976 Olympic Games, the dome was converted into a nature exhibit in 1992.
Map of Montreal in 1700 Old Montreal Biodome Old Montreal Biodome
Imagemap enhanced with CSS3 & JavaScript. Hotspots are marked in red on the inset illustration; hotspots are just below the inset

has many powerful features, but one major limitation: changes to elements can only affect those that follow them. That is, hover on an element can affect the next element, using an adjacent or sibling selector, or a child element with a descendant selector, but not any other element on the page. This limits CSS interactivity to certain modalities… and while there’s plenty of room within this space, forcing certain kinds of UI to work with pure CSS sometimes necessitates a degree of trickery and inspired hacks.

has the ability to modify arbitrary elements on the page, linking an action here to an effect over there. run “closer to the metal” than JavaScript manipulations, making smoother, swifter and cleaner transitions. When an effect would benefit from the strengths of both technologies, it makes sense to merge them.

A good example is my earlier creation of a modern imagemap that utilized CSS3 transitions to create popup information boxes. While it worked, it did so only to a fashion: the use of the CSS :target pseudo-selector meant that current browsers would visually jump the page to the clicked portion of the imagemap due to a shared bug.

Rather than wait for the browser code to be fixed, a better solution right now would be to hybridize the effect: keep the pop-up elements as pure , and retain the , but use JavaScript to initiate the effect.

To demonstrate this idea I’ll create another imagemap, this time of old Montreal in the 1700s. You can see the imagemap hotspots highlighted in the illustration. I won’t cover this step here; if you’re interested, you can read how to make an imagemap in Dreamweaver.

Each area on the imagemap uses the freeform HTML5 data attribute to create data-pop, with a value that matches the id of the associated <figure> element. Each interior <figure> contains information related to the highlighted area.

<figure id="oldmap">
	<figure id="old-montreal">
		<img src="basilique-notre-dame.jpg" alt="Photograph of Notre Dame">
		<h4>Old Montreal</h4>
		<figcaption>The site of the original French settlement, turned into a fortified city in 1721.</figcaption>
	</figure>
<figure id="biodome">
	<img src="ring-tailed-lemur.jpg" alt="Photograph of ring-tailed lemur">
	<h4>Biodome</h4>
	<figcaption>
Originally constructed as a velodrome and judo dojo for the 1976 Olympic Games, the dome was converted into a nature exhibit in 1992.
	</figcaption>
</figure>
	<img src="montreal.jpg" alt="Map of Montreal in 1700"
style="max-width:100%;height:auto;" usemap="#montreal">
	<map name="montreal" style="position: relative">
	<area shape="poly" alt="Old Montreal" data-pop=old-montreal
coords="577,282,562,270,521,290,531,309,557,307,575,298,578,231">
	<area shape="poly" coords="586,320,595,300,590,288,570,312"
alt="Biodome" data-pop=biodome >
	</map>
</figure>

Above that, I’ll create a few rules for the individual <figure> elements to determine their position, an attribute selector to set them all to hidden (using opacity) and a class (.popup) that will be used to “pop” each <figure> into existence:

figure#oldmap {
	margin: 0;
	padding: 0;
	position: relative;
}
figure#oldmap figure {
	width: 200px;
	position: absolute;
	background: rgba(238,238,238,0.78);
	border: 1px solid rgba(177,177,177,0.8);
	border-radius: 3px;
	opacity: 0;
	left: 203px;
	top: 120px;
	z-index: 99;
	transform: scale(0.8);
	transition: .4s all cubic-bezier(.06,.62,.73,1.5);
	padding: 0;
}
figure#oldmap figure img { 
	width: 100%;
}
.popup {
	opacity: 1;
	transform: scale(1);
}
figure#oldmap figure h4 {
	text-align: center;
	margin: .5rem;
}
figure#oldmap figure figcaption {
	padding: .5rem;
	margin-top: 0;
	margin-bottom: 1rem;
}

Finally the script at the end of the page:

$('area').click(function() {
	var popup = $(this).attr('data-pop');
	$('figure#oldmap figure').removeClass("popup");
	$("#" + popup).addClass("popup");
	return false;
});

The JQuery code is very simple: using the value of data-pop from the area that is clicked on to determine the id of the <figure> to apply the popup class to.

You’ll note that the script doesn’t immediately work, even though the class is applied, due to the fact that the class will not overrule the established CSS. One way to get around this is to add the recently-discussed !important: to the declarations:

.popup {
	opacity: 1 !important;
	transform: scale(1) !important;
}

This brings the two technologies nicely together: the transition will occur due to the state of the element changing: in this case, through having a new class applied via .

Map of old Quebec from Wikipedia, photographs by Doug and Eric Bégin. licensed under Creative Commons.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.