Web InnoventixFreeCode

Saturate Pop Effect

Original · free

Muted image saturates and pops on hover.

byWeb InnoventixReact + Tailwind
saturatepopimageeffect
Open

Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.

npx shadcn@latest add https://webinnoventix.com/r/imgfx-saturate-pop.json
imgfx-saturate-pop.tsx
"use client";

const photos = [
  {
    src: "/img/gallery/g07.webp",
    alt: "Sunlit market stall stacked with fresh produce",
    caption: "Market",
  },
  {
    src: "/img/gallery/g14.webp",
    alt: "Coastal cliffs meeting turquoise water at midday",
    caption: "Coast",
  },
  {
    src: "/img/gallery/g22.webp",
    alt: "Neon-lit city street reflected in wet pavement",
    caption: "Nightfall",
  },
];

export default function ImgfxSaturatePop() {
  return (
    <section className="relative w-full bg-neutral-50 px-6 py-20 dark:bg-neutral-950 sm:px-10 sm:py-28">
      <style>{`
        .satpop-card img {
          filter: saturate(0.35) brightness(0.94) contrast(0.96);
          transition:
            filter 600ms cubic-bezier(0.22, 1, 0.36, 1),
            transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
          will-change: filter, transform;
        }
        .satpop-card:hover img,
        .satpop-card:focus-within img {
          filter: saturate(1.45) brightness(1.04) contrast(1.06);
          transform: scale(1.05);
        }
        .satpop-ring {
          transition: opacity 600ms cubic-bezier(0.22, 1, 0.36, 1);
          opacity: 0;
        }
        .satpop-card:hover .satpop-ring,
        .satpop-card:focus-within .satpop-ring {
          opacity: 1;
        }
        @media (prefers-reduced-motion: reduce) {
          .satpop-card img,
          .satpop-ring {
            transition: none;
          }
          .satpop-card:hover img,
          .satpop-card:focus-within img {
            transform: none;
          }
        }
      `}</style>

      <div className="mx-auto max-w-5xl">
        <div className="mb-12 text-center">
          <p className="mb-3 text-xs font-semibold uppercase tracking-[0.2em] text-indigo-600 dark:text-indigo-400">
            Image Effect / Saturate Pop
          </p>
          <h2 className="text-balance text-3xl font-semibold tracking-tight text-neutral-900 dark:text-neutral-50 sm:text-4xl">
            Muted until you look closer
          </h2>
          <p className="mx-auto mt-4 max-w-md text-pretty text-sm text-neutral-500 dark:text-neutral-400">
            Each frame rests desaturated and calm. Hover or focus to let the
            color bloom back in.
          </p>
        </div>

        <div className="grid grid-cols-1 gap-6 sm:grid-cols-3">
          {photos.map((photo) => (
            <figure
              key={photo.src}
              tabIndex={0}
              className="satpop-card group relative aspect-[4/5] overflow-hidden rounded-2xl bg-neutral-200 outline-none ring-1 ring-neutral-200 focus-visible:ring-2 focus-visible:ring-indigo-500 dark:bg-neutral-800 dark:ring-neutral-800"
            >
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img
                src={photo.src}
                alt={photo.alt}
                loading="lazy"
                draggable={false}
                className="h-full w-full object-cover"
              />

              <div
                aria-hidden="true"
                className="satpop-ring pointer-events-none absolute inset-0 rounded-2xl ring-2 ring-inset ring-indigo-400/70 dark:ring-indigo-300/60"
              />

              <figcaption className="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent p-4">
                <span className="text-sm font-medium text-white/95">
                  {photo.caption}
                </span>
              </figcaption>
            </figure>
          ))}
        </div>

        <p className="mt-8 text-center text-xs font-medium uppercase tracking-[0.16em] text-neutral-400 dark:text-neutral-600">
          Hover or focus to reveal the color
        </p>
      </div>
    </section>
  );
}

Dependencies

None (React + Tailwind only).

Licence

Built by Web Innoventix. Free for personal and commercial use, no attribution required.

Built by Web Innoventix

Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.

Get a free quote

Similar components

Browse all →