Product Card
A shop card that rises into place and lifts under the cursor.
Why it is timed this way
The reasoning
The entrance is a keyframe animation and the hover is a transition, which is the split that matters: an entrance plays once on load, a hover has to be interruptible halfway through and reverse cleanly.
4 elements move, the first at 0ms and the last starting at 165ms — the whole scene settles by 1065ms. Every bar below is one element's animation window.
The code
Everything the scene needs, in whichever format you ship. Entrances compile to@keyframesand hover states totransition, with a reduced-motion guard on both.
.product {
transform: translate3d(0px, 0px, 0);
width: 960px;
height: 480px;
transform-origin: 480px 115px;
}
.product-card {
transform: translate3d(0px, 0px, 0);
box-shadow: 0px 14px 38px 0px #00000059;
width: 252px;
height: 150px;
background: #171a24;
border-radius: 18px;
transform-origin: 150px 99px;
transition: transform 200ms ease-out;
}
.product-card:hover {
transform: translate3d(330px, -8px, 0);
transition: transform 180ms ease-out;
}
.product-image {
transform: translate3d(0px, 0px, 0);
height: 18px;
background: #1f2331;
border-radius: 14px;
transform-origin: 44px 23px;
}
.badge {
transform: translate3d(0px, 0px, 0);
width: 60px;
height: 18px;
background: #22d3ee;
border-radius: 999px;
transform-origin: 36px 15px;
}
.badge-text {
transform: translate3d(0px, 0px, 0);
width: 60px;
height: 18px;
background: #00000000;
color: #06281e;
font-size: 12px;
font-weight: 700;
animation: badge-text-anim 1065ms linear 0ms infinite both;
will-change: transform, opacity;
}
@keyframes badge-text-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
65.73% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.product-title {
transform: translate3d(0px, 0px, 0);
height: 26px;
background: #00000000;
color: #eceef4;
font-size: 19px;
font-weight: 700;
animation: product-title-anim 1065ms linear 0ms infinite both;
will-change: transform, opacity;
}
@keyframes product-title-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
5.16% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
70.89% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.product-price {
transform: translate3d(0px, 0px, 0);
height: 22px;
background: #00000000;
color: #98a1b5;
font-size: 16px;
font-weight: 500;
animation: product-price-anim 1065ms linear 0ms infinite both;
will-change: transform, opacity;
}
@keyframes product-price-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
10.33% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
76.06% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
.add-to-cart {
transform: translate3d(0px, 0px, 0);
height: 42px;
background: #6366f1;
border-radius: 10px;
color: #ffffff;
font-size: 14px;
font-weight: 600;
transition: transform 200ms ease-out, background 200ms ease-out;
animation: add-to-cart-anim 1065ms linear 0ms infinite both;
will-change: transform, opacity;
}
.add-to-cart:hover {
transform: translate3d(24px, 129px, 0);
background: #8b7bff;
transition: transform 180ms ease-out, background 180ms ease-out;
}
@keyframes add-to-cart-anim {
0% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
}
15.49% {
transform: translate3d(0px, 48px, 0);
opacity: 0;
animation-timing-function: ease-out;
}
81.22% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
100% {
transform: translate3d(0px, 0px, 0);
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.product-card,
.badge-text,
.product-title,
.product-price,
.add-to-cart {
animation: none;
transition: none;
}
}More scenes
Three-Plan Pricing
Three plans that pop in, with the featured column raised and hover lifts on every card.
Feature Tile Grid
Six tiles arriving as a wave across the grid, each lifting on hover.
Testimonial Card
A quote card that rises into place, avatar first.