AnimationsSimpleApril 8, 2026
Image Scale on Hover
Image starts slightly scaled up (1.1) inside an overflow-hidden container and returns to scale(1) on hover. The container clips the overflow, giving the image room to breathe inward.
View Full Demo →Preview
Source
demo.jsx
import ImageScaleOnHover from "./index.jsx";
import { imageScaleOnHover } from "@/content/animations/demo-data.js";
import styles from "./demo.module.css";
export default function ImageScaleOnHoverDemo() {
return (
<div className={styles.demo}>
<div className={styles.top}>
<p className={styles.label}>Portfolio — 2024</p>
<h2 className={styles.heading}>Selected Work</h2>
</div>
<ImageScaleOnHover {...imageScaleOnHover} />
</div>
);
}
index.jsx
import styles from "./styles.module.css";
export default function ImageScaleOnHover({ items = [] }) {
return (
<div className={styles.grid}>
{items.map((item) => (
<a key={item.label} href={item.href} className={styles.item}>
<div className={styles.imageWrap}>
<div
className={styles.image}
style={{ backgroundImage: `url(${item.image})` }}
/>
</div>
<span className={styles.label}>{item.label}</span>
</a>
))}
</div>
);
}
demo.module.css
.demo {
min-height: 100vh;
background: #0a0a0a;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 5rem 3rem;
gap: 3rem;
}
.top {
text-align: center;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.label {
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 0.14em;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.35);
}
.heading {
font-size: clamp(2rem, 5vw, 4rem);
font-weight: 500;
letter-spacing: -0.03em;
line-height: 1;
color: #ffffff;
}
/* Override item label color for dark bg */
.demo :global(.label) {
color: rgba(255, 255, 255, 0.6);
}
styles.module.css
.grid {
display: flex;
gap: 2rem;
padding: 3rem;
justify-content: center;
flex-wrap: wrap;
}
.item {
display: flex;
flex-direction: column;
gap: 0.75rem;
text-decoration: none;
color: #1a1a1a;
}
.imageWrap {
width: 200px;
height: 260px;
overflow: hidden;
border-radius: 6px;
}
.image {
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
transform: scale(1.1);
transition: transform 700ms cubic-bezier(0.25, 1, 0.5, 1);
}
.item:hover .image {
transform: scale(1);
}
.label {
font-size: 0.875rem;
font-weight: 500;
letter-spacing: -0.01em;
}