20 CSS Image Hover Effects 19 / 20
CSS Image Icon Reveal Center Hover
Thumbnail grid where the image darkens and an action icon (play, magnify, link) scales in at the exact centre on hover using transform origin.
The code
<div class="ih-19">
<div class="ih-19__grid">
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--1"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🎬</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">▶</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Intro Reel 2025</span><span class="ih-19__views">4.2k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--2"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌿</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔍</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Jungle Macro</span><span class="ih-19__views">1.8k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--3"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🔮</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔗</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Prism Study</span><span class="ih-19__views">9.1k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--4"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌅</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">▶</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Golden Hour BTS</span><span class="ih-19__views">3.3k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--5"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌊</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔍</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Deep Blue Series</span><span class="ih-19__views">7.6k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--6"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌺</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔗</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Bloom Editorial</span><span class="ih-19__views">2.9k views</span></div>
</div>
</div>
</div> <div class="ih-19">
<div class="ih-19__grid">
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--1"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🎬</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">▶</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Intro Reel 2025</span><span class="ih-19__views">4.2k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--2"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌿</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔍</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Jungle Macro</span><span class="ih-19__views">1.8k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--3"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🔮</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔗</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Prism Study</span><span class="ih-19__views">9.1k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--4"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌅</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">▶</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Golden Hour BTS</span><span class="ih-19__views">3.3k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--5"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌊</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔍</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Deep Blue Series</span><span class="ih-19__views">7.6k views</span></div>
</div>
<div class="ih-19__card">
<div class="ih-19__img ih-19__img--6"></div>
<div class="ih-19__img-content"><span class="ih-19__thumb">🌺</span></div>
<div class="ih-19__icon-wrap"><div class="ih-19__icon-btn">🔗</div></div>
<div class="ih-19__strip"><span class="ih-19__title">Bloom Editorial</span><span class="ih-19__views">2.9k views</span></div>
</div>
</div>
</div>.ih-19,.ih-19 *,.ih-19 *::before,.ih-19 *::after{margin:0;padding:0;box-sizing:border-box}
.ih-19 ::selection{background:#818cf8;color:#fff}
.ih-19{
--accent:#818cf8;--bg:#07070e;--text:#f1f5f9;--muted:#475569;
--duration:0.38s;--ease:cubic-bezier(0.16,1,0.3,1);
font-family:system-ui,sans-serif;background:var(--bg);padding:40px 24px;
min-height: 100vh;display:flex;align-items:center;justify-content:center;
}
.ih-19__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;max-width:780px;width:100%}
.ih-19__card{position:relative;border-radius:10px;overflow:hidden;aspect-ratio:4/3;cursor:pointer}
.ih-19__img{position:absolute;inset:0;transition:filter var(--duration) var(--ease),transform var(--duration) var(--ease)}
.ih-19__img--1{background:linear-gradient(135deg,#0f0c29,#312e81,#4338ca)}
.ih-19__img--2{background:linear-gradient(135deg,#042f2e,#065f46,#059669)}
.ih-19__img--3{background:linear-gradient(135deg,#3b0764,#7e22ce,#a855f7)}
.ih-19__img--4{background:linear-gradient(135deg,#1c1003,#92400e,#d97706)}
.ih-19__img--5{background:linear-gradient(135deg,#0c1445,#1e3a8a,#2563eb)}
.ih-19__img--6{background:linear-gradient(135deg,#1a0010,#9d174d,#e11d48)}
.ih-19__card:hover .ih-19__img{filter:brightness(0.4);transform:scale(1.06)}
.ih-19__img-content{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.ih-19__thumb{font-size:40px;opacity:0.4;transition:opacity var(--duration) var(--ease), transform var(--duration) var(--ease)}
.ih-19__card:hover .ih-19__thumb{opacity:0;transform:scale(0.7)}
/* The center icon — scales in from 0 */
.ih-19__icon-wrap{
position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
opacity:0;transform:scale(0.5) rotate(-20deg);
transition:opacity var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.ih-19__card:hover .ih-19__icon-wrap{opacity:1;transform:scale(1) rotate(0deg)}
.ih-19__icon-btn{
width:52px;height:52px;border-radius:50%;
background:rgba(255,255,255,0.12);
border:2px solid rgba(255,255,255,0.25);
backdrop-filter:blur(8px);
display:flex;align-items:center;justify-content:center;
font-size:22px;
transition:background 0.2s ease, transform 0.2s ease;
}
.ih-19__card:hover .ih-19__icon-btn:hover{background:rgba(255,255,255,0.22);transform:scale(1.1)}
/* Bottom strip */
.ih-19__strip{
position:absolute;bottom:0;left:0;right:0;padding:8px 10px;
background:linear-gradient(to top,rgba(0,0,0,0.8),transparent);
display:flex;align-items:center;justify-content:space-between;
}
.ih-19__title{font-size:11px;font-weight:700;color:var(--text)}
.ih-19__views{font-size:10px;color:var(--muted)}
@media(prefers-reduced-motion:reduce){.ih-19__img,.ih-19__thumb,.ih-19__icon-wrap{transition:none}.ih-19__icon-wrap{opacity:1;transform:none}} .ih-19,.ih-19 *,.ih-19 *::before,.ih-19 *::after{margin:0;padding:0;box-sizing:border-box}
.ih-19 ::selection{background:#818cf8;color:#fff}
.ih-19{
--accent:#818cf8;--bg:#07070e;--text:#f1f5f9;--muted:#475569;
--duration:0.38s;--ease:cubic-bezier(0.16,1,0.3,1);
font-family:system-ui,sans-serif;background:var(--bg);padding:40px 24px;
min-height: 100vh;display:flex;align-items:center;justify-content:center;
}
.ih-19__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;max-width:780px;width:100%}
.ih-19__card{position:relative;border-radius:10px;overflow:hidden;aspect-ratio:4/3;cursor:pointer}
.ih-19__img{position:absolute;inset:0;transition:filter var(--duration) var(--ease),transform var(--duration) var(--ease)}
.ih-19__img--1{background:linear-gradient(135deg,#0f0c29,#312e81,#4338ca)}
.ih-19__img--2{background:linear-gradient(135deg,#042f2e,#065f46,#059669)}
.ih-19__img--3{background:linear-gradient(135deg,#3b0764,#7e22ce,#a855f7)}
.ih-19__img--4{background:linear-gradient(135deg,#1c1003,#92400e,#d97706)}
.ih-19__img--5{background:linear-gradient(135deg,#0c1445,#1e3a8a,#2563eb)}
.ih-19__img--6{background:linear-gradient(135deg,#1a0010,#9d174d,#e11d48)}
.ih-19__card:hover .ih-19__img{filter:brightness(0.4);transform:scale(1.06)}
.ih-19__img-content{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.ih-19__thumb{font-size:40px;opacity:0.4;transition:opacity var(--duration) var(--ease), transform var(--duration) var(--ease)}
.ih-19__card:hover .ih-19__thumb{opacity:0;transform:scale(0.7)}
/* The center icon — scales in from 0 */
.ih-19__icon-wrap{
position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
opacity:0;transform:scale(0.5) rotate(-20deg);
transition:opacity var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.ih-19__card:hover .ih-19__icon-wrap{opacity:1;transform:scale(1) rotate(0deg)}
.ih-19__icon-btn{
width:52px;height:52px;border-radius:50%;
background:rgba(255,255,255,0.12);
border:2px solid rgba(255,255,255,0.25);
backdrop-filter:blur(8px);
display:flex;align-items:center;justify-content:center;
font-size:22px;
transition:background 0.2s ease, transform 0.2s ease;
}
.ih-19__card:hover .ih-19__icon-btn:hover{background:rgba(255,255,255,0.22);transform:scale(1.1)}
/* Bottom strip */
.ih-19__strip{
position:absolute;bottom:0;left:0;right:0;padding:8px 10px;
background:linear-gradient(to top,rgba(0,0,0,0.8),transparent);
display:flex;align-items:center;justify-content:space-between;
}
.ih-19__title{font-size:11px;font-weight:700;color:var(--text)}
.ih-19__views{font-size:10px;color:var(--muted)}
@media(prefers-reduced-motion:reduce){.ih-19__img,.ih-19__thumb,.ih-19__icon-wrap{transition:none}.ih-19__icon-wrap{opacity:1;transform:none}}How this works
The icon wrapper starts at opacity: 0; transform: scale(0.5) rotate(-20deg) and transitions to natural size on hover. The image element simultaneously receives filter: brightness(0.4) to darken it, providing contrast for the white icon. The icon is centred using position: absolute; inset: 0; display: flex; align-items: center; justify-content: center — no manual offsets needed.
The small rotational component in the starting state (rotate(-20deg)) gives the icon entrance a spinning-in quality that stops exactly at 0 degrees. The spring easing cubic-bezier(0.16, 1, 0.3, 1) combined with scale(0.5) → scale(1) produces an elastic "pop" as the icon materialises at the centre.
Customize
- Change the icon per card by placing different emoji or SVG in each
.icon-btnelement — the size, transition, and positioning remain the same. - Add a tooltip label below the icon using an absolutely-positioned span that also fades in with a slight delay (
transition-delay: 0.1s). - For video thumbnails, replace the darkening filter with a subtle blur:
filter: blur(2px) brightness(0.7)for a soft depth-of-field focus effect. - Add a
:hoverstate on the icon button itself (not just the card) that scales it further toscale(1.12)for an extra micro-interaction layer. - Use an SVG icon inside the button instead of emoji for sharper rendering at all DPI levels and easier colour control via
fill: currentColor.
Watch out for
- Setting
filter: brightness()on an image that containsposition: fixedchildren will clip those children to the filtered element's bounds — ensure no fixed children exist inside filtered cards. - The
scale(0.5) rotate(-20deg)starting transform compounds the two functions — the order matters:scale(0.5) rotate(-20deg)is NOT the same asrotate(-20deg) scale(0.5). Always apply scale first. - On Firefox, the spring easing
cubic-bezier(0.16, 1, 0.3, 1)can slightly overshoot on the icon and cause a brief clip against the card edge — reduce the scale start to0.6if this occurs.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 51+ | 9+ | 36+ | 51+ |
Uses only CSS transforms, filter, and opacity — universally supported in all modern browsers without prefixes.