<div class="lightbox" x-data="{lightboxOpen: false, imgSrc: '', caption: ''}" x-show="lightboxOpen" x-transition.opacity @lightbox.window="lightboxOpen = true; imgSrc = $event.detail.src; caption = $event.detail.caption">
  <div class="lightbox-container">
    <div class="lightbox-content" x-show="lightboxOpen" x-transition.scale>
      <button class="lightbox-close" @click="lightboxOpen = false">&times;</button>
      <img :src="imgSrc" @click.away="lightboxOpen = false">
      <p x-text="caption" class="caption"></p>
    </div>
  </div>
</div>

<div x-data class="gallery">
  <img src="https://picsum.photos/id/1/160/160" @click="$dispatch('lightbox', {src: 'https://picsum.photos/id/1/640/360', caption: 'ini caption 1'})" />
  <img src="https://picsum.photos/id/2/160/160" @click="$dispatch('lightbox', {src: 'https://picsum.photos/id/2/640/360', caption: 'ini caption 2'})" />
  <img src="https://picsum.photos/id/3/160/160" @click="$dispatch('lightbox', {src: 'https://picsum.photos/id/3/640/360', caption: 'ini caption 3'})" />
  <img src="https://picsum.photos/id/4/160/160" @click="$dispatch('lightbox', {src: 'https://picsum.photos/id/4/640/360', caption: 'ini caption 4'})" />
</div>
.gallery {
  display: flex;
  gap: 1em;
}

.gallery img {
  cursor: zoom-in;
}

.lightbox {
  position: fixed;
  inset: 0;
  height: 100vh;
  width: 100vw;
  background-color: rgba(0, 0, 0, 0.8);
}

.lightbox-container {
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

.lighbox-container * {
  max-width: 100%;
}

.lightbox-content {
  position: relative;
}

.lightbox-content .caption {
  text-align: center;
  color: white;
}

.lightbox-close {
  position: absolute;
  top: -1em;
  right: -1em;
  border-radius: 50%;
  height: 44px;
  width: 44px;
  font-size: 1.8em;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/[email protected]/dist/cdn.min.js