Slide and Bounce an Image on Hover

by kirupa   |   11 October 2012

Commonly, you only see transitions being used on hover. Given some of the limitations transitions have in defining rich animations, this snippet shows how you can play a CSS animation on hover instead to create both a slide and a bounce. I also handle the handoff problem animations have when you hover out while the hover-in animation is still playing.

The Example

Below is an example of this snippet running (you can also view it in its own page):

When you hover over each image, notice that your image slides up with a slight bounce. Hovering away does the same thing...except in the opposite direction.

The HTML

The HTML for this example look as follows:

<div id="main">
<div class="pictureContainer">
<img class="theimage" src="http://www.kirupa.com/html5/examples/images/smiley.png" height="300" width="150"/>
</div>
<div class="pictureContainer">
<img class="theimage" src="http://www.kirupa.com/html5/examples/images/tongue.png" height="300" width="150"/>
</div>
<div class="pictureContainer">
<img class="theimage" src="http://www.kirupa.com/html5/examples/images/meh.png" height="300" width="150"/>
</div>
<div class="pictureContainer">
<img class="theimage" src="http://www.kirupa.com/html5/examples/images/sad.png" height="300" width="150"/>
</div>
</div>
<script src="http://www.kirupa.com/html5/examples/js/prefixfree.min.js"></script>

This corresponds to the four images that you see. Notice that I am specifying the prefix free library.

The CSS

The style rules for specifying the animation and the keyframes along with the arrangement of the images looks as follows:

#main {
	height: 330px;
	width: 330px;
}
.pictureContainer {
	border: 1px solid #CCCCCC;
	display: inline-block;
	float: left;
	height: 150px;
	margin: 5px;
	overflow: hidden;
	width: 150px;
}

.pictureContainer img {
	position: relative;
	top: 0px;
	animation-duration: .3s;
	animation-timing-function: ease-in-out;
	animation-fill-mode: forwards;
}

.pictureContainer img.slideIn {
	animation-name: inKeyframes;
}

.pictureContainer img.slideOut {
	animation-name: outKeyframes;
}

@keyframes inKeyframes {
70% {
		top: -170px;
	}
	100% {
		top: -150px;
	}
}

@keyframes outKeyframes {
	70% {
		top: 20px;
	}
	100% {
		top: 0px;
	}
}

JavaScript

In order to handle the synchronization problems associated with hovering out when your hovering in animation is still playing, I use JavaScript to store the values so that the hover out animation knows from where to begin:

var images = document.getElementsByClassName("theimage");

for (var i = 0; i < images.length; i++) {
	var image = images[i];
	image.addEventListener('mouseover', addAnimationClass, false);
	image.addEventListener('mouseout', removeAnimationClass, false);
}

var topPosition = null;

function addAnimationClass(e) {
	var thisImage = e.target;

	topPosition = getComputedStyle(thisImage).top;
	thisImage.style.top = topPosition;

	thisImage.className += " slideIn";
	thisImage.className = thisImage.className.replace(" slideOut",'');
}

function removeAnimationClass(e) {
	var thisImage = e.target;

	topPosition = getComputedStyle(thisImage).top;
	thisImage.style.top = topPosition;

	thisImage.className += " slideOut";
	thisImage.className = thisImage.className.replace(" slideIn",'');
}

Because I am only animating the top property, my JavaScript only handles storing its value. If your animation modifies more CSS properties, then you'll need to extend this code to cover the additional properties as well.

Further Exploration

If you want to know more about this snippet and other related background reading, check out the following articles:

Getting Help

If you have questions, need some assistance on this topic, or just want to chat - post in the comments below or drop by our friendly forums (where you have a lot more formatting options) and post your question. There are a lot of knowledgeable and witty people who would be happy to help you out

Share

Did you enjoy reading this and found it useful? If so, please share it with your friends:

If you didn't like it, I always like to hear how I can do better next time. Please feel free to contact me directly via e-mail, facebook, or twitter.

Kirupa Chinnathambi
I like to talk a lot - A WHOLE LOT. When I'm not talking, I've been known to write the occasional English word. You can learn more about me by going here.

Add Your Comment (or post on the Forums)

blog comments powered by Disqus

Awesome and high-performance web hosting!
BACK TO TOP
new books - yay!!!