Awesome Open Source
Awesome Open Source


All Contributors npm version npm downloads bundlephobia size Coverage Status

This library is a React.js implementation of's image zoom that allows for images to work together for a β€œzooming” effect and works regardless of parent elements that have overflow: hidden or parents with transform properties.

As an added bonus, it will let you zoom anything (see the Storybook Examples for more).

Blog post announcing v4



$ npm i react-medium-image-zoom


$ yarn add react-medium-image-zoom


<!-- this build only needs React to be already present -->
<script src=""></script>

Basic Usage

Uncontrolled component (default)

Import the component and the CSS, wrap whatever you want to be "zoomable" with this component, and the component will handle it's own state:

import React from 'react'
import Zoom from 'react-medium-image-zoom'
import 'react-medium-image-zoom/dist/styles.css'

const MyComponent = () => (
      alt="that wanaka tree"

export default MyComponent

You can zoom anything, so <picture>, <figure>, and even <div> elements are all valid:

// <picture>
    <source media="(max-width: 800px)" srcSet="/path/to/teAraiPoint.jpg" />
      alt="that wanaka tree"

// <figure>
      alt="that wanaka tree"
  <figcaption>That Wanaka Tree</figcaption>

// <div> that looks like a circle
    aria-label="A blue circle"
      width: 300,
      height: 300,
      borderRadius: '50%',
      backgroundColor: '#0099ff'

Controlled component (Controlled)

Import the Controlled component and the CSS, wrap whatever you want to be "zoomable" with this component and then dictate the zoomed/unzoomed state to the component. Here, we will automatically zoom the component once the image has loaded:

import React, { useCallback, useState } from 'react'
import { Controlled as ControlledZoom } from 'react-medium-image-zoom'
import 'react-medium-image-zoom/dist/styles.css'

const MyComponent = () => {
  const [isZoomed, setIsZoomed] = useState(false)

  const handleImgLoad = useCallback(() => {
  }, [])

  const handleZoomChange = useCallback(shouldZoom => {
  }, [])

  return (
    <ControlledZoom isZoomed={isZoomed} onZoomChange={handleZoomChange}>
        alt="that wanaka tree"

export default MyComponent

The onZoomChange prop accepts a callback that will receive true or false based on events that occur (like click or scroll events) to assist you in determining when to zoom and unzoom the component.

There is also an example in the Storybook Examples of how to use a Controlled component to create a full-screen slideshow gallery.


Both uncontrolled & controlled components

You can pass these options to either the default or controlled components.

Prop Type Required Default Details
closeText String no 'Unzoom Image' Accessible label text for when you want to unzoom
openText String no 'Zoom Image' Accessible label text for when you want to zoom
overlayBgColorEnd String no 'rgba(255, 255, 255, 0.95)' Modal overlay background color at end of zoom
overlayBgColorStart String no 'rgba(255, 255, 255, 0)' Modal overlay background color at start of zoom
portalEl Element no document.body DOM Element to which we will append the zoom modal
scrollableEl Window no window DOM Element to which we will listen for scroll events to determine if we should unzoom
transitionDuration Number no 300 Transition duration in milliseconds for the component to use on zoom and unzoom. Set this to 0 to disable the animation
wrapElement String no 'div' Wrapper element
wrapStyle Object no null Optional style object to pass to the wrapper element. Useful when you want the <Zoom> container to be width: '100%', for example
zoomMargin Number no 0 Offset in pixels the zoomed image should be from the window' boundaries
zoomZindex Number no 2147483647 z-index value for the zoom overlay

Only the controlled component

You can pass these options to only the controlled component.

Prop Type Required Default Details
isZoomed bool yes false Tell the component whether or not it should be zoomed
onZoomChange Function no Function.prototype Listen for hints from the component about when you should zoom (true value) or unzoom (false value)

Migrating From v3 to v4

In v3, you might have code like this:

    src: '/path/to/bridge.jpg',
    alt: 'Golden Gate Bridge',
    className: 'img',
    style: { width: '50em' }
    src: '/path/to/bridge-big.jpg',
    alt: 'Golden Gate Bridge'

In v3, you would pass properties for your normal image that would be zoomed, and you would pass an optional zoomImage that would be a higher quality image that would replace the original image when zoomed.

The problem with v3 was that it tried to assume too many things about what it is you were trying to zoom, and this resulted in overly complex and near-unmaintainable code that had a number of bugs.

In v4, you can zoom the bridge example above like this:

<Zoom zoomMargin={40}>
    alt="Golden Gate Bridge"
    style={{ width: '50em'}}

We've removed the zoomImage functionality (there is an issue for us to consider re-adding something like it), but as it was not a primary use case for many consumers, we opted to ship v4 without it.

Please see the Controlled component (Controlled) section for further documentation regarding controlled components that used the isZoomed, onZoom, and onUnzoom properties.


Thanks goes to these wonderful people (emoji key):

Cameron Bothner

πŸ’» πŸ“– πŸ› πŸ’‘ πŸ€” πŸ‘€ ⚠️

Jeremy Bini

πŸ’» πŸ›


πŸ› πŸ€”

Rajit Singh


Roberto Saccon




Robert Pearce

πŸ’» πŸ’¬ ⚠️ πŸ› πŸ’‘ 🎨 πŸ‘€ πŸ€” πŸ“–

Josh Sloat

πŸ› πŸ’» πŸ’‘ πŸ‘€ πŸ€” πŸ“– 🎨 πŸ’¬



Alex Shelkovskiy


Adrian Bindiu


Kendall Buchanan





πŸ› πŸ’¬

Ludwig Frank

πŸ› πŸ’»


πŸ› πŸ€”

Rosen Tomov


Tom Moor

πŸ’» πŸ›

Johan Preynat

πŸ’» πŸ›

Rahul Gaba

πŸ’» πŸ›

Spencer Davis

πŸ’» πŸ€” πŸ‘€ 🎨



Sean King


Ben Hood

πŸ€” πŸ› πŸ’‘ πŸ‘€





Akshay Kadam (A2K)

πŸ› πŸ€”

Jake Stewart

πŸ› πŸ€”





Sun Knudsen

πŸ’» πŸ› πŸ€” πŸ’‘ πŸ’¬ πŸ‘€ ⚠️ πŸ“–

Douglas Galdino

πŸ’» πŸ“– πŸ› πŸ€” πŸ’‘ πŸ‘€ ⚠️

Mohammed Faragallah

πŸ› πŸ€” πŸ’‘

Youngrok Kim

πŸ’» πŸ›

Nandhagopal Ezhilmaran


This project follows the all-contributors specification. Contributions of any kind welcome!

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
typescript (10,876)Β 
react (5,295)Β 
reactjs (1,055)Β 
zoom (71)Β 
medium (51)Β 
props (26)Β 

Find Open Source By Browsing 7,000 Topics Across 59 Categories

Advertising πŸ“¦Β 10
All Projects
Application Programming Interfaces πŸ“¦Β 124
Applications πŸ“¦Β 192
Artificial Intelligence πŸ“¦Β 78
Blockchain πŸ“¦Β 73
Build Tools πŸ“¦Β 113
Cloud Computing πŸ“¦Β 80
Code Quality πŸ“¦Β 28
Collaboration πŸ“¦Β 32
Command Line Interface πŸ“¦Β 49
Community πŸ“¦Β 83
Companies πŸ“¦Β 60
Compilers πŸ“¦Β 63
Computer Science πŸ“¦Β 80
Configuration Management πŸ“¦Β 42
Content Management πŸ“¦Β 175
Control Flow πŸ“¦Β 213
Data Formats πŸ“¦Β 78
Data Processing πŸ“¦Β 276
Data Storage πŸ“¦Β 135
Economics πŸ“¦Β 64
Frameworks πŸ“¦Β 215
Games πŸ“¦Β 129
Graphics πŸ“¦Β 110
Hardware πŸ“¦Β 152
Integrated Development Environments πŸ“¦Β 49
Learning Resources πŸ“¦Β 166
Legal πŸ“¦Β 29
Libraries πŸ“¦Β 129
Lists Of Projects πŸ“¦Β 22
Machine Learning πŸ“¦Β 347
Mapping πŸ“¦Β 64
Marketing πŸ“¦Β 15
Mathematics πŸ“¦Β 55
Media πŸ“¦Β 239
Messaging πŸ“¦Β 98
Networking πŸ“¦Β 315
Operating Systems πŸ“¦Β 89
Operations πŸ“¦Β 121
Package Managers πŸ“¦Β 55
Programming Languages πŸ“¦Β 245
Runtime Environments πŸ“¦Β 100
Science πŸ“¦Β 42
Security πŸ“¦Β 396
Social Media πŸ“¦Β 27
Software Architecture πŸ“¦Β 72
Software Development πŸ“¦Β 72
Software Performance πŸ“¦Β 58
Software Quality πŸ“¦Β 133
Text Editors πŸ“¦Β 49
Text Processing πŸ“¦Β 136
User Interface πŸ“¦Β 330
User Interface Components πŸ“¦Β 514
Version Control πŸ“¦Β 30
Virtualization πŸ“¦Β 71
Web Browsers πŸ“¦Β 42
Web Servers πŸ“¦Β 26
Web User Interface πŸ“¦Β 210