blog

Stack Motion Hover Effects

Category: Playground

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

Stack Motion Hover Effects was written by Mary Lou and published on Codrops.

LEAVE A REPLY