demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

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

A Stitch In Time: Using JavaScript To Trigger CSS3 Animations

javascript / animation

Estimated reading time: 3 minutes, 18 seconds

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 CSS3 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 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:

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

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.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.