Image Gallery with Horizontal Scroll

CSSCSSBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we will delve into the world of CSS programming to create a responsive image gallery with a horizontal scroll. The purpose of this lab is to teach you how to use CSS properties to create a visually appealing and interactive gallery that allows users to scroll through images seamlessly. By the end of this lab, you will have a solid understanding of how to create a horizontal scrollable image gallery using CSS.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL css(("`CSS`")) -.-> css/BasicConceptsGroup(["`Basic Concepts`"]) css(("`CSS`")) -.-> css/BasicStylingGroup(["`Basic Styling`"]) css(("`CSS`")) -.-> css/CoreLayoutGroup(["`Core Layout`"]) css(("`CSS`")) -.-> css/AdvancedLayoutGroup(["`Advanced Layout`"]) css(("`CSS`")) -.-> css/IntermediateStylingGroup(["`Intermediate Styling`"]) css(("`CSS`")) -.-> css/CSSPreprocessorsGroup(["`CSS Preprocessors`"]) css/BasicConceptsGroup -.-> css/selectors("`Selectors`") css/BasicStylingGroup -.-> css/colors("`Colors`") css/CoreLayoutGroup -.-> css/margin_and_padding("`Margin and Padding`") css/CoreLayoutGroup -.-> css/borders("`Borders`") css/CoreLayoutGroup -.-> css/width_and_height("`Width and Height`") css/CoreLayoutGroup -.-> css/display_property("`Display Property`") css/CoreLayoutGroup -.-> css/positioning("`Positioning`") css/AdvancedLayoutGroup -.-> css/flexbox("`Flexbox`") css/AdvancedLayoutGroup -.-> css/grid_layout("`Grid Layout`") css/IntermediateStylingGroup -.-> css/backgrounds("`Backgrounds`") css/CSSPreprocessorsGroup -.-> css/nesting("`Nesting`") css/IntermediateStylingGroup -.-> css/pseudo_elements("`Pseudo-elements`") subgraph Lab Skills css/selectors -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/colors -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/margin_and_padding -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/borders -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/width_and_height -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/display_property -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/positioning -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/flexbox -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/grid_layout -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/backgrounds -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/nesting -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} css/pseudo_elements -.-> lab-35210{{"`Image Gallery with Horizontal Scroll`"}} end

index.html and style.css have already been provided in the VM.

Here are the instructions for creating a horizontally scrollable image gallery:

  1. To position the .thumbnails at the bottom of the container, set position: absolute; bottom: 8px; for the .thumbnails class.
  2. To create a snap effect on horizontal scroll, use scroll-snap-type: x mandatory and overscroll-behavior-x: contain. Snap elements to the start of the container using scroll-snap-align: start.
  3. Hide scrollbars by setting scrollbar-width: none. To style the pseudo-element ::-webkit-scrollbar, add display: none;.
  4. Define a scrollToElement function using Element.scrollTo() that scrolls the gallery to the given item.
  5. Populate the .thumbnails element using Array.prototype.map() and Array.prototype.join(). Give each thumbnail a data-id attribute with the index of the image.
  6. Register a handler for the 'click' event on each thumbnail using Document.querySelectorAll() and Array.prototype.forEach(). Use EventTarget.addEventListener() and the scrollToElement function.
  7. Register a handler for the 'scroll' event using Document.querySelector() and EventTarget.addEventListener(). Update the .thumbnails element to match the current scroll position using the highlightThumbnail function.

Here is the HTML code for the gallery:

<div class="gallery-container">
  <div class="thumbnails"></div>
  <div class="slides">
    <div><img src="https://picsum.photos/id/1067/540/720" /></div>
    <div><img src="https://picsum.photos/id/122/540/720" /></div>
    <div><img src="https://picsum.photos/id/188/540/720" /></div>
    <div><img src="https://picsum.photos/id/249/540/720" /></div>
    <div><img src="https://picsum.photos/id/257/540/720" /></div>
    <div><img src="https://picsum.photos/id/259/540/720" /></div>
    <div><img src="https://picsum.photos/id/283/540/720" /></div>
    <div><img src="https://picsum.photos/id/288/540/720" /></div>
    <div><img src="https://picsum.photos/id/299/540/720" /></div>
  </div>
</div>

Here is the CSS code for the gallery:

.gallery-container {
  position: relative;
  display: flex;
  justify-content: center;
}

.thumbnails {
  position: absolute;
  bottom: 8px;
  display: flex;
  flex-direction: row;
  gap: 6px;
}

.thumbnails div {
  width: 8px;
  height: 8px;
  cursor: pointer;
  background: #aaa;
  border-radius: 100%;
}

.thumbnails div.highlighted {
  background-color: #777;
}

.slides {
  margin: 0 16px;
  display: grid;
  grid-auto-flow: column;
  gap: 1rem;
  width: 540px;
  padding: 0 0.25rem;
  height: 720px;
  overflow-y: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.slides > div {
  scroll-snap-align: start;
}

.slides img {
  width: 540px;
  object-fit: contain;
}

.slides::-webkit-scrollbar {
  display: none;
}

And here is the JavaScript code for the gallery:

const slideGallery = document.querySelector(".slides");
const slides = slideGallery.querySelectorAll("div");
const thumbnailContainer = document.querySelector(".thumbnails");
const slideCount = slides.length;
const slideWidth = 540;

const highlightThumbnail = () => {
  thumbnailContainer
    .querySelectorAll("div.highlighted")
    .forEach((el) => el.classList.remove("highlighted"));
  const index = Math.floor(slideGallery.scrollLeft / slideWidth);
  thumbnailContainer
    .querySelector(`div[data-id="${index}"]`)
    .classList.add("highlighted");
};

const scrollToElement = (el) => {
  const index = parseInt(el.dataset.id, 10);
  slideGallery.scrollTo(index * slideWidth, 0);
};

thumbnailContainer.innerHTML += [...slides]
  .map((slide, i) => `<div data-id="${i}"></div>`)
  .join("");

thumbnailContainer.querySelectorAll("div").forEach((el) => {
  el.addEventListener("click", () => scrollToElement(el));
});

slideGallery.addEventListener("scroll", (e) => highlightThumbnail());

highlightThumbnail();

Please click on 'Go Live' in the bottom right corner to run the web service on port 8080. Then, you can refresh the Web 8080 Tab to preview the web page.

Summary

Congratulations! You have completed the Image Gallery With Horizontal Scroll lab. You can practice more labs in LabEx to improve your skills.

Other CSS Tutorials you may like