Web InnoventixFreeCode

Blur Sharp Effect

Original · free

Blurred image sharpens on hover.

byWeb InnoventixReact + Tailwind
blursharpimageeffect
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-blur-sharp.json
imgfx-blur-sharp.tsx
"use client";

import { useState } from "react";

type Shot = {
  src: string;
  alt: string;
  label: string;
  place: string;
};

const SHOTS: Shot[] = [
  {
    src: "/img/gallery/g07.webp",
    alt: "Sunlit mountain ridge fading into layered haze",
    label: "Ridgeline",
    place: "Dawn, high country",
  },
  {
    src: "/img/gallery/g18.webp",
    alt: "Quiet city street reflected in wet evening pavement",
    label: "After rain",
    place: "Old town, dusk",
  },
  {
    src: "/img/gallery/g24.webp",
    alt: "Close portrait of wildflowers catching low golden light",
    label: "Field study",
    place: "Late summer",
  },
];

export default function ImgfxBlurSharp() {
  const [active, setActive] = useState<number | null>(null);

  return (
    <section className="relative w-full overflow-hidden bg-neutral-50 px-6 py-20 sm:py-28 dark:bg-neutral-950">
      <style>{`
        .ibs-fx {
          filter: blur(14px) saturate(0.8) brightness(0.94);
          transform: scale(1.06);
          transition:
            filter 620ms cubic-bezier(0.22, 1, 0.36, 1),
            transform 620ms cubic-bezier(0.22, 1, 0.36, 1);
          will-change: filter, transform;
        }
        .ibs-card:hover .ibs-fx,
        .ibs-card:focus-visible .ibs-fx,
        .ibs-card:focus-within .ibs-fx {
          filter: blur(0) saturate(1.05) brightness(1);
          transform: scale(1);
        }
        .ibs-veil {
          opacity: 1;
          transition: opacity 620ms cubic-bezier(0.22, 1, 0.36, 1);
        }
        .ibs-card:hover .ibs-veil,
        .ibs-card:focus-visible .ibs-veil,
        .ibs-card:focus-within .ibs-veil {
          opacity: 0;
        }
        .ibs-cap {
          transform: translateY(6px);
          opacity: 0;
          transition:
            opacity 480ms ease,
            transform 480ms cubic-bezier(0.22, 1, 0.36, 1);
        }
        .ibs-card:hover .ibs-cap,
        .ibs-card:focus-visible .ibs-cap,
        .ibs-card:focus-within .ibs-cap {
          transform: translateY(0);
          opacity: 1;
        }
        @media (prefers-reduced-motion: reduce) {
          .ibs-fx,
          .ibs-veil,
          .ibs-cap {
            transition-duration: 1ms;
          }
          .ibs-fx {
            filter: blur(6px) saturate(0.9);
            transform: none;
          }
        }
      `}</style>

      <div className="mx-auto max-w-5xl">
        <div className="mb-12 text-center">
          <p className="text-xs font-semibold uppercase tracking-[0.25em] text-indigo-600 dark:text-indigo-400">
            Image Effect
          </p>
          <h2 className="mt-3 text-3xl font-semibold tracking-tight text-neutral-900 sm:text-4xl dark:text-neutral-50">
            Pull it into focus
          </h2>
          <p className="mx-auto mt-3 max-w-md text-sm text-neutral-500 dark:text-neutral-400">
            Each frame rests in soft blur until you look closer. Hover or tab to
            a photo and it sharpens.
          </p>
        </div>

        <ul className="grid grid-cols-1 gap-6 sm:grid-cols-3">
          {SHOTS.map((shot, i) => (
            <li key={shot.src}>
              <button
                type="button"
                onFocus={() => setActive(i)}
                onBlur={() => setActive(null)}
                onMouseEnter={() => setActive(i)}
                onMouseLeave={() => setActive(null)}
                aria-pressed={active === i}
                aria-label={`Sharpen photo: ${shot.label} — ${shot.place}`}
                className="ibs-card group relative block w-full overflow-hidden rounded-2xl bg-neutral-200 shadow-sm outline-none ring-1 ring-neutral-900/5 transition-shadow duration-500 hover:shadow-xl focus-visible:ring-2 focus-visible:ring-indigo-500 dark:bg-neutral-800 dark:ring-white/10"
              >
                <div className="relative aspect-[3/4] w-full">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={shot.src}
                    alt={shot.alt}
                    loading="lazy"
                    draggable={false}
                    className="ibs-fx absolute inset-0 h-full w-full object-cover"
                  />

                  <div
                    aria-hidden="true"
                    className="ibs-veil pointer-events-none absolute inset-0 bg-gradient-to-t from-neutral-900/50 via-neutral-900/10 to-transparent dark:from-neutral-950/70"
                  />

                  <div className="pointer-events-none absolute inset-x-0 top-0 flex justify-end p-3">
                    <span className="ibs-veil rounded-full bg-white/85 px-2.5 py-1 text-[10px] font-semibold uppercase tracking-wider text-neutral-700 backdrop-blur dark:bg-neutral-900/80 dark:text-neutral-200">
                      Blurred
                    </span>
                  </div>

                  <div className="pointer-events-none absolute inset-x-0 bottom-0 p-4 text-left">
                    <div className="ibs-cap">
                      <p className="text-sm font-semibold text-white drop-shadow">
                        {shot.label}
                      </p>
                      <p className="text-xs text-white/80 drop-shadow">
                        {shot.place}
                      </p>
                    </div>
                  </div>
                </div>
              </button>
            </li>
          ))}
        </ul>

        <p className="mt-10 text-center text-xs uppercase tracking-[0.2em] text-neutral-400 dark:text-neutral-600">
          Hover to reveal
        </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 →