Stack Motion Hover Effects

Experimental hover effects that reveal a stack of multiple colored cards behind the hovered item.

View demo Download source

Today we’d like to share some tiny hover effect ideas with you. The concept stems from the hover effect seen on Merci-Michel which has a really nice feel to it because of its fluidity. The idea is to show a stack behind the hovered thumbnail that has the same main color as the image and then animate the elements in a swift motion. We are using the JavaScript library anime.js for the animations.

Attention: Modern CSS properties at work, so modern browsers only.

Stack Motion Effect Markup & Styles

The markup for the items is as follows:

<div class="grid grid--effect-vega">
	<a href="#" class="grid__item grid__item--c1">
		<div class="stack">
			<div class="stack__deco"></div>
			<div class="stack__deco"></div>
			<div class="stack__deco"></div>
			<div class="stack__deco"></div>
			<div class="stack__figure">
				<img class="stack__img" src="img/1.png" alt="Image"/>
			</div>
		</div>
		<div class="grid__item-caption">
			<h3 class="grid__item-title">anaerobic</h3>
			<div class="column column--left">
				<span class="column__text">Period</span>
				<span class="column__text">Subjects</span>
				<span class="column__text">Result</span>
			</div>
			<div class="column column--right">
				<span class="column__text">2045</span>
				<span class="column__text">133456</span>
				<span class="column__text">Positive</span>
			</div>
		</div>
	</a>
	<a href="#" class="grid__item grid__item--c2"><!-- ... --></a>
	<a href="#" class="grid__item grid__item--c2"><!-- ... --></a>
</div><!-- /grid -->

We use a specific class for the grid to create individual effects. The four stack__deco divisions are the decorative elements that we animate along with the stack__figure and the image. The grid itself is the container that has perspective. The grid caption has a title and two columns that optionally get animated, too.

For the grid we use a flexbox layout (see demo.css). For the decorative cards of the stack and the figure with its image will have the following styles:

.stack {
	position: relative;
	width: 100%;
	height: 200px;
	transform-style: preserve-3d;
}

.stack__deco {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-color: currentColor;
	transform-origin: 50% 100%;
}

.stack__deco:first-child {
	opacity: 0.2;
}

.stack__deco:nth-child(2) {
	opacity: 0.4;
}

.stack__deco:nth-child(3) {
	opacity: 0.6;
}

.stack__deco:nth-child(4) {
	opacity: 0.8;
}

.stack__figure {
	position: relative;
	display: flex;
	justify-content: center;
	align-items: center;
	overflow: hidden;
	width: 100%;
	height: 100%;
	cursor: pointer;
	transform-origin: 50% 100%;
}

.stack__img {
	position: relative;
	display: block;
	flex: none;
}

For some effects we want some special styles:

/* Individual effects */

/* Vega */
.grid--effect-vega .column {
	opacity: 1;
}

/* deneb */
.grid--effect-deneb {
	perspective: none;
}

.grid--effect-deneb .stack__figure,
.grid--effect-deneb .stack__deco {
	transform-origin: 50% 50%;
}

.grid--effect-deneb .column {
	opacity: 1;
}

/* ... */

And here is an example for an effect animation (hovering in and out):

HamalFx.prototype._in = function() {
	var self = this;

	this.DOM.stackItems.map(function(e, i) {
		e.style.opacity = i !== self.totalItems - 1 ? 0.2*i+0.2 : 1
	});

	anime({
		targets: this.DOM.stackItems,
		duration: 1000,
		easing: 'easeOutExpo',
		translateY: function(target, index) {
			return -1*index*5;
		},
		rotate: function(target, index, cnt) {
			if( index === cnt - 1 ) {
				return 0;
			}
			else {
				return index%2 ? (cnt-index)*1 : -1*(cnt-index)*1;
			}
		},
		scale: function(target, index, cnt) {
			if( index === cnt - 1 ) {
				return 1;
			}
			else {
				return 1.05;
			}
		},
		delay: function(target, index, cnt) {
			return (cnt-index-1)*30
		}
	});
	
	anime({
		targets: this.DOM.img,
		duration: 1000,
		easing: 'easeOutExpo',
		scale: 0.7
	});

	anime({
		targets: [this.DOM.columns.left, this.DOM.columns.right],
		duration: 1000,
		easing: 'easeOutExpo',
		translateX: function(target, index) {
			return index === 0 ? -30 : 30;
		}
	});
	
};

HamalFx.prototype._out = function() {
	var self = this;

	anime({
		targets: this.DOM.stackItems,
		duration: 500,
		easing: 'easeOutExpo',
		translateY: 0,
		rotate: 0,
		scale: 1,
		opacity: function(target, index, cnt) {
			return index !== cnt - 1 ? 0 : 1
		}
	});

	anime({
		targets: this.DOM.img,
		duration: 1000,
		easing: 'easeOutElastic',
		scale: 1
	});

	anime({
		targets: [this.DOM.columns.left, this.DOM.columns.right],
		duration: 500,
		easing: 'easeOutExpo',
		translateX: 0
	});
};

We hope you like these hover effects and find them inspirational!

References and Credits

View demo Download source

Previous:
Next:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://www.codrops.com

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start leanirng CSS now.

Feedback 10

  1. 2

    Wow! I don’t have any uses for something like that just now but I will definitely keep those in mind, awesome.

  2. 5

    It is great….I kind of made it work. But in my case after the hover animation, the images disappears. If I hover on the empty space I can see the animation again (firefox and chrome). Oh well. Too advanced for me.

  3. 6

    Those are fantastic hover effect! I will use one of this in my personal landing page! Congrats!

  4. 8

    Amazing hover effects for slow motion. I can use all of these effects in my project. Thank you.

  5. 9

    Can you help me to implement it? i try to use it but im just seeing the items without hover effects

Follow this discussion

Leave a Comment