Search code examples
javascripthtmlslideraccessibilityswiper.js

Swiper JS - Enter button doesn't do anything on the thumbnail for accessibility


Issue:

We are having accessibility issues on the swiper slider when pressing the enter button on the thumbnail which doesn't bring the selected image to the main image area. is there any way if we can do so pressing the enter button changes the main image of the slider?

Scenario:

We have a swiper JS - slider (https://swiperjs.com/) set up on our website the slider works perfectly with thumbnails. that means clicking on the thumbnail, shows the specific image in the main image area.

But for the accessibility, I am trying to add "tabindex='0'" and "role='button'" so I can focus the thumbnails by pressing tabs (and this works) but pressing (enter) button doesn't bring up the selected image on the main image area.

Please see the codepen link below with the code example and you can see that you can tab through the thumbnails but hitting enter on the thumbnail doesn't do anything:

Code with the demo link:

https://codepen.io/asifkhanlush/pen/oNjvVpG?editors=1111

Code:

HTML:

<body>
    <div class="swiper-container gallery-top">
        <div class="swiper-wrapper">
            <div tabindex="0" role="button" class="swiper-slide">
                <div class="swiper-slide-container">Slide 1</div>
            </div>
            <div tabindex="0" role="button" class="swiper-slide">
                <div class="swiper-slide-container">Slide 2</div>
            </div>
            ....
        </div>
        <!-- Add Arrows -->
        <div class="swiper-button-next"></div>
        <div class="swiper-button-prev"></div>
    </div>
    <div class="swiper-container gallery-thumbs">
        <div class="swiper-wrapper">
            <div tabindex="0" role="button" class="swiper-slide">
                <div class="swiper-slide-container" >Slide 1</div>
            </div>
            <div class="swiper-slide" tabindex="0" role="button">
                <div class="swiper-slide-container">Slide 2</div>
            </div>
            ...
        </div>
</div>

JS:

var galleryTop = new Swiper('.gallery-top', {
    spaceBetween: 10,
    navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
    },
    loop: true,
    loopedSlides: 4
});
var galleryThumbs = new Swiper('.gallery-thumbs', {
  spaceBetween: 10,
  centeredSlides: true,
  slidesPerView: 'auto',
  touchRatio: 0.2,
  slideToClickedSlide: true,
      loop: true,
      loopedSlides: 4
});
galleryTop.controller.control = galleryThumbs;
galleryThumbs.controller.control = galleryTop;

Solution

  • This is a bug/missing feature in Swiper (https://github.com/nolimits4web/swiper/issues/4324), but I found a workaround.

    Basically, add data-slide-index to all thumbs and add a keydown listener to the thumbnail elements:

    galleryThumbs.$el.on("keydown", (e) => {
      if (e.keyCode !== 13 && e.keyCode !== 32) return;
    
      var slideIndex = e.target.dataset.slideIndex;
    
      if (!slideIndex) return;
    
      galleryThumbs.slideTo(slideIndex);
      galleryTop.slideTo(slideIndex);
    });
    

    Here's the full code with a demo: https://codesandbox.io/s/swiper-thumbs-gallery-forked-2d1up?file=/index.html.