20 CSS Image Hover Effects18 / 20

Pure CSSMIT licensed

CSS Masonry Gallery Zoom Hover

Pinterest-style column masonry gallery where individual items zoom in on hover without disrupting the column flow via isolated overflow contexts.

Published

Live Demo
Try it

The code

<div class="ih-18">
  <div class="ih-18__masonry">
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--tall ih-18__img--a"></div>
      <span class="ih-18__emoji">🌌</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Cosmos</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--sq ih-18__img--b"></div>
      <span class="ih-18__emoji">🌿</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Flora</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--wide ih-18__img--c"></div>
      <span class="ih-18__emoji">🏜️</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Desert</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--sq ih-18__img--d"></div>
      <span class="ih-18__emoji">🌊</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Ocean</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--tall ih-18__img--e"></div>
      <span class="ih-18__emoji">🌺</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Bloom</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--wide ih-18__img--f"></div>
      <span class="ih-18__emoji">🧊</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Ice</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--wide ih-18__img--g"></div>
      <span class="ih-18__emoji">🔮</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Mystic</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--tall ih-18__img--h"></div>
      <span class="ih-18__emoji">🌲</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Forest</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--sq ih-18__img--a"></div>
      <span class="ih-18__emoji">⭐</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Stars</span></div>
    </div>
  </div>
</div>
.ih-18,
.ih-18 *,
.ih-18 *::before,
.ih-18 *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.ih-18 ::selection {
  background: #f43f5e;
  color: #fff;
}

.ih-18 {
  --accent: #f43f5e;
  --bg: #08080c;
  --text: #f1f5f9;
  --muted: #64748b;
  --duration: 0.4s;
  --ease: cubic-bezier(0.25,0.46,0.45,0.94);
  font-family: system-ui,sans-serif;
  background: var(--bg);
  padding: 32px 24px;
  min-height: 100vh;
}
/* CSS Masonry via columns — no JS layout required */

.ih-18__masonry {
  columns: 3;
  column-gap: 12px;
  max-width: 780px;
  margin: 0 auto;
}

.ih-18__item {
  break-inside: avoid;
  margin-bottom: 12px;
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  /* Isolate so zoom doesn't clip to the column boundary */
  display: block;
}

.ih-18__img {
  display: block;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--duration) var(--ease);
}

.ih-18__item:hover .ih-18__img {
  transform: scale(1.08);
}
/* Heights via padding-top for aspect ratios */

.ih-18__img--tall {
  padding-top: 140%;
}

.ih-18__img--sq {
  padding-top: 100%;
}

.ih-18__img--wide {
  padding-top: 65%;
}

.ih-18__img--a {
  background-image: url('https://picsum.photos/seed/masonry-a/600/600'), linear-gradient(150deg,#1a0533,#4c1d95,#7c3aed);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--b {
  background-image: url('https://picsum.photos/seed/masonry-b/600/600'), linear-gradient(150deg,#042f2e,#065f46,#10b981);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--c {
  background-image: url('https://picsum.photos/seed/masonry-c/600/600'), linear-gradient(150deg,#1c1003,#92400e,#f59e0b);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--d {
  background-image: url('https://picsum.photos/seed/masonry-d/600/600'), linear-gradient(150deg,#0c1445,#1e3a8a,#3b82f6);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--e {
  background-image: url('https://picsum.photos/seed/masonry-e/600/600'), linear-gradient(150deg,#1a0010,#9d174d,#f43f5e);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--f {
  background-image: url('https://picsum.photos/seed/masonry-f/600/600'), linear-gradient(150deg,#082032,#1e3a5f,#0891b2);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--g {
  background-image: url('https://picsum.photos/seed/masonry-g/600/600'), linear-gradient(150deg,#0f0c29,#312e81,#4f46e5);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--h {
  background-image: url('https://picsum.photos/seed/masonry-h/600/600'), linear-gradient(150deg,#052e16,#14532d,#4ade80);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Hover overlay */

.ih-18__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,rgba(0,0,0,0.7) 0%,transparent 60%);
  opacity: 0;
  transition: opacity var(--duration) var(--ease);
  display: flex;
  align-items: flex-end;
  padding: 10px;
}

.ih-18__item:hover .ih-18__overlay {
  opacity: 1;
}

.ih-18__tag {
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  background: rgba(244,63,94,0.7);
  border-radius: 4px;
  padding: 2px 6px;
}

.ih-18__emoji {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  font-size: 36px;
  opacity: 0.3;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .ih-18__img,
    .ih-18__overlay {
    transition: none;
  }

  .ih-18__overlay {
    opacity: 1;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Image Hover Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Masonry Gallery Zoom Hover
Source: https://codefronts.com/motion/css-image-hover-effects/css-masonry-gallery-zoom-hover/

Pinterest-style column masonry gallery where individual items zoom in on hover without disrupting the column flow via isolated overflow contexts.
## HTML
```html
<div class="ih-18">
  <div class="ih-18__masonry">
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--tall ih-18__img--a"></div>
      <span class="ih-18__emoji">🌌</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Cosmos</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--sq ih-18__img--b"></div>
      <span class="ih-18__emoji">🌿</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Flora</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--wide ih-18__img--c"></div>
      <span class="ih-18__emoji">🏜️</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Desert</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--sq ih-18__img--d"></div>
      <span class="ih-18__emoji">🌊</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Ocean</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--tall ih-18__img--e"></div>
      <span class="ih-18__emoji">🌺</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Bloom</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--wide ih-18__img--f"></div>
      <span class="ih-18__emoji">🧊</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Ice</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--wide ih-18__img--g"></div>
      <span class="ih-18__emoji">🔮</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Mystic</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--tall ih-18__img--h"></div>
      <span class="ih-18__emoji">🌲</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Forest</span></div>
    </div>
    <div class="ih-18__item">
      <div class="ih-18__img ih-18__img--sq ih-18__img--a"></div>
      <span class="ih-18__emoji">⭐</span>
      <div class="ih-18__overlay"><span class="ih-18__tag">Stars</span></div>
    </div>
  </div>
</div>
```
## CSS
```css
.ih-18,
.ih-18 *,
.ih-18 *::before,
.ih-18 *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.ih-18 ::selection {
  background: #f43f5e;
  color: #fff;
}

.ih-18 {
  --accent: #f43f5e;
  --bg: #08080c;
  --text: #f1f5f9;
  --muted: #64748b;
  --duration: 0.4s;
  --ease: cubic-bezier(0.25,0.46,0.45,0.94);
  font-family: system-ui,sans-serif;
  background: var(--bg);
  padding: 32px 24px;
  min-height: 100vh;
}
/* CSS Masonry via columns — no JS layout required */

.ih-18__masonry {
  columns: 3;
  column-gap: 12px;
  max-width: 780px;
  margin: 0 auto;
}

.ih-18__item {
  break-inside: avoid;
  margin-bottom: 12px;
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  /* Isolate so zoom doesn't clip to the column boundary */
  display: block;
}

.ih-18__img {
  display: block;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--duration) var(--ease);
}

.ih-18__item:hover .ih-18__img {
  transform: scale(1.08);
}
/* Heights via padding-top for aspect ratios */

.ih-18__img--tall {
  padding-top: 140%;
}

.ih-18__img--sq {
  padding-top: 100%;
}

.ih-18__img--wide {
  padding-top: 65%;
}

.ih-18__img--a {
  background-image: url('https://picsum.photos/seed/masonry-a/600/600'), linear-gradient(150deg,#1a0533,#4c1d95,#7c3aed);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--b {
  background-image: url('https://picsum.photos/seed/masonry-b/600/600'), linear-gradient(150deg,#042f2e,#065f46,#10b981);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--c {
  background-image: url('https://picsum.photos/seed/masonry-c/600/600'), linear-gradient(150deg,#1c1003,#92400e,#f59e0b);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--d {
  background-image: url('https://picsum.photos/seed/masonry-d/600/600'), linear-gradient(150deg,#0c1445,#1e3a8a,#3b82f6);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--e {
  background-image: url('https://picsum.photos/seed/masonry-e/600/600'), linear-gradient(150deg,#1a0010,#9d174d,#f43f5e);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--f {
  background-image: url('https://picsum.photos/seed/masonry-f/600/600'), linear-gradient(150deg,#082032,#1e3a5f,#0891b2);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--g {
  background-image: url('https://picsum.photos/seed/masonry-g/600/600'), linear-gradient(150deg,#0f0c29,#312e81,#4f46e5);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.ih-18__img--h {
  background-image: url('https://picsum.photos/seed/masonry-h/600/600'), linear-gradient(150deg,#052e16,#14532d,#4ade80);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Hover overlay */

.ih-18__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,rgba(0,0,0,0.7) 0%,transparent 60%);
  opacity: 0;
  transition: opacity var(--duration) var(--ease);
  display: flex;
  align-items: flex-end;
  padding: 10px;
}

.ih-18__item:hover .ih-18__overlay {
  opacity: 1;
}

.ih-18__tag {
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  background: rgba(244,63,94,0.7);
  border-radius: 4px;
  padding: 2px 6px;
}

.ih-18__emoji {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  font-size: 36px;
  opacity: 0.3;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .ih-18__img,
    .ih-18__overlay {
    transition: none;
  }

  .ih-18__overlay {
    opacity: 1;
  }
}
```

How this works

Masonry layout is achieved with CSS columns: 3 and break-inside: avoid on each item — no JavaScript layout engine required. Each item's image uses transform: scale(1.08) on hover for the zoom. The item itself has overflow: hidden and border-radius to clip the zoom within the card boundary, while the column layout is unaffected because transform does not participate in layout flow.

A hover overlay with opacity: 0 → 1 transition provides a gradient and tag label. Because each item is display: block with break-inside: avoid, the column algorithm distributes them across columns without fragmenting a card mid-element.

Make it yours

  • Vary the column count responsively: @media (max-width: 600px) { .masonry { columns: 2 } }.
  • Add a column-gap value to control horizontal spacing, and margin-bottom on items for vertical spacing.
  • Use aspect-ratio instead of padding-top hacks for cleaner aspect ratio control in modern browsers.
  • Add will-change: transform on .item:hover img to hint to the browser to promote hovered images to their own GPU layer.
  • Combine with a lightbox: add a data-src attribute and intercept clicks to open a fullscreen modal without leaving the masonry page.

Gotchas — read before shipping

  • The CSS columns masonry approach does NOT support reordering items — columns fill top-to-bottom. For true Pinterest-style reordering (by height), JavaScript masonry libraries are required.
  • Items with break-inside: avoid that are taller than the column will overflow the column boundary on some rendering engines — set a max-height if item heights are unpredictable.
  • In Firefox, columns with overflow: hidden children can exhibit a 1px gap between columns — use a negative margin or column-rule to mask it.

Browser support

ChromeSafariFirefoxEdge
50+9+52+50+

CSS multi-column layout is broadly supported. The masonry-specific column fill behaviour may differ slightly between engines.

Techniques used in this demo

Search CodeFronts

Loading…