Image Popup/Overlay Viewer with Zoom In and Out using CSS and JavaScript

In this tutorial, you can learn to create an Image Overlay or Popup Viewer using HTML, CSS, and JavaScript. The tutorial aims to provide students and beginners with a reference for learning how to build a useful component of a website or web application using CSS and JS. Here, I have provided a simple program that I created that demonstrates the creation of an Image Overlay or Popup Viewer with zoom and drag features.

What is an Image Overlay or Popup Viewer?

The Image Overlay or Popup Viewer is a website or web application component for displaying or showing the image in a larger size. This component allows the users to view the images shown on the web page in larger sizes and overlays on the web page screen. The image viewer is often implemented with zoom and drag functionality.

How to create an Image Overlay or Popup Viewer?

The Image Overlay or Popup Viewer can be achieved using CSS and JavaScript. sing CSS, we can design the image viewer that overlays on the whole page and display the image on a larger scale. Using the JavaScript event listeners and some methods, APIs, and functionality can help us to display the selected image in the Image viewer. Check out the sample web page script that I have provided below to understand more about how to create the Image Overlay or Popup Viewer.

About the Sample Program

The sample source code provided below results in a simple web page that serves as an Image or Website Gallery page. It contains multiple images that are shown in grid view and smaller scale. Users can view the image on a larger scale. When viewing the image on the overlay viewer, users can also zoom in and out of the image.

Page Interface

Here's the HTML file script of the program that contains the page layout and the sample Image and their container. The file is known as index.html.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.     <meta charset="UTF-8">
  4.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>CSS/JS - Image Popup/Overlay Viewer</title>
  7.     <link rel="preconnect" href="https://fonts.googleapis.com">
  8.     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  9.     <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" />
  10.     <link rel="stylesheet" href="style.css">
  11.  
  12. </head>
  13.     <!-- Image Overlay Wrapper -->
  14.     <div id="image-overlay-wrapper">
  15.         <a href="#" class="image-overlay-backdrop"></a>
  16.         <div class="image-overlay-content">
  17.             <div class="image-overlay-viewer"></div>
  18.             <div class="image-overlay-buttons">
  19.                 <a href="#" class="image-overlay-close-btn">
  20.                     <span class="material-symbols-outlined">close</span>
  21.                 </a>
  22.                 <a href="#" class="image-overlay-zoomin-btn">
  23.                     <span class="material-symbols-outlined">zoom_in</span>
  24.                 </a>
  25.                 <a href="#" class="image-overlay-zoomout-btn">
  26.                     <span class="material-symbols-outlined">zoom_out</span>
  27.                 </a>
  28.             </div>
  29.         </div>
  30.     </div>
  31.     <!-- Image Overlay Wrapper -->
  32.  
  33.     <div id="wrapper">
  34.         <div class="page-title">Image Popup/Overlay Viewer using JavaScript</div>
  35.         <hr style="width:25px">
  36.         <div id="image-wrapper">
  37.             <div class="image-item">
  38.                 <img src="images/image-1.jpg" alt="Sample Image 1">
  39.             </div>
  40.             <div class="image-item">
  41.                 <img src="images/image-2.jpg" alt="Sample Image 2">
  42.             </div>
  43.             <div class="image-item">
  44.                 <img src="images/image-3.jpg" alt="Sample Image 3">
  45.             </div>
  46.             <div class="image-item">
  47.                 <img src="images/image-4.jpg" alt="Sample Image 4">
  48.             </div>
  49.         </div>
  50.     </div>
  51.     <script src="script.js"></script>
  52. </body>
  53. </html>

Stylesheet

Here's the CSS file script named style.css. The script contains the CSS style codes of the page layout and Image overlay viewer design.

  1. @import url('https://fonts.googleapis.com/css2?family=Rubik&display=swap');
  2. @import url('https://fonts.googleapis.com/css2?family=Courgette&family=Secular+One&display=swap" rel="stylesheet');
  3. :root{
  4.     --secular-font: 'Secular One', sans-serif;
  5.     --satisfy-font: 'Satisfy', cursive;
  6. }
  7. *{
  8.     box-sizing: border-box;
  9. }
  10. body *{
  11.     font-family: 'Rubik', sans-serif;
  12. }
  13. /**
  14. Page Design
  15. */
  16. body,
  17. html{
  18.     height: 100%;
  19.     width: 100%;
  20.     margin: 0;
  21.     padding: 0;
  22. }
  23. body{
  24.     background-color: #789395;
  25. }
  26. /* Page Wrapper */
  27. #wrapper{
  28.     width: 100%;
  29.     min-height: 100%;
  30.     display: flex;
  31.     flex-direction: column;
  32.     align-items: center;
  33.     justify-content: center;
  34.     padding: 3em 0;
  35. }
  36. .page-title{
  37.     font-size: 35px;
  38.     font-family: var(--secular-font);
  39.     letter-spacing: 2px;
  40.     text-align: center;
  41.     color:#fff;
  42.     text-shadow: 0px 0px 5px #7070709c;
  43. }
  44. /* Image Wrapper */
  45. #image-wrapper{
  46.     width: 760px;
  47.     margin: auto;
  48.     display: flex;
  49.     flex-wrap: wrap;
  50.     justify-content: space-evenly;
  51. }
  52. @media (max-width:760px){
  53.     #image-wrapper{
  54.         width: 100%;
  55.     }
  56. }
  57. #image-wrapper .image-item{
  58.     width:48%;
  59.     height:35vh;
  60.     margin-bottom: 1em;
  61.     overflow: hidden;
  62.     cursor: pointer;
  63. }
  64.  
  65. #image-wrapper .image-item>img{
  66.     height: 100%;
  67.     width: 100%;
  68.     object-fit: cover;
  69.     transition: all .3s ease-in-out;
  70. }
  71. #image-wrapper .image-item:hover>img{
  72.     transform: scale(1.2);
  73. }
  74.  
  75. /* Image Overlay */
  76. #image-overlay-wrapper{
  77.     position: fixed;
  78.     width: 100%;
  79.     height: 100%;
  80.     top: 0;
  81.     left: 0;
  82.     flex-direction: column;
  83.     align-items: center;
  84.     justify-content: center;
  85.     overflow: hidden;
  86.     z-index: 99;
  87.     display: hidden;
  88.     opacity: 0;
  89.     animation:fade-out .8s ease-in-out -10s forwards;
  90. }
  91. #image-overlay-wrapper .image-overlay-backdrop{
  92.     position: absolute;
  93.     width: 100%;
  94.     height: 100%;
  95.     background-color: #2929299c;
  96.     z-index: 100;
  97. }
  98. #image-overlay-wrapper .image-overlay-content{
  99.     width: 80%;
  100.     min-height: 80%;
  101.     max-height: 95%;
  102.     overflow: hidden;
  103.     background-color: #272727;
  104.     border:1px solid #3e3e3e;
  105.     box-shadow: 0px 0px 7px #525252;
  106.     display: flex;
  107.     z-index: 101;
  108.     filter: blur(7px);
  109.     transition: filter .3s ease-in-out 1s;
  110. }
  111. #image-overlay-wrapper.show{
  112.     display: flex;
  113.     animation:fade .8s ease-in-out forwards;
  114. }
  115. html:has(#image-overlay-wrapper.show){
  116.     overflow: hidden;
  117. }
  118. @keyframes fade {
  119.     0%{
  120.         opacity: 0;
  121.         width: 0%;
  122.         height: 0%;
  123.     }
  124.     100%{
  125.         opacity: 1;
  126.         width: 100%;
  127.         height: 100%;
  128.         top:0;
  129.         left:0;
  130.     }
  131.    
  132. }
  133. @keyframes fade-out {
  134.     0%{
  135.         opacity: 1;
  136.         width: 100%;
  137.         height: 100%;
  138.         top:0;
  139.         left:0;
  140.     }
  141.     100%{
  142.         opacity: 0;
  143.         width: 0%;
  144.         height: 0%;
  145.     }
  146.    
  147. }
  148. @media (max-width:480px) {
  149.     #image-overlay-wrapper .image-overlay-content{
  150.         width: 95%;
  151.         height: 95%;
  152.     }
  153. }
  154. #image-overlay-wrapper.show .image-overlay-content{
  155.     filter: blur(0px);
  156. }
  157.  
  158. #image-overlay-wrapper .image-overlay-viewer{
  159.     position: relative;
  160.     width: 95%;
  161.     height: 100%;
  162.     background-color: #000;
  163.     overflow: hidden;
  164. }
  165. #image-overlay-wrapper .image-overlay-viewer>img{
  166.     position: relative;
  167.     width: 100%;
  168.     height: 100%;
  169.     object-fit: scale-down;
  170.     object-position: center center;
  171.     transition: transform .3s ease-in-out;
  172. }
  173. #image-overlay-wrapper .image-overlay-viewer>img[data-draggable]{
  174.     cursor: grab;
  175. }
  176. #image-overlay-wrapper .image-overlay-buttons{
  177.     width: 5%;
  178.     height: 100%;
  179.     display: flex;
  180.     flex-direction: column;
  181.     flex-wrap:wrap ;
  182. }
  183. #image-overlay-wrapper .image-overlay-buttons>a{
  184.     width: 100%;
  185.     height: 35px;
  186.     text-decoration: none;
  187.     color:#c9c9c9;
  188.     display: flex;
  189.     align-items: center;
  190.     justify-content: center;
  191. }
  192. #image-overlay-wrapper .image-overlay-buttons>a:hover{
  193.     background-color: #f5f5f533;
  194. }
  195. #image-overlay-wrapper .image-overlay-buttons>a[disabled]{
  196.     pointer-events: none;
  197.     cursor: not-allowed;
  198.     color:#838383;
  199. }    

Using the script above will result in something like the following image.

Page Layout

Image Popup/Overlay Viewer using CSS and JS

Image Viewer

Image Popup/Overlay Viewer using CSS and JS

JavaScript

Then, the JS script provided below contains the codes that make the web page viewing, zooming and dragging the image functional. The file is known as script.js.

  1. // Image Items Selector
  2. const imageItems = document.querySelectorAll('.image-item')
  3. // Image Overlay Wrapper Selector
  4. const ImageOverlay = document.getElementById('image-overlay-wrapper')
  5. // Image Overlay Close Button Selector
  6. const ImageOverlayCloseBtn = ImageOverlay.querySelector('.image-overlay-close-btn')
  7. // Image Overlay Backdorp Selector
  8. const ImageOverlayBackdropBtn = ImageOverlay.querySelector('.image-overlay-backdrop')
  9. // Image Overlay Close Zoomin Selector
  10. const ImageOverlayZoomInBtn = ImageOverlay.querySelector('.image-overlay-zoomin-btn')
  11. // Image Overlay Close Zoomout Selector
  12. const ImageOverlayZoomoutBtn = ImageOverlay.querySelector('.image-overlay-zoomout-btn')
  13.  
  14. // maximum zoom in
  15. const ZoomMax = 5;
  16. // Current zoom state
  17. var currentZoom = 1;
  18.  
  19. /**
  20.     * Set Image Viewer as Draggable when zoom in
  21.     */
  22. const makeDraggable = () =>{
  23.     var _image = ImageOverlay.querySelector('.image-overlay-viewer>img')
  24.     if(_image === undefined)
  25.         return false;
  26.     if(currentZoom > 1){
  27.         if(!_image.hasAttribute('data-draggable'))
  28.         _image.setAttribute('data-draggable','')
  29.     }else{
  30.         if(_image.hasAttribute('data-draggable'))
  31.         _image.removeAttribute('data-draggable')
  32.     }
  33. }
  34.  
  35. /**
  36.     * Enable/Disable Zoom Out Button
  37.     */
  38. const disableEnableZoomOut = (e) =>{
  39.     if(e !== undefined)
  40.         e.preventDefault()
  41.         if(currentZoom <= 1){
  42.             if(!ImageOverlayZoomoutBtn.hasAttribute('disabled'))
  43.             ImageOverlayZoomoutBtn.setAttribute('disabled', "")
  44.         }else{
  45.             if(ImageOverlayZoomoutBtn.hasAttribute('disabled'))
  46.             ImageOverlayZoomoutBtn.removeAttribute('disabled')
  47.         }
  48. }
  49.  
  50. /**
  51.     * Enable/Disable Zoom In Button
  52.     */
  53. const disableEnableZoomIn = (e) =>{
  54.     if(e !== undefined)
  55.         e.preventDefault()
  56.         if(currentZoom >= ZoomMax){
  57.             if(!ImageOverlayZoomInBtn.hasAttribute('disabled'))
  58.             ImageOverlayZoomInBtn.setAttribute('disabled', "")
  59.         }else{
  60.             if(ImageOverlayZoomInBtn.hasAttribute('disabled'))
  61.             ImageOverlayZoomInBtn.removeAttribute('disabled')
  62.         }
  63. }
  64.  
  65. disableEnableZoomOut()
  66. disableEnableZoomIn()
  67.  
  68. /**
  69.     * Zoom In Image when Zoom In Button is clicked
  70.     */
  71. ImageOverlayZoomInBtn.addEventListener('click',e=>{
  72.     e.preventDefault()
  73.     var _image = ImageOverlay.querySelector('.image-overlay-viewer>img')
  74.     if(_image === undefined || currentZoom == ZoomMax)
  75.         return false;
  76.     currentZoom++;
  77.     var _newscale = (currentZoom == 0) ? 1 : `${currentZoom}`
  78.     _image.style.transform = `scale(${_newscale})`
  79.     disableEnableZoomOut()
  80.     disableEnableZoomIn()
  81.     makeDraggable()
  82. })
  83.  
  84. /**
  85.     * Zoom Out Image when Zoom Out Button is clicked
  86.     */
  87. ImageOverlayZoomoutBtn.addEventListener('click',e=>{
  88.     e.preventDefault()
  89.     var _image = ImageOverlay.querySelector('.image-overlay-viewer>img')
  90.     if(_image === undefined || currentZoom <= 1)
  91.         return false;
  92.     currentZoom--;
  93.     var _newscale = (currentZoom == 0) ? 1 : `${currentZoom}`
  94.     _image.style.transform = `scale(${_newscale})`
  95.     disableEnableZoomOut()
  96.     disableEnableZoomIn()
  97.     makeDraggable()
  98.     if(currentZoom == 1)
  99.     _image.style.objectPosition = `center center`
  100.  
  101. })
  102.  
  103. //remove transition delay
  104. setTimeout(()=>{
  105.     ImageOverlay.style.animationDelay = '0s'
  106. },1000)
  107.  
  108. /**
  109.     * Show Image Viewer Overlay
  110.     */
  111. const showImageOverlay = () =>{
  112.     if(!ImageOverlay.classList.contains('show'))
  113.         ImageOverlay.classList.add('show');
  114. }
  115. /**
  116.     * Close Image Viewer Overlay
  117.     */
  118. const closeImageOverlay = (e) =>{
  119.     if(e !== undefined)
  120.         e.preventDefault();
  121.     if(ImageOverlay.classList.contains('show'))
  122.         ImageOverlay.classList.remove('show');
  123.     if(ImageOverlay.querySelector('.image-overlay-viewer>img') !== undefined)
  124.     ImageOverlay.querySelector('.image-overlay-viewer>img').remove()
  125.     currentZoom = 1;
  126.     disableEnableZoomOut()
  127.     disableEnableZoomIn()
  128. }
  129.  
  130. /**
  131.     * Event to allow Image to move
  132.     */
  133. const imageDraggable = () =>{
  134.     var _image = ImageOverlay.querySelector('.image-overlay-viewer>img')
  135.    
  136.     var currentXpos = 0,
  137.         currentYpos = 0,
  138.         cursorXstart = _image.x,
  139.         cursorYstart = _image.x,
  140.         _newX,
  141.         _newY;
  142.  
  143.     function dragging(e){
  144.         var cursorX = e.layerX
  145.         var cursorY = e.layerY
  146.         _newX = currentXpos + (cursorX - cursorXstart)
  147.         _newY = currentYpos + (cursorY - cursorYstart)
  148.         _image.style.objectPosition = `${_newX}px ${_newY}px`
  149.     }
  150.     function startDragging(e){
  151.         if(e !== undefined)
  152.             e.preventDefault();
  153.         if(!_image.hasAttribute('data-draggable'))
  154.         return false;
  155.         cursorXstart = e.layerX
  156.         cursorYstart = e.layerY
  157.         _image.addEventListener('mousemove', dragging)
  158.         _image.addEventListener('mouseup', ()=>{
  159.             _image.removeEventListener('mousemove', dragging)
  160.             currentXpos = _newX;
  161.             currentYpos = _newY;
  162.         })
  163.     }
  164.     _image.addEventListener('mousedown', startDragging)
  165. }
  166.  
  167. /**
  168.     * Show Image when image items are clicked
  169.     */
  170. imageItems.forEach(item=>{
  171.     item.addEventListener("click", e =>{
  172.         var _left = item.offsetLeft
  173.         var _top = item.offsetTop
  174.         var _width =  item.clientWidth
  175.         var _height =  item.clientHeight
  176.  
  177.         var _image = item.querySelector('img')
  178.         if(_image === undefined)
  179.             return false;
  180.         var clonedImage = _image.cloneNode(true)
  181.         ImageOverlay.querySelector('.image-overlay-viewer').appendChild(clonedImage)
  182.         ImageOverlay.style.top = `${_top}px`
  183.         ImageOverlay.style.left = `${_left}px`
  184.         ImageOverlay.style.width = `${_width}px`
  185.         ImageOverlay.style.height = `${_height}px`
  186.  
  187.  
  188.         showImageOverlay()
  189.         imageDraggable()
  190.     })
  191.    
  192. })
  193.  
  194. ImageOverlayCloseBtn.addEventListener('click', closeImageOverlay)
  195. ImageOverlayBackdropBtn.addEventListener('click', closeImageOverlay)    

The script above makes the images on the web page clickable which triggers the image viewer to display and show the selected image on a larger scale. It also contains the script that makes the zooming buttons and image dragging functional.

Here's a snapshot of the image viewer that displays the image using the default scale or size.

Image Popup/Overlay Viewer using CSS and JS

Then, when the below image is an example view of a zoomed-in image.

Image Popup/Overlay Viewer using CSS and JS

There you go! I have also provided the complete source code zip file on this website and it is free to download. The download button is located below this tutorial's content. Feel free to download and modify it.

That's it! I hope this Image Popup/Overlay Viewer with Zoom In and Out using CSS and JavaScript will help you with what you are looking for and will be useful for your current and future web application projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding =)

Add new comment