Scaling an image with backdrop 26th July 2024

Motivation

While building a landing page for work, I had to include a couple of images of the product. The app is an enterprise application with lots happening on it and a 1/4 screen width screenshot wasn’t going to cut it. While the screenshot looked good on the site, the text content of the screenshot was barely visible. So, to provide value to an interested visitor on the site, I wanted to expand the image on hover.

What I did

  1. Figure out if the screen is a desktop
  2. Use tailwind group utility to figure out when to show text/icon that indicates the image is clickable
  3. Use a state variable to hold whether the image is expanded or collapsed and scale accordingly
  4. Add a backdrop that takes up the entire screen but has a zIndex less than the image
  5. If you don’t add flex when the image is expanded, it won’t resize correctly and the scroll position is lost

The result was something like below.

FullScreenImageOnExpand.tsx
export const FullScreenImage: React.FC = () => {
const [expandImage, setExpandImage] = useState(false);
return (
<>
<div
className={`group z-[12] transition-all ease-in-out duration-500 hover:cursor-pointer ${expandImage ? "scale-125 fixed flex origin-center top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" : "mt-6 relative"}`}
onClick={() => {
if (window.screen.width >= 1024) {
setExpandImage(!expandImage);
}
}}
>
<img
id="jang-falls-image"
src={JangFalls}
alt="Image of Jang Falls Tawang District"
className={`rounded-xl mx-auto w-fit h-auto peer`}
/>
<div className="absolute top-0 w-full h-full lg:group-hover:flex text-black bg-opacity-50 hidden">
<p className="m-auto font-bold">
Click to {expandImage ? "collapse" : "expand"}
</p>
</div>
</div>
<div
className={`${
expandImage
? "fixed left-0 top-0 z-[11] h-screen w-screen backdrop-blur-sm"
: "hidden"
}`}
></div>
</>
);
};

There’s one problem with the above. You can still scroll behind the image. Making the body fixed resolves this.

FullScreenImageOnExpand.tsx
useEffect(() => {
if (expandImage) {
document.body.classList.add("overflow-hidden");
} else {
document.body.classList.remove("overflow-hidden");
}
return () => {
document.body.classList.remove("overflow-hidden");
};
}, [expandImage]);

Here’s the final result:

Image of Jang Falls Tawang District