A simple grid container houses the grid and aligns it center via flexbox. The grid itself holds six images and is set to display: grid.
Controls (next, previous, and exit buttons) are fixed-position and initially hidden, along with the lightbox. Each control holds a simple SVG and shows a subtle circular background on hover.
The lightbox setup is simple: it holds two images stacked on top of each other. The images are stacked so the script can crossfade between them by toggling opacity during next/previous transitions.
An event listener in JavaScript listens for image clicks. When an image is clicked, an “active” class is added to the lightbox, the selected image, and the controls. The active classes make these elements visible through opacity and pointer-events changes (or display toggles, depending on setup).
Since we’re using querySelectorAll to select our images, we can loop through them using their index. Each image includes a data-index="0" (and so on) in HTML, giving a reference to which grid item is selected. When clicked, the index value is passed into a function that opens the lightbox and displays the correct image.
The next and previous buttons use modular arithmetic to cycle through the images without breaking the sequence. For example, (currentIndex + 1) % totalImages moves forward and loops back to the first image when reaching the end. The same idea applies in reverse for the previous button.
During transitions, the inactive lightbox image updates to the next source, then fades in while the other fades out. This double-layer setup prevents flicker and allows for true crossfade. The exit button (or pressing Escape) removes the active classes, closing the lightbox, and hides the controls.