Free Web Design Code & Scripts

Image Gallery with Vertical Thumbnail Slider

Image Gallery with Vertical Thumbnail Slider
Code Snippet:(accessible-slick) PDP thumbnail image sliders
Author: Accessible360
Published: 6 months ago
Last Updated: 6 months ago
Downloads: 264
License: MIT
Edit Code online: View on CodePen
Read More

This tutorial will guide you through creating an accessible image gallery with a vertical thumbnail slider. This is a great way to showcase multiple images and provide a user-friendly experience, especially for users with disabilities. We’ll be using accessible-slick, a fully WCAG 2.0/2.1 compliant slider, to ensure inclusivity.

Step 1: Include Header Assets

First, add these links within the <head> tag of your HTML document to include the necessary CSS and Font Awesome:

<link rel="stylesheet" href="https://public.codepenassets.com/css/normalize-5.0.0.min.css">
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/@accessible360/accessible-slick@1.0.1/slick/slick.min.css'>
<link rel='stylesheet' href='https:////cdn.jsdelivr.net/npm/@accessible360/accessible-slick@1.0.1/slick/accessible-slick-theme.min.css'>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css'>

Step 2: Create the HTML Structure

Next, create the HTML structure for your image gallery. This involves creating containers for the thumbnail slider and the main image slider. Make sure to use descriptive alt attributes for your images.

<div class="product-image-carousels">
  <!-- Thumbnail track carousel -->
  <div class="thumbnails-slider">
    <button class="thumbnail-button" aria-current="true">
      <!-- Note that the alt attribute values describe the FUNCTION of the button, not the CONTENT of the image inside the button. -->
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/annie-spratt-500x500.jpg" alt="Go to image 1">
    </button>

    <button class="thumbnail-button">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/blanca-paloma-sanchez-500x500.jpg" alt="Go to image 2">
    </button>

    <button class="thumbnail-button">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/erol-ahmed-500x500.jpg" alt="Go to image 3">
    </button>

    <button class="thumbnail-button">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/armando-castillejo-500x500.jpg" alt="Go to image 4">
    </button>

    <button class="thumbnail-button">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/calle-macarone-500x500.jpg" alt="Go to image 5">
    </button>
  </div>


  <!-- Main image carousel -->
  <div class="main-image-slider">
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/annie-spratt-500x500.jpg" target="_blank" class="image-link">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/annie-spratt-500x500.jpg" alt="Extreme close up of a plant with flat leaves with rounded sides and pointy tips.">
    </a>
    
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/blanca-paloma-sanchez-500x500.jpg" target="_blank" class="image-link">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/blanca-paloma-sanchez-500x500.jpg" alt="Top view of at least 3 plants with flat leaves with rounded sides and pointy tips arranged radially.">
    </a>

    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/erol-ahmed-500x500.jpg" target="_blank" class="image-link">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/erol-ahmed-500x500.jpg" alt="Close-up top view of a single plant with flat leaves with rounded sides and pointy tips, showing small serrations along the leaf margins.">
    </a>

    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/armando-castillejo-500x500.jpg" target="_blank" class="image-link">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/armando-castillejo-500x500.jpg" alt="Close-up top view of a single plant with flat leaves with rounded sides and pointy tips, showing more pronounced serrations along the leaf margins.">
    </a>

    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/calle-macarone-500x500.jpg" target="_blank" class="image-link">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3609497/calle-macarone-500x500.jpg" alt="Close up of a plant showing a group of separate clusters of buds.">
    </a>
  </div>
</div>

<p class="note">Built with <a href="https://github.com/Accessible360/accessible-slick" target="_blank">accessible-slick</a>, a fully WCAG 2.0 / 2.1 compliant, drop-in replacement for Slick Slider!</p>

Step 3: Add CSS Styles

Now, add the following CSS to style your image gallery. This CSS handles the layout, appearance, and responsiveness of the sliders.

:root {
  --main-image-width: 500px;
  --main-image-height: 400px;
  --thumbnail-track-width: 90px;
  --thumbnail-height: 79px;
}

* {
  box-sizing: border-box;
}

body {
  background-color: #f5f5f5;
  padding: 20px;
}

.product-image-carousels {
  display: flex;
  justify-content: center;
}

/**
  Thumbnails carousel
*/
.thumbnails-slider {
  width: var(--thumbnail-track-width);
  padding: 30px 0;
  margin-right: 5px;
  /** Previous/next buttons */
  /** Single thumbnail */
}
.thumbnails-slider button {
  height: 30px;
  width: 100%;
  padding: 0;
  margin: 0;
  font-size: 30px;
  color: rgba(0, 0, 0, 0.7);
}
.thumbnails-slider button:not([disabled]):hover {
  background-color: rgba(0, 0, 0, 0.1);
  color: black;
}
.thumbnails-slider button:focus {
  background-color: royalblue;
}
.thumbnails-slider button:focus .slick-prev-icon,
.thumbnails-slider button:focus .slick-next-icon {
  color: white !important;
}
.thumbnails-slider button.slick-prev {
  top: 15px;
  left: 0;
}
.thumbnails-slider button.slick-prev .slick-prev-icon {
  display: inline-block;
  transform: rotate(90deg);
  color: black;
}
.thumbnails-slider button.slick-next {
  bottom: -15px;
  right: 0;
  top: auto;
}
.thumbnails-slider button.slick-next .slick-next-icon {
  display: inline-block;
  transform: rotate(90deg);
  color: black;
}
.thumbnails-slider .thumbnail-button {
  display: block;
  height: var(--thumbnail-height) !important;
  cursor: pointer;
  border: 0;
  background: none;
  background-color: rgba(0, 0, 0, 0.4);
  transition: opacity 0.1s linear;
}
.thumbnails-slider .thumbnail-button:focus img, .thumbnails-slider .thumbnail-button:hover img, .thumbnails-slider .thumbnail-button[aria-current=true] img {
  opacity: 1;
  filter: grayscale(0);
}
.thumbnails-slider .thumbnail-button:focus img {
  outline: 3px dashed white;
  outline-offset: -4px;
}
.thumbnails-slider .thumbnail-button img {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0.3;
  -o-object-fit: cover;
     object-fit: cover;
  filter: grayscale(0.6);
  transition: all 0.1s linear;
}

/**
  Main image carousel
*/
.main-image-slider {
  position: relative;
  width: var(--main-image-width);
  height: var(--main-image-height);
  position: relative;
  margin-bottom: 1px;
  /** Previous/next buttons */
  /** Slides */
}
.main-image-slider button {
  z-index: 1;
}
.main-image-slider button.slick-prev {
  left: 10px;
}
.main-image-slider button.slick-prev .slick-prev-icon {
  opacity: 1;
}
.main-image-slider button.slick-next {
  right: 10px;
}
.main-image-slider button.slick-next .slick-next-icon {
  opacity: 1;
}
.main-image-slider .slick-slide {
  width: var(--main-image-width);
}
.main-image-slider .slick-slide .image-link {
  height: var(--main-image-height);
  overflow: hidden;
  transition: outline 0.1s linear;
}
.main-image-slider .slick-slide .image-link:focus {
  outline: 4px dashed white;
  outline-offset: -7px;
}
.main-image-slider .slick-slide .image-link img {
  display: block;
  -o-object-fit: cover;
     object-fit: cover;
  width: 100%;
  height: 100%;
}

/**
  Demo only
*/
.note {
  text-align: center;
  font-size: 14px;
  width: var(--main-image-width);
  padding: 0 20px;
  margin: 0 auto;
  opacity: 0.8;
}
.note a {
  color: black;
  font-weight: bold;
}

Step 4: Include Footer Assets and JavaScript

Before closing the <body> tag, include the necessary JavaScript libraries and the custom JavaScript code to make the sliders functional.

<script src='https://code.jquery.com/jquery-3.5.1.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/@accessible360/accessible-slick@1.0.1/slick/slick.min.js'></script>
$(document).ready(function() {  
  /*********************
    Thumbnails slider
  *********************/
  // Change the main image whenever a thumbnail button is activated
  $('.thumbnails-slider').on('init', function(e, slider) {
    $(slider.$slides.find('.thumbnail-button')).each(function(index) {
      $(this).on('click', function() {
        // Move aria-current="true" to this button
        $(slider.$slides.find('.thumbnail-button').removeAttr('aria-current'));
        $(this).attr('aria-current', true);

        // Change the main image to match this thumbnail button
        var index = $(this).closest('.slick-slide').data('slick-index');
        $('.main-image-slider').slick('slickGoTo', index);
      });
    });
  });
  
  // Initialize the slider
  $('.thumbnails-slider').slick({
    vertical: true,
    slidesToShow: 4,
    infinite: false,
    instructionsText: 'This carousel contains a column of small thumbnails. Selecting a thumbnail will change the main image in the carousel that follows. Use the Previous and Next buttons to cycle through all the thumbnails, use Enter to select.',
    regionLabel: 'thumbnails carousel'
  });
  
  
  /********************
    Main image slider
  *********************/
  $('.main-image-slider').slick({
    slidesToShow: 1,
    draggable: false,
    instructionsText: 'This carousel shows one large product image at a time. Use the Previous and Next buttons to move between images, or use the preceding thumbnails carousel to select a specific image to display here.',
    regionLabel: 'main image carousel',
  });
  
    // Update the thumbnail slider when the user changes the main slider directly.
    $('.main-image-slider').on('beforeChange', function(e, slider, currentSlide, nextSlide) {
      // Remove aria-current from the last selected thumbnail image button
      $('.thumbnails-slider .thumbnail-button[aria-current="true"]').removeAttr('aria-current');
      
      // Select the thumbnail image button that goes with this main image. Most importantly, this updates Slick's internal state to be consistent with the visual change.
      $('.thumbnails-slider').slick('slickGoTo', nextSlide);

      // Add aria-current="true" to the correct thumbnail image button to convey to screen readers that it's active.
      $('.thumbnails-slider .thumbnail-button:eq(' + nextSlide + ')').attr('aria-current', true);
    }); 
});

Congratulations! You’ve successfully created an image gallery with a vertical thumbnail slider. Remember to replace placeholder images with your own.

Related Code Snippets:

Loading... ...

Loading preview...

Device: Desktop
Dimensions: 1200x800
Lines: 0 Characters: 0 Ln 1, Ch 1

Leave a Comment

About W3Frontend

W3Frontend provides free, open-source web design code and scripts to help developers and designers build faster. Every snippet is reviewed before publishing for quality. Learn more.