Cards✨ Premium

Image Zoom

Pure CSS — hovering the container triggers scale(1.15) on the image, clipped by overflow:hidden; a semi-transparent scrim fades in alongside.

CSSHoverImage

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Cards has 41 effects, including 6 free. Explore the category →

3 usage examples

Editorial gallery — Article grid with thumbnails — Image Zoom example 1

① Editorial gallery — Article grid with thumbnails

WhenA blog or magazine displays articles in a 3-column grid, each card combining a photo and a title.
WhyThe subtle zoom signals that the card is clickable without extra icons or borders. The hover scrim improves title readability with a dark overlay.
Settingsscale(1.12) for a subtle zoom, transition 0.4s, scrim rgba(0,0,0,0.45) for bright photos.
Product catalogue — E-commerce card with name and price — Image Zoom example 2

② Product catalogue — E-commerce card with name and price

WhenA shop displays products as portrait tiles: full-bleed photo at the top, name and price below.
WhyThe zoom showcases the product on hover and draws the eye to the photo without JS or a library. Compatible with any CMS or framework.
Settingsscale(1.10), transition 0.6s ease-in-out for a premium feel; overlay hidden (remove .zoom-overlay) to keep the price block visible.
Portfolio — Project tiles in a 2×2 grid — Image Zoom example 3

③ Portfolio — Project tiles in a 2×2 grid

WhenA portfolio or agency presents its work in a 2×2 grid, each tile covering all available space.
WhyThe zoom creates depth and an inviting feel. The overlay shows the project name on hover — zero JS, zero layout reflow.
Settingsscale(1.20) for a dramatic effect on large tiles, overlay rgba(0,0,0,0.55) with project name in white centred, transition 0.5s.

How it works

The effect relies on a CSS pair. The card carries overflow:hidden: when the image scales up it overflows logically, but is visually clipped to the card edges. Hovering (:hover img) applies transform:scale(1.15), animated by transition:transform .5s. No layout change occurs — the card does not move, only the image pixels are scaled.

An overlay layer (.zoom-overlay) is positioned absolute; inset:0 with opacity:0 at rest. On hover it reaches opacity:1 via an independent transition (opacity .3s), faster than the zoom — this speed offset gives the fade a snappier feel. The rgba(0,0,0,0.3) backdrop and centred text live entirely in HTML, with no JavaScript.

No JavaScript is involved. The effect applies to any <img> with object-fit:cover inside a fixed-size container — changing the card's size is enough; the zoom stays proportional.

Accessibility

  • prefers-reduced-motion ABSENT: no @media (prefers-reduced-motion:reduce) rule in the code — the transform .5s transition runs even when the OS signals a motion-reduction preference. Add manually: @media (prefers-reduced-motion:reduce) { .card-image-zoom img { transition:none } }.
  • :focus-within absent: zoom triggers on :hover only. A keyboard user tabbing to the card does not see the zoom. Add .card-image-zoom:focus-within img { transform:scale(1.15) } for keyboard coverage.
  • The alt attribute is present in the demo code (alt="Mountain") — replace with a real description in production for screen reader users.
  • Overlay contrast: rgba(0,0,0,0.3) background + white text — ratio ≈ 7:1 on a mid-dark background, WCAG AA compliant.
  • The card is a <div> without role or aria-label — if clickable (link to an article or product), use a native <a> or add role="button" and tabindex="0".

Browser compatibility

Uses only CSS3: transform, transition, overflow, object-fit. No JS or external dependency.

Chrome 45+✓ Full
Firefox 41+✓ Full
Safari 9+✓ Full
Edge 18+✓ Full
Mobile iOS✓ Touch partial
Android Chrome✓ Full

Without transition support, the hover state changes instantly but remains functional. Without object-fit (very old browsers), the image may distort — mitigate with fixed width/height on the <img> element.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="card-demo card-image-zoom">
  <img src="your-image.jpg" alt="Image description">

  <!-- Optional: scrim + hover text -->
  <div class="zoom-overlay">
    <span>Optional text</span>
  </div>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
scale(1.15) 1.15 Zoom factor on hover. 1.08 = very subtle, 1.15 = standard, 1.25 = dramatic. Edit in the .card-image-zoom:hover img rule.
transition: transform .5s .5s Zoom animation duration. 0.3s = snappy, 0.5s = smooth, 0.8s = cinematic. Edit in .card-image-zoom img.
rgba(0,0,0,.3) .3 Scrim background opacity on hover. 0 = invisible (remove the overlay block), 0.5 = clearly visible. Edit in .zoom-overlay.
transition: opacity .3s .3s Scrim fade duration, independent from the zoom duration. Differentiate the two for a temporal stagger effect.
--radius-xl 1rem CSS variable — card corner radius. 0 = square, 0.5rem = slight, 1.5rem = very rounded.
--bg-card #12121a CSS variable — card background visible while the image loads or if it fails.

FAQ

No — there is no CSS variable or data- attribute exposed. The value scale(1.15) is a constant in the .card-image-zoom:hover img rule. Edit it directly in your stylesheet or override with a more specific selector (.my-card.card-image-zoom:hover img { transform:scale(1.20) }).
On mobile, :hover behaves differently by browser: a tap may trigger the hover state on iOS Safari (persisting until the next tap elsewhere), but not reliably on Android Chrome. For consistent touch behavior, complement with :focus-within or add touchstart/touchend JS listeners.
Remove the <div class="zoom-overlay"> from the HTML — the image zoom works independently of the overlay. You can also keep the block and add display:none in your CSS, then reveal it dynamically via JS if needed.