Adding lightbox to image in CMS rich text field

Hi, I wondered if it was possible to add a lightbox feature to an image that has been added in a rich text field through the CMS? I have seen workarounds for using a lightbox for an image that is in a specific image field in the CMS but can’t seem to find anything that would work if it has been added in a rich text field.

Thanks

1 Like

Trying to do the same :frowning:

Hmm that’s definitely a tricky problem to solve. I honestly can’t think of anyway to do this exactly how you want. The only solutions I can think of aren’t super practical, but may help:

​1. Turn the entire rich text element into a click trigger interaction. You can’t target just the image so you’d have to use the entire thing, then use interactions to set up a pop up modal / custom lightbox with the image inside
​2. Create two separate rich text fields. One field for above the image content, the other for after image content. Then add an image field to the collection and set your image as needed. Then you can structure the page like this:

From here you can create a custom lightbox using interactions and set the image as the click trigger to open the lightbox.

Beyond those two methods I can’t think of any other way to do this natively. Best of luck and let us know if you find a better solution! :slight_smile:

3 Likes

Thanks for your help Brandon.

2 Likes

Here’s code that enables that functionality.

<script>
  (() => {
    function replaceImagesWithLightboxes(element) {
      const figures = element.querySelectorAll(".w-richtext-figure-type-image");

      figures.forEach((figure) => {
        const image = figure.querySelector("img");
        const imageUrl = image.getAttribute("src");
        const imageAlt = image.getAttribute("alt");
        const imageWidth = image.getAttribute("width"); // Added to retrieve the image width

        // Create lightbox HTML
        const lightbox = document.createElement("a");
        lightbox.setAttribute("href", "#");
        lightbox.classList.add("w-inline-block", "w-lightbox");

        const lightboxImage = document.createElement("img");
        lightboxImage.setAttribute("src", imageUrl);
        lightboxImage.setAttribute("loading", "lazy");
        lightboxImage.setAttribute("sizes", "100vw");
        lightboxImage.setAttribute("srcset", generateSrcset(imageUrl, imageWidth));
        lightboxImage.setAttribute("alt", imageAlt);

        const script = document.createElement("script");
        script.setAttribute("type", "application/json");
        script.classList.add("w-json");
        script.textContent = JSON.stringify({
          items: [
            {
              _id: Math.random().toString(),
              origFileName: imageAlt,
              fileName: imageAlt,
              url: imageUrl,
              width: imageWidth ? parseInt(imageWidth) : undefined, // Updated to use the retrieved image width
              type: "image",
            },
          ],
          group: "",
        });

        lightbox.appendChild(lightboxImage);
        lightbox.appendChild(script);

        figure.innerHTML = "";
        figure.appendChild(lightbox);
      });
    }

    function generateSrcset(imageUrl, imageWidth) {
      const sizes = [500, 800, 1080, 1600, 2000];
      const srcset = sizes
      .filter((size) => size <= imageWidth) // Filter sizes smaller than or equal to the original image width
      .map((size) => {
        return `${imageUrl.replace(".png", `-p-${size}.png`)} ${size}w`;
      });

      srcset.push(`${imageUrl} ${imageWidth}w`);

      return srcset.join(", ");
    }


    const containerElement = document.querySelector('.pillar-main__rte');
    replaceImagesWithLightboxes(containerElement);
  })();
</script>

Let’s break down the code and understand its functionality:

  1. The code is wrapped in an immediately invoked function expression (IIFE) to create a local scope and avoid polluting the global namespace.
  2. The replaceImagesWithLightboxes function is defined. It accepts an element parameter, which should be an HTML element containing the images that need to be replaced with lightboxes.
  3. The function starts by selecting all elements with the class “w-richtext-figure-type-image” within the provided element. These elements are typically used to represent images within a Webflow rich text element.
  4. The function iterates over each of the selected figures using the forEach method.
  5. For each figure, the function retrieves the img element within it and extracts the URL (src attribute), alternate text (alt attribute), and width (width attribute) of the image.
  6. The code then proceeds to create the necessary HTML elements for the lightbox functionality. It creates an a element (lightbox) that serves as a container for the image and attaches the necessary classes (w-inline-block and w-lightbox).
  7. Inside the lightbox container, an img element (lightboxImage) is created and populated with attributes such as the image URL, lazy loading, sizes for responsiveness, and a srcset attribute generated by the generateSrcset function.
  8. Additionally, a script element is created to hold JSON data representing the image properties. It includes an array of objects representing the image data, such as ID, original and file names, URL, width, and type.
  9. The lightboxImage and script elements are appended as children to the lightbox container.
  10. After constructing the lightbox HTML, the figure’s contents are cleared (innerHTML = "") to remove the original image.
  11. Finally, the lightbox container is appended as a child to the figure, effectively replacing the original image with the lightbox.
  12. The generateSrcset function is defined to generate the srcset attribute for the lightbox image. It takes the image URL and width as input parameters.
  13. Inside the function, an array of sizes is defined (e.g., [500, 800, 1080, 1600, 2000]). It filters out sizes that are smaller than or equal to the original image width.
  14. For each remaining size, it generates a URL with the size appended (e.g., replacing “.png” with “-p-500.png”) and appends it to the srcset array with the corresponding width (size + "w").
  15. Finally, the srcset array is joined into a comma-separated string and returned.
  16. Outside the function definitions, the code selects the container element (specified by the class “RICH-TEXT-ELEMENT-CLASS”) where the images should be replaced with lightboxes.
  17. The replaceImagesWithLightboxes function is called with the container element as an argument, triggering the replacement of images within that element.

Overall, this code enhances the images within a Webflow rich text element by replacing them with lightboxes, which allow users to view the images in a larger size or in a modal popup. It also provides responsive behavior by generating a srcset attribute with different image sizes based on the

Explanation offered by ChatGPT, but seems right

4 Likes

Thank you for sharing this code. Could you demo this in a webflow site where this is functioning? Thank you. Andras

This looks amazing, thanks. How would you implement this site-wide? I can’t code for sh*t :slight_smile:

1 Like

I tried the code provided above, just need to change element to document and it will work
So here how to make it for anyone who don’t know how to code @schaffan @dozzi

First, open your page settings and go to the custom code section, put the code in the Before </body> tag, and put it like this:

<script>
  (() => {
    function replaceImagesWithLightboxes(element) {
      const figures = document.querySelectorAll(".w-richtext-figure-type-image");

      figures.forEach((figure) => {
        const image = figure.querySelector("img");
        const imageUrl = image.getAttribute("src");
        const imageAlt = image.getAttribute("alt");
        const imageWidth = image.getAttribute("width"); // Added to retrieve the image width

        // Create lightbox HTML
        const lightbox = document.createElement("a");
        lightbox.setAttribute("href", "#");
        lightbox.classList.add("w-inline-block", "w-lightbox");

        const lightboxImage = document.createElement("img");
        lightboxImage.setAttribute("src", imageUrl);
        lightboxImage.setAttribute("loading", "lazy");
        lightboxImage.setAttribute("sizes", "100vw");
        lightboxImage.setAttribute("srcset", generateSrcset(imageUrl, imageWidth));
        lightboxImage.setAttribute("alt", imageAlt);

        const script = document.createElement("script");
        script.setAttribute("type", "application/json");
        script.classList.add("w-json");
        script.textContent = JSON.stringify({
          items: [
            {
              _id: Math.random().toString(),
              origFileName: imageAlt,
              fileName: imageAlt,
              url: imageUrl,
              width: imageWidth ? parseInt(imageWidth) : undefined, // Updated to use the retrieved image width
              type: "image",
            },
          ],
          group: "",
        });

        lightbox.appendChild(lightboxImage);
        lightbox.appendChild(script);

        figure.innerHTML = "";
        figure.appendChild(lightbox);
      });
    }

    function generateSrcset(imageUrl, imageWidth) {
      const sizes = [500, 800, 1080, 1600, 2000];
      const srcset = sizes
      .filter((size) => size <= imageWidth) // Filter sizes smaller than or equal to the original image width
      .map((size) => {
        return `${imageUrl.replace(".png", `-p-${size}.png`)} ${size}w`;
      });

      srcset.push(`${imageUrl} ${imageWidth}w`);

      return srcset.join(", ");
    }


    const containerElement = document.querySelector('.pillar-main__rte');
    replaceImagesWithLightboxes(containerElement);
  })();
</script>

If still not, you may want to add this to the Inside <head> tag

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
3 Likes

Thanks for this. It seems close to working, but I get a bunch of JS errors which prevent the click action doing anything.

(I’m using Lam Thai’s code)

Any ideas what might need to change to fix it?

This is the page I have it on: Outline

1 Like

@Lam_Thai1 sorry to bug you, curious if those JS errors make any sense to you?

omg, it worked! thank you so much! just a note that, you can only see it after publishing the website, you can’t see it in the preview, it works like a champ!

only thing is that, it gets rid of the caption (unable to display the caption for the image), are you able to keep the caption from the original image?

thanks to @Lam_Thai1 I had motified the code with GPT so now it shows the caption as well, and here’s the code:

<script>
  (() => {
    function replaceImagesWithLightboxes(element) {
      const figures = document.querySelectorAll(".w-richtext-figure-type-image");

      figures.forEach((figure) => {
        const image = figure.querySelector("img");
        const caption = figure.querySelector("figcaption");
        const imageUrl = image.getAttribute("src");
        const imageAlt = image.getAttribute("alt");
        const imageWidth = image.getAttribute("width"); 

        // Create lightbox HTML
        const lightbox = document.createElement("a");
        lightbox.setAttribute("href", "#");
        lightbox.classList.add("w-inline-block", "w-lightbox");

        const lightboxImage = document.createElement("img");
        lightboxImage.setAttribute("src", imageUrl);
        lightboxImage.setAttribute("loading", "lazy");
        lightboxImage.setAttribute("sizes", "100vw");
        lightboxImage.setAttribute("srcset", generateSrcset(imageUrl, imageWidth));
        lightboxImage.setAttribute("alt", imageAlt);

        const script = document.createElement("script");
        script.setAttribute("type", "application/json");
        script.classList.add("w-json");
        script.textContent = JSON.stringify({
          items: [
            {
              _id: Math.random().toString(),
              origFileName: imageAlt,
              fileName: imageAlt,
              url: imageUrl,
              width: imageWidth ? parseInt(imageWidth) : undefined,
              type: "image",
              caption: caption ? caption.innerText : undefined,
            },
          ],
          group: "",
        });

        lightbox.appendChild(lightboxImage);
        lightbox.appendChild(script);

        // Clear figure and append new elements
        figure.innerHTML = "";
        figure.appendChild(lightbox);
        if (caption) {
          figure.appendChild(caption.cloneNode(true)); // Add a clone of the caption
        }
      });
    }

    function generateSrcset(imageUrl, imageWidth) {
      const sizes = [500, 800, 1080, 1600, 2000];
      const srcset = sizes
        .filter((size) => size <= imageWidth)
        .map((size) => `${imageUrl.replace(".png", `-p-${size}.png`)} ${size}w`);

      srcset.push(`${imageUrl} ${imageWidth}w`);

      return srcset.join(", ");
    }

    const containerElement = document.querySelector('.pillar-main__rte');
    replaceImagesWithLightboxes(containerElement);
  })();
</script>

1 Like

Oli, I’m getting the same errors as you. I’ve tried it on an existing site and a fresh build so I don’t think anything else is interfering with it.

Are we supposed to set the width of the figure image somewhere other than choosing a default width when clicking on it in the designer? It seems like it’s looking for a pixel width for the image that isn’t there.

If anyone else is having issues with this and getting Javascript errors, I’ve made a simple alternative solution you can use that doesn’t use the native lightbox functionality.

Here is the read-only link where you can grab it. Webflow - Modal lightbox for figure images in a rich text field

And here is the published site: https://modal-lightbox-for-figure-images-in-a-r.webflow.io/

All you have to do is include an embed anywhere on your page that has the HTML for the modal, some CSS in the page settings inside the head tag, and the script inside the page settings before the closing body tag.

Just look at the home page and it should be self explanatory. This will work on static pages as well as CMS pages as long as you are using the figure element in a rich text field.

Here is how to implement it:

Add an embed anywhere on the page with this (you will only see it in the designer, not the published site):

<!-- Modal HTML markup -->
<div id="modal">
  <span id="close">&times;</span>
  <img id="modal-img" src="" alt="Modal Image">
</div>

Open your page settings and add this CSS inside the tag:

<style>
  /* Style for the modal */
  #modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    z-index: 9999;
    justify-content: center;
    align-items: center;
  }

  #modal img {
    max-width: 90%;
    max-height: 90%;
  }

  /* Style for the close button */
  #close {
    position: absolute;
    top: 20px;
    right: 20px;
    color: #fff;
    cursor: pointer;
  }

  /* Change cursor to pointer when hovering over initial figure image */
  .w-richtext-align-center img {
    cursor: pointer;
  }

  /* Change cursor to pointer for entire body when modal is open */
  body.modal-open {
    cursor: pointer;
  }
</style>

Then add this script before the tag:

<script>
  document.addEventListener("DOMContentLoaded", function() {
    var modal = document.getElementById("modal");
    var modalImg = document.getElementById("modal-img");
    var closeBtn = document.getElementById("close");

    // Function to open modal with clicked image
    function openModal(imgSrc) {
      modalImg.src = imgSrc;
      modal.style.display = "flex";
      document.body.classList.add('modal-open'); // Add modal-open class to body
    }

    // Function to close modal
    function closeModal() {
      modal.style.display = "none";
      document.body.classList.remove('modal-open'); // Remove modal-open class from body
    }

    // Event listener to open modal when image is clicked
    document.querySelectorAll('.w-richtext-align-center img').forEach(function(img) {
      img.addEventListener('click', function() {
        openModal(img.src);
      });
    });

    // Event listener to close modal when clicked outside of image or on the modal image
    modal.addEventListener('click', function(event) {
      if (event.target === modal || event.target === closeBtn || event.target === modalImg) {
        closeModal();
      }
    });

    // Optional: Close modal when pressing Esc key
    document.addEventListener('keydown', function(event) {
      if (event.key === 'Escape') {
        closeModal();
      }
    });
  });
</script>

That’s it! No Webflow lightboxes or external lightbox scripts needed! Just don’t ask me how to make it fade in and out - you’re on your own on that one! :wink:

2 Likes

Building on the solution @Seantubridy provided I worked on the issue with Chatgpt because two things weren’t working:

  1. The image wasn’t opened whenever a different class than .w-richtext-align-center img was used so I replaced it with the following class I found in the selector .w-richtext-figure-type-image. Now all images are opened upon click indepent of their alignment inside the text.
  2. no caption was being displayed. I added some updates to the HTML embed, to the CSS and Javascript so that the caption would be displayed.
    This is the complete code I am using (mind you, I’m not a JS expert so I can’t help with any request - I also just tinkered with Chat GPT) - hope this helps. The next step is to figure out that additional fade-in fade-out effect :)

HTML embed to create the modal:

<!-- Modal HTML markup -->
<div id="modal">
  <span id="close">&times;</span>
  <div id="modal-content">
    <img id="modal-img" src="" alt="Modal Image">
    <div id="modal-caption"></div> <!-- Use a separate container for the caption -->
  </div>
</div>

CSS inside <head> tag

<style>
  /* Style for the modal */
  #modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    z-index: 9999;
    justify-content: center;
    align-items: center;
  }

  #modal img {
    max-width: 90%;
    max-height: 90%;
    display: block; /* Ensure the image is displayed as a block element */
    margin: 0 auto; /* Center the image horizontally */
  }

  #modal-caption {
    color: #fff; /* Set caption text color */
    margin-top: 10px; /* Add space between image and caption */
    text-align: center; /* Center the caption text */
  }

  /* Style for the close button */
  #close {
    position: absolute;
    top: 20px;
    right: 20px;
    color: #fff;
    cursor: pointer;
  }

  /* Change cursor to pointer when hovering over initial figure image */
  .w-richtext-align-fullwidth.w-richtext-figure-type-image img {
    cursor: pointer;
  }

  /* Change cursor to pointer for entire body when modal is open */
  body.modal-open {
    cursor: pointer;
  }
</style>

Javascript before </body> tag:

<script>
document.addEventListener("DOMContentLoaded", function() {
  var modal = document.getElementById("modal");
  var modalImg = document.getElementById("modal-img");
  var modalCaption = document.getElementById("modal-caption"); // Reference to the caption container
  var closeBtn = document.getElementById("close");

  // Function to open modal with clicked image and caption
  function openModal(imgSrc, captionText) {
    modalImg.src = imgSrc;
    modalCaption.textContent = captionText; // Set the caption text
    modal.style.display = "flex";
    document.body.classList.add('modal-open');
  }

  // Function to close modal
  function closeModal() {
    modal.style.display = "none";
    document.body.classList.remove('modal-open');
  }

  // Event listener to open modal when image is clicked
  document.querySelectorAll('.w-richtext-figure-type-image').forEach(function(figure) {
    var img = figure.querySelector('img');
    var caption = figure.querySelector('figcaption');
    img.addEventListener('click', function() {
      var imgSrc = img.getAttribute('src'); // Get the image source URL
      var captionText = caption ? caption.innerText : ''; // Get the caption text
      openModal(imgSrc, captionText);
    });
  });

  // Event listener to close modal when clicked outside of image or on the modal image
  modal.addEventListener('click', function(event) {
    if (event.target === modal || event.target === closeBtn || event.target === modalImg) {
      closeModal();
    }
  });

  // Optional: Close modal when pressing Esc key
  document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape') {
      closeModal();
    }
  });
});
</script>
1 Like

Now I used ChatGPT again to create a transition effect. It’s a fade-in effect. I decided against a fade-out effect after clicking the closing button.
Basically adding and removing the “show” class to the modal element did the trick in combination with the following:

  • We use setTimeout to add and remove the “show” class and to change the display property with a slight delay. This delay allows the transition effect to be visible.
  • Adjust the delay values (10 and 0 milliseconds) as needed to match the transition duration defined in your CSS.

This is the updated code for my specific use case:

CSS inside <head> tag

<!-- [Attributes by Finsweet] Powerful Rich Text -->
<script defer src="https://cdn.jsdelivr.net/npm/@finsweet/attributes-richtext@1/richtext.js"></script>

<style>
  /* Style for the modal */
  #modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(50, 50, 50, 0.9);
    z-index: 9999;
    justify-content: center;
    align-items: center;
    opacity: 0; /* Start with 0 opacity */
    transition: opacity 0.3s ease; /* Add transition for opacity */
    backdrop-filter: blur(3px);
  }
  
    #modal.show {
    opacity: 1; /* Show modal with full opacity */
  }

  #modal img {
    max-width: 90%;
    max-height: 90%;
    border-radius: 3px;
    display: block; /* Ensure the image is displayed as a block element */
    margin: 0 auto; /* Center the image horizontally */
  }

  #modal-caption {
    color: #fff; /* Set caption text color */
    margin-top: 10px; /* Add space between image and caption */
    text-align: center; /* Center the caption text */
    font-size: 18px;
    font-family: poppins;
		max-width: 90%;
    padding: 5px;
    padding-top: 10px;
    padding-bottom: 10px;
    justify-content: center;
    align-items: center;
    margin-left: 5%;
    margin-right:5%;
    border-radius: 3px;
  }

  /* Style for the close button */
  #close {
    position: absolute;
    top: 2%;
    right: 2%;
    color: #fff;
    cursor: pointer;
		font-size: 4rem;
    font-weight: 100;
    color: #cea92f;
    text-shadow: 0px 0px #cea92f;
    font-family: roboto;
  }

  /* Change cursor to pointer when hovering over initial figure image */
  .w-richtext-align-fullwidth.w-richtext-figure-type-image img {
    cursor: pointer;
  }

  /* Change cursor to pointer for entire body when modal is open */
  body.modal-open {
    cursor: pointer;
  }
</style>

Javascript before </body> tag:

<script>
document.addEventListener("DOMContentLoaded", function() {
  var modal = document.getElementById("modal");
  var modalImg = document.getElementById("modal-img");
  var modalCaption = document.getElementById("modal-caption");
  var closeBtn = document.getElementById("close");

  // Function to open modal with clicked image and caption
  function openModal(imgSrc, captionText) {
    modalImg.src = imgSrc;
    modalCaption.textContent = captionText; // Set the caption text
    modal.style.display = "flex";
    setTimeout(function() {
      modal.classList.add('show'); // Add 'show' class to display the modal with a delay for transition effect
    }, 10); // Adjust the delay as needed
    document.body.classList.add('modal-open');
  }

  // Function to close modal
  function closeModal() {
    modal.classList.remove('show'); // Remove 'show' class to hide the modal
    document.body.classList.remove('modal-open');
    setTimeout(function() {
      modal.style.display = "none"; // Hide the modal with a delay for transition effect
    }, 0); // Adjust the delay to match the transition duration
  }

  // Event listener to open modal when image is clicked
  document.querySelectorAll('.w-richtext-figure-type-image').forEach(function(figure) {
    var img = figure.querySelector('img');
    var caption = figure.querySelector('figcaption');
    img.addEventListener('click', function() {
      var imgSrc = img.getAttribute('src'); // Get the image source URL
      var captionText = caption ? caption.innerText : ''; // Get the caption text
      openModal(imgSrc, captionText);
    });
  });

  // Event listener to close modal when clicked outside of image or on the modal image
  modal.addEventListener('click', function(event) {
    if (event.target === modal || event.target === closeBtn) {
      closeModal();
    }
  });

  // Optional: Close modal when pressing Esc key
  document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape') {
      closeModal();
    }
  });
});
</script>

2 Likes

Thanks for this @_Max, works great!

2 Likes

Thanks so much guys! Used @_Max 's code but asked gpt to make a max size (in the HTML code element) to make some breathing room around the image (max size 800px both ways). The code seems long but it works nicely.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Max Size Modal</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
    }

    /* Modal container (background) */
    #modal {
      display: none;
      position: fixed;
      z-index: 1000;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.8); /* Semi-transparent background */
      justify-content: center;
      align-items: center;
    }

    /* Modal content area */
    #modal-content {
      position: relative;
      max-width: 800px; /* Max width of modal */
      max-height: 800px; /* Max height of modal */
    }

    /* Image inside the modal */
    #modal-img {
      max-width: 100%; /* Ensure the image doesn't overflow */
      max-height: 100%; /* Ensure the image doesn't overflow */
      width: auto;
      height: auto;
      display: block;
      border-radius: 5px;
    }

    /* Close button */
    #close {
      position: absolute;
      top: 15px;
      right: 25px;
      font-size: 30px;
      font-weight: bold;
      color: white;
      cursor: pointer;
    }

    /* Close button hover effect */
    #close:hover {
      color: red;
    }
  </style>
</head>
<body>

  <!-- Modal HTML markup -->
  <div id="modal">
    <span id="close">&times;</span>
    <div id="modal-content">
      <img id="modal-img" src="" alt="Modal Image">
      <div id="modal-caption"></div> <!-- Caption for the image -->
    </div>
  </div>

  <!-- Example thumbnail image to trigger modal -->
  <img src="https://via.placeholder.com/150" id="trigger-image" alt="Thumbnail" style="cursor: pointer;">

  <script>
    // Function to open the modal with image and caption
    function openModal(imageUrl, captionText) {
      const modal = document.getElementById('modal');
      const modalImg = document.getElementById('modal-img');
      const modalCaption = document.getElementById('modal-caption');
      
      modal.style.display = 'flex'; // Display the modal
      modalImg.src = imageUrl;      // Set the modal image source
      modalCaption.innerHTML = captionText; // Set the modal caption
    }

    // Function to close the modal
    const closeModal = document.getElementById('close');
    closeModal.onclick = function() {
      const modal = document.getElementById('modal');
      modal.style.display = 'none'; // Hide the modal
    }

    // Close modal when clicking outside the content area
    window.onclick = function(event) {
      const modal = document.getElementById('modal');
      if (event.target === modal) {
        modal.style.display = 'none';
      }
    }

    // Trigger the modal when the thumbnail image is clicked
    const triggerImage = document.getElementById('trigger-image');
    triggerImage.onclick = function() {
      openModal('https://via.placeholder.com/600', 'Sample Image Caption');
    }
  </script>

</body>
</html>
3 Likes

This totally worked for me, thanks SO MUCH!!