How to add lightbox to WordPress images and galleries without plugin
When it comes to adding a lightbox effect to WordPress images and galleries, the options may seem overwhelming. Many plugins are available, but they often come with unnecessary complexities and code. To simplify the process for your clients, a great solution is to integrate lightbox functionality directly into the WordPress core images and galleries. I will walk you through the complete steps to achieve a lightweight and easy-to-use lightbox for your WordPress theme.
To start, we’ll register a custom block style that will allow your clients to easily apply the lightbox effect to images and galleries.
Example of registering block style
function theme_name_register_block_styles() {
register_block_style(
'core/image',
array(
'name' => 'lightbox',
'label' => __( 'Lightbox', 'theme_name' ),
)
);
register_block_style(
'core/gallery',
array(
'name' => 'lightbox',
'label' => __( 'Lightbox', 'theme_name' ),
)
);
add_action( 'init', 'theme_name_register_block_styles' );
Example of JavaScript file.
document.addEventListener('DOMContentLoaded', function() {
// Get all lightbox containers by class name
var lightboxContainers = document.getElementsByClassName('is-style-lightbox');
// Loop through each lightbox container
Array.from(lightboxContainers).forEach(function(container) {
// Find all child images within the container
var images = container.querySelectorAll('img');
// Loop through each image
Array.from(images).forEach(function(image, index) {
// Add the lightbox image class
image.classList.add('lightbox-image');
// Add click event listener to open lightbox
image.addEventListener('click', function() {
openLightbox(container, images, index);
});
});
});
// Function to open lightbox
function openLightbox(container, images, startIndex) {
// Create the lightbox overlay and content elements
var overlay = document.createElement('div');
overlay.classList.add('lightbox-overlay');
var content = document.createElement('div');
content.classList.add('lightbox-content');
// Create the close button element
var closeButton = document.createElement('span');
closeButton.classList.add('lightbox-close');
closeButton.innerHTML = '×';
// Add click event listener to close lightbox
closeButton.addEventListener('click', function() {
closeLightbox(container, overlay);
});
// Append the close button to the content element
content.appendChild(closeButton);
// Create the navigation arrows
var prevArrow = document.createElement('span');
prevArrow.classList.add('lightbox-arrow', 'lightbox-arrow-prev');
prevArrow.innerHTML = '❮';
var nextArrow = document.createElement('span');
nextArrow.classList.add('lightbox-arrow', 'lightbox-arrow-next');
nextArrow.innerHTML = '❯';
// Check if there is more than one image
if (images.length > 1) {
// Add click event listeners to navigate between images
prevArrow.addEventListener('click', function() {
showPreviousImage();
});
nextArrow.addEventListener('click', function() {
showNextImage();
});
// Append the navigation arrows to the content element
content.appendChild(prevArrow);
content.appendChild(nextArrow);
}
// Create the container for the images
var imageContainer = document.createElement('div');
imageContainer.classList.add('lightbox-image-container');
// Loop through each image and clone them
Array.from(images).forEach(function(image, index) {
// Clone the image and add additional classes
var clonedImage = image.cloneNode(true);
clonedImage.classList.add('lightbox-enlarged');
clonedImage.style.display = 'none'; // Hide all images initially except for the selected one
// Append the cloned image to the container
imageContainer.appendChild(clonedImage);
// Show the selected image
if (index === startIndex) {
clonedImage.style.display = 'block';
clonedImage.style.animation = 'tilt 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both';
}
});
// Append the image container to the content element
content.appendChild(imageContainer);
// Append the content element to the overlay element
overlay.appendChild(content);
// Append the overlay to the body
document.body.appendChild(overlay);
// Add click event listener to close lightbox when clicking outside the image
overlay.addEventListener('click', function(event) {
if (event.target === overlay) {
closeLightbox(container, overlay);
}
});
// Variable to keep track of the current image index
var currentIndex = startIndex;
// Function to show the next image
function showNextImage() {
var nextIndex = (currentIndex + 1) % images.length;
imageContainer.children[currentIndex].style.display = 'none';
imageContainer.children[nextIndex].style.display = 'block';
imageContainer.children[nextIndex].style.animation = 'tilt 0.6s cubic-bezier(0.680, -0.550, 0.265, 1.550) both';
currentIndex = nextIndex;
}
// Function to show the previous image
function showPreviousImage() {
var previousIndex = (currentIndex - 1 + images.length) % images.length;
imageContainer.children[currentIndex].style.display = 'none';
imageContainer.children[previousIndex].style.display = 'block';
imageContainer.children[previousIndex].style.animation = 'tilt-back 0.6s cubic-bezier(0.680, -0.550, 0.265, 1.550) both';
currentIndex = previousIndex;
}
// Add keyboard arrow key support for sliding
document.addEventListener('keydown', function(event) {
if (event.key === 'ArrowRight') {
showNextImage();
} else if (event.key === 'ArrowLeft') {
showPreviousImage();
} else if (event.key === 'Escape') {
closeLightbox(container, overlay);
}
});
// Lazy load images within the lightbox
var lazyImages = overlay.querySelectorAll('img[data-src]');
Array.from(lazyImages).forEach(function(lazyImage) {
lazyImage.setAttribute('src', lazyImage.getAttribute('data-src'));
lazyImage.onload = function() {
lazyImage.removeAttribute('data-src');
};
});
// Show caption if available
var caption = images[startIndex].getAttribute('alt');
if (caption) {
var captionElement = document.createElement('div');
captionElement.classList.add('lightbox-caption');
captionElement.innerText = caption;
content.appendChild(captionElement);
}
}
// Function to close lightbox
function closeLightbox(container, overlay) {
// Remove the overlay from the body
document.body.removeChild(overlay);
}
});
Example of wp_enqueue_script() assuming that you will create in that location file named like this:
wp_enqueue_script('lightbox', get_template_directory_uri() . '/assets/js/lightbox.js', array('jquery'), '1.0', true);
Example of CSS
.lightbox-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
transition: opacity 0.3s ease;
}
/* Lightbox content */
.lightbox-content {
position: relative;
margin: auto;
padding: 0;
width: 90%;
}
.lightbox-close {
position: absolute;
font-size: 48px;
font-weight: bold;
top: 10px;
right: 10px;
color: var(--wp--preset--color--primary-light);
cursor: pointer;
transition: color 0.3s ease;
z-index: 1;
}
.lightbox-close:hover {
color: var(--wp--preset--color--primary);
}
.lightbox-arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 48px;
color: var(--wp--preset--color--primary-light);
cursor: pointer;
opacity: 0.5;
transition: opacity 0.3s ease;
z-index: 1;
}
.lightbox-arrow:hover {
opacity: 1;
}
.lightbox-arrow-prev {
left: 10px;
}
.lightbox-arrow-next {
right: 10px;
}
.lightbox-image-container {
display: flex;
align-items: center;
justify-content: center;
height: 90vh;
padding: 1.6rem;
margin: auto;
}
/* Lightbox image */
.lightbox-image {
cursor: pointer;
transition: opacity 0.2s;
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.lightbox-image:hover {
opacity: 0.7;
}
.lightbox-enlarged {
opacity: 1;
}
.lightbox-caption {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
margin: auto;
padding: 1rem;
text-align: center;
background-color: rgba(0, 0, 0, 0.8);
color: var(--wp--preset--color--primary-light);
border-radius: 24px;
}
@-webkit-keyframes tilt{
0% {
-webkit-transform: rotateY(20deg) rotateX(35deg) translate(300px, -300px) skew(-35deg, 10deg);
transform: rotateY(20deg) rotateX(35deg) translate(300px, -300px) skew(-35deg, 10deg);
opacity: 0;
}
100% {
-webkit-transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
opacity: 1;
}
}
@keyframes tilt {
0% {
-webkit-transform: rotateY(20deg) rotateX(35deg) translate(300px, -300px) skew(-35deg, 10deg);
transform: rotateY(20deg) rotateX(35deg) translate(300px, -300px) skew(-35deg, 10deg);
opacity: 0;
}
100% {
-webkit-transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
opacity: 1;
}
}
@-webkit-keyframes tilt-back {
0% {
-webkit-transform: rotateY(-20deg) rotateX(35deg) translate(-300px, -300px) skew(35deg, -10deg);
transform: rotateY(-20deg) rotateX(35deg) translate(-300px, -300px) skew(35deg, -10deg);
opacity: 0;
}
100% {
-webkit-transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
opacity: 1;
}
}
@keyframes tilt-back {
0% {
-webkit-transform: rotateY(-20deg) rotateX(35deg) translate(-300px, -300px) skew(35deg, -10deg);
transform: rotateY(-20deg) rotateX(35deg) translate(-300px, -300px) skew(35deg, -10deg);
opacity: 0;
}
100% {
-webkit-transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
transform: rotateY(0) rotateX(0deg) translate(0, 0) skew(0deg, 0deg);
opacity: 1;
}
}
You can see lightbox in action on this website