2D and 3D transforms - tilts, cubes, perspective and chained motion - driven only by hover and keyframes.
13D Card Tilt
Tilts a card in 3D with a moving glare on hover - a pure CSS take on the mouse-follow tilt. Class: fx-3d-card-tilt
What our buyers asked us most
$75.39
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="card border-0 shadow-sm fx-3d-card-tilt" style="width:12rem">
<img src="https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?auto=format&fit=crop&w=1200&h=800&q=70" alt="Card cover" class="card-img-top object-fit-cover" style="height:100px">
<div class="card-body py-2">
<h3 class="h6 mb-0">What our buyers asked us most</h3>
<p class="small text-body-secondary mb-0">$75.39</p>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-3d-card-tilt {
position: relative; overflow: hidden; transform-style: preserve-3d;
transform: perspective(900px) rotateX(0deg) rotateY(0deg);
transition: transform .55s cubic-bezier(.2, .8, .2, 1), box-shadow .55s;
}
.fx-3d-card-tilt::after {
content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .45) 48%, transparent 62%);
transform: translateX(-60%); transition: transform .7s ease, opacity .4s;
}
.fx-3d-card-tilt:hover, .fx-3d-card-tilt:focus-within {
transform: perspective(900px) rotateX(8deg) rotateY(-12deg) translateY(-4px);
box-shadow: 18px 22px 40px -18px rgba(var(--wt-primary-rgb), .55);
}
.fx-3d-card-tilt:hover::after, .fx-3d-card-tilt:focus-within::after { opacity: 1; transform: translateX(60%); }
@media (prefers-reduced-motion: reduce) {
.fx-3d-card-tilt, .fx-3d-card-tilt::before, .fx-3d-card-tilt::after, .fx-3d-card-tilt *, .fx-3d-card-tilt *::before, .fx-3d-card-tilt *::after { animation: none !important; transition: none !important; }
}2Skew Parallax
On hover the card skews one way and its image drifts the other, creating a quick sense of depth. Class: fx-skew-parallax
Our favourite tips for busy weeks
$19.54
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="card border-0 shadow-sm fx-skew-parallax" style="width:12rem">
<img src="https://images.unsplash.com/photo-1771366260867-7e07094579d7?auto=format&fit=crop&w=1200&h=800&q=70" alt="Card cover" class="card-img-top object-fit-cover" style="height:100px">
<div class="card-body py-2">
<h3 class="h6 mb-0">Our favourite tips for busy weeks</h3>
<p class="small text-body-secondary mb-0">$19.54</p>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-skew-parallax { overflow: hidden; transition: transform .5s cubic-bezier(.2, .8, .2, 1); }
.fx-skew-parallax img { transform: scale(1.12); transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.fx-skew-parallax:hover { transform: skewY(-2deg) translateY(-3px); }
.fx-skew-parallax:hover img { transform: scale(1.18) skewY(2deg) translateY(-6px); }
@media (prefers-reduced-motion: reduce) {
.fx-skew-parallax, .fx-skew-parallax::before, .fx-skew-parallax::after, .fx-skew-parallax *, .fx-skew-parallax *::before, .fx-skew-parallax *::after { animation: none !important; transition: none !important; }
}3Transform Chain
Chains translate, rotate and scale as separate properties with staggered timing for a lively hover. Class: fx-transform-chain
Buying a building plot: what to check first
$26.48
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="card border-0 shadow-sm fx-transform-chain" style="width:12rem">
<img src="https://images.unsplash.com/photo-1670589953882-b94c9cb380f5?auto=format&fit=crop&w=1200&h=800&q=70" alt="Card cover" class="card-img-top object-fit-cover" style="height:100px">
<div class="card-body py-2">
<h3 class="h6 mb-0">Buying a building plot: what to check first</h3>
<p class="small text-body-secondary mb-0">$26.48</p>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-transform-chain { transition: translate .3s ease, rotate .5s cubic-bezier(.34, 1.56, .64, 1) .08s, scale .4s ease .16s; }
.fx-transform-chain:hover, .fx-transform-chain:focus-visible { translate: 0 -8px; rotate: -3deg; scale: 1.06; }
@supports not (translate: 0) {
.fx-transform-chain { transition: transform .4s cubic-bezier(.34, 1.56, .64, 1); }
.fx-transform-chain:hover, .fx-transform-chain:focus-visible { transform: translateY(-8px) rotate(-3deg) scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
.fx-transform-chain, .fx-transform-chain::before, .fx-transform-chain::after, .fx-transform-chain *, .fx-transform-chain *::before, .fx-transform-chain *::after { animation: none !important; transition: none !important; }
}