ResponsiveZoom

Adaptive image zoom that automatically switches between inline zoom (desktop) and full-screen viewer (tablets) based on device capabilities.

Demo

Try interacting with the image below. On desktop, click to zoom in 2x. On tablets, tap to open a full-screen viewer with pinch-to-zoom. On phones, zoom is disabled.

Loading playground...

Features

ResponsiveZoom automatically detects device capabilities and provides the optimal zoom experience. No manual device detection needed!

Desktop

  • ✓ Custom zoom cursor (±)
  • ✓ Click to zoom in/out (2x)
  • ✓ Zoom follows mouse position
  • ✓ Smooth transform transitions
  • ✓ Keyboard accessible

Tablets

  • ✓ Auto-opens full-screen viewer
  • ✓ Native pinch-to-zoom
  • ✓ Swipe between images
  • ✓ Optimized touch experience

Phones

  • ✓ Zoom disabled
  • ✓ Normal scrolling behavior
  • ✓ Swipe through carousel
  • ✓ No accidental zooms

Additional Features

  • ✓ Automatic device detection (no props needed!)
  • ✓ Screen reader announcements
  • ✓ ARIA labels for accessibility
  • ✓ Transform origin based on click position
  • ✓ No layout shift when zooming
  • ✓ Works with any child component

How It Works

ResponsiveZoom combines ZoomOverlay and EnhancedImageViewer into a single component that automatically adapts to the device:

1. Desktop (non-touch devices)

Shows a custom cursor with + or - icon. On click, applies a CSS transform: scale(2) centered at the cursor position. As you move the mouse, the transform origin updates to follow your cursor for smooth panning.

2. Tablets (large touch devices, 768px+)

On tap, automatically opens a full-screen EnhancedImageViewer with native pinch-to-zoom support. Perfect for iPad and other tablets where inline zoom isn't ideal.

3. Phones (small touch devices, <768px)

Click handlers are disabled completely. The image behaves as a normal element, allowing users to scroll and swipe through a carousel without accidentally triggering zoom.

Code

Simple usage - device detection is automatic!

Multiple Images

When using multiple images, pass the correct imageIndex to each ResponsiveZoom wrapper so the enhanced viewer knows which image to show.

ResponsiveZoom Props

imageIndexnumberrequired
Index of the image in a gallery/carousel. Used to track which image is being viewed when opening the enhanced viewer.
childrenReactNoderequired
The image element to wrap with zoom functionality. Typically an img or ProductImage component.
classNamestring
CSS classes to apply to the wrapper element.
styleReact.CSSProperties
Inline styles to apply to the wrapper element.

Installation

ResponsiveZoom is available in @merch/ui. It combines ZoomOverlay and EnhancedImageViewer with automatic device detection.

npm install @merch/ui

Install @merch/ui to get ResponsiveZoom and all related components.

import { ResponsiveZoom } from "@merch/ui";