RAY MORTIMER

UK Web Developer

Convert a Wordpress Gallery Block to a Carousel (NO Plugin)

Hacking the Built-in Gallery Block

Of the wide range of standard blocks available in Wordpress, there are none that can give us an interactive carousel or slideshow.

We would need to install a plugin to provide such a block in the WP editor and some Javascript to run the thing on the client side.

But this seems a little bit of a waste considering that the standard Wordpress Gallery block contains 95% of the HTML markup required for a carousel.

So, with a few lines of Javascript and the SwiperJS Javascript library we can easily convert a gallery to an interactive carousel. I'm sure other libraries such as Slick Slider could also be used.

When creating Wordpress content, you only need to add a custom css class to the gallery block to transform it!

Screenshot of the finished gallery

Overview

Here is a brief overview of the steps required before we go into more detail:

  1. Insert a gallery block and load the images required - ideally they should all be the same size.
    Use captions if required - just a few words, don't make them too long
  2. In the advanced panel for the gallery, under "additional css classes", add carousel
  3. Enqueue the swiper.min.js in the functions.php file just like any other script
  4. Add the code below to your main Javascript file for this site
  5. Add the required carousel CSS to the site stylesheet
  6. That's it!
As it appears in the Wordpress editor

Details

These screenshots were taken from a completely standard installation of Wordpress 6.2 running the TwentyTwentyTwo theme.

Selecting the gallery block
  1. Insert a gallery block from the block chooser and insert all the images you want within this carousel. As with any carousel, it looks neater if all the images are exactly the same size. You can add captions to images if you want
  2. Select the gallery block by clicking any image in the gallery and choose the first icon in the toolbar (screenshot above)
  3. On the right hand size under Advanced, find the Additional CSS Classes field
  4. Add the class carousel (this is mandatory)
  5. The following two classes are optional (without them, the carousel is swipe only):
    Add the class use-arrows if you want to show the left and right arrows
    Add the class use-dots to show a row of pagination dots for the slides
  6. Save the page and we're done. Going forward, just repeat these steps anytime you want a carousel on your site
  7. In functions.php enqueue the swiperJS library.
    NOTE It is important that the swiper library is loaded before any of our site Javascript
    wp_enqueue_script( 'carousel', get_template_directory_uri() . '/js/swiperjs.min.js', '', '', true);
    wp_enqueue_script( 'site-main-js', get_template_directory_uri() . '/js/main.js', '', '', true);
  8. We need to add extra some Javascript in order to prepare the carousels before we initialize them with swiperJS. Specifically, we will be doing the following:
    • Add a unique ID to each swiper on the page
    • Add a wrapper DIV within the gallery block to contain all the slides (this is the 'track' that contains all the slides and is overflow hidden so we only see one at a time)
    • Move the slides into that new DIV
    • Add the navigation dots and arrows if required
  9. Here is the Javascript code: (run after window load to ensure all the HTML is ready)
    function initCarousels() {
        let theSlideName = 'wp-block-image',    // each slide is a gallery block fig
            theWrapperClass = 'carousel-inner', // new wrapper div for slides
            allSwipers = document.querySelectorAll('.carousel'),
            c = 0;
    
        // for each carousel
        [].slice.call(allSwipers).forEach(function(carousel) {
            c = c + 1;
            // set a unique ID and get all the slides
            carousel.setAttribute('ID', 'carousel' + c);
            let swiperID = '#carousel' + c,
                content = carousel.querySelectorAll('figure'),
                newDiv = document.createElement('div');
    
            // append a new inner-wrapper
            newDiv.className = theWrapperClass;
            carousel.appendChild(newDiv);
    
            // move each slide into the new wrapper
            [].slice.call(content).forEach(function(node) {
                newDiv.appendChild(node);
            });
    
            // if this carousel has use-dots class add dot pagination
            if (carousel.classList.contains('use-dots')) carousel.insertAdjacentHTML('beforeend', '<div class="swiper-pagination"></div>');
    
            // if this carousel has use-arrows class add arrow buttons
            if (carousel.classList.contains('use-arrows')) carousel.insertAdjacentHTML('beforeend', '<div class="swiper-buttons"><div class="swiper-prev"></div><div class="swiper-next"></div></div>');
    
            // set up each swiper using standard swiperJS syntax
            // you can set different options here if required
            let swiper = new Swiper(swiperID, {
                slidesPerView: '1',
                loop: true,
                wrapperClass: theWrapperClass,
                slideClass: theSlideName,
                centeredSlides: true,
                spaceBetween: 20,
                pagination: {
                    el: swiperID + ' .swiper-pagination',
                    type: 'bullets',
                    clickable: true,
                },
                navigation: {
                    nextEl: swiperID + ' .swiper-next',
                    prevEl: swiperID + ' .swiper-prev',
                },
                initialSlide: 0,
            });
        });
    }
    window.addEventListener('load', initCarousels, false);
  10. Add the following CSS to the stylesheet. I've used text for the pagination dots and arrows here for simplicity, but I'd normally use either a FontAwesome icon or an SVG file.
    /* CAROUSELS ----------------------------------------- */
    
    /*
    can have no pagination or dots and/or arrows
    (add .use-dots and/or .use-arrows to .carousel
    add captions except for dots
    */
    
    .carousel { margin: 0 auto; position: relative; overflow: hidden; padding: 0; z-index: 1; width: 100%; visibility: hidden; opacity: 0; transition: opacity 0.5s ease; justify-content: center; }
    .carousel.swiper-initialized { visibility: visible; opacity: 1; }    
    .carousel.use-arrows,
    .carousel.use-dots { padding-bottom: 25px; }
    .carousel-inner { position: relative; width: 100%; z-index: 1; display: flex; flex-flow: row nowrap; transition-property: transform; box-sizing: content-box; align-items: flex-start; gap: 0; }
    
    /* slides */
    .carousel .wp-block-image { width: 100%; height: auto; position: relative; flex-shrink: 0; display: flex; flex-flow: row wrap; margin-bottom: 0; cursor: ew-resize; }
    .carousel .wp-block-image img { width: 100%; height: auto; }
    
    .swiper-pagination,
    .swiper-buttons { display: none; gap: 20px; position: absolute; bottom: 25px; }
    
    /* dots */
    .carousel.use-dots .swiper-pagination { display: flex; }
    .swiper-pagination-bullet { height: 15px; cursor: pointer; display: inline-block; flex: 1; }
    .swiper-pagination-bullet:after { font-size: 10px;  content: "O"; opacity: 0.5; }
    .swiper-pagination-bullet-active:after { font-size: 20px; opacity: 1; }
    
    /* arrows */
    .carousel.use-arrows .swiper-buttons { display: flex; right: 0; bottom: 10px; }
    .swiper-buttons div { cursor: pointer; line-height: 1; font-size: 30px; }
    .swiper-prev:after { content: "<"; }
    .swiper-next:after { content: ">"; }

Conclusion

This code will allow us to create lightweight carousels for our Wordpress sites without relying on third party WP plugins.

We do require swiperJS, which could be fetched from a CDN to ensure it's always up-to-date. Or we could create our own lightweight Javascript carousel code.