From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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.
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.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
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
- Idea based on the effect seen on the projects page of Merci-Michel
- Anime.js by Julian Garnier
- Images made with a design by Freepik.com
- Typeface Overpass Mono by Delve Withrington
Really nice! I want to use some in my projects. 😀
Wow! I don’t have any uses for something like that just now but I will definitely keep those in mind, awesome.
I wonder if similar animation can be tried with multiple box-shadows. Worth trying…
I just can say WOW
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.
Those are fantastic hover effect! I will use one of this in my personal landing page! Congrats!
very interesting, I love to use it.
Amazing hover effects for slow motion. I can use all of these effects in my project. Thank you.
Can you help me to implement it? i try to use it but im just seeing the items without hover effects
wow! i have no words !
unfortunately i cant fix it on my projectt , it was good if you make a short clip for install that or teach a lit better or more …
Happy new spirit \m/