Image Gallery With Vertical Scroll

CSSCSSBeginner
Practice Now

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

Introduction

In this lab, we will explore the basics of CSS programming by creating a simple image gallery with a vertical scroll. You will learn how to use flexbox and scroll-snap properties to create a smooth scroll effect, hide scrollbars, and style the scrollbar thumb. By the end of this lab, you will have gained a better understanding of how to use CSS to create responsive and interactive web designs.


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/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-35255{{"`Image Gallery With Vertical Scroll`"}} css/colors -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/margin_and_padding -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/width_and_height -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/display_property -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/positioning -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/flexbox -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/grid_layout -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/backgrounds -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/nesting -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} css/pseudo_elements -.-> lab-35255{{"`Image Gallery With Vertical Scroll`"}} end

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

This code creates a horizontally scrollable image gallery. The following steps are taken:

  1. The layout for the container is set up using display: flex and justify-content: center.
  2. The layout for the slides is set up using display: flex and flex-direction: column.
  3. A snap effect is created on vertical scroll using scroll-snap-type: y mandatory and overscroll-behavior-y: contain. Elements are snapped to the start of the container using scroll-snap-align: start.
  4. Scrollbars are hidden using scrollbar-width: none and styling the pseudo-element ::-webkit-scrollbar to display: none.
  5. A scrollToElement function is defined using Element.scrollTo() to scroll the gallery to the given item.
  6. The .thumbnails element is populated using Array.prototype.map() and Array.prototype.join(). Each thumbnail is given a data-id attribute with the index of the image.
  7. A handler for the 'click' event is registered on each thumbnail using Document.querySelectorAll(), Array.prototype.forEach(), EventTarget.addEventListener(), and the scrollToElement function.
  8. A handler for the 'scroll' event is registered using Document.querySelector() and EventTarget.addEventListener(). The .thumbnails and .scrollbar elements are updated to match the current scroll position using the scrollThumb function.

HTML:

<div class="gallery-container">
  <div class="thumbnails"></div>
  <div class="scrollbar">
    <div class="thumb"></div>
  </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>

CSS:

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

.thumbnails {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.thumbnails img {
  width: 40px;
  height: 40px;
  cursor: pointer;
}

.scrollbar {
  width: 1px;
  height: 720px;
  background: #ccc;
  display: block;
  margin: 0 0 0 8px;
}

.thumb {
  width: 1px;
  position: absolute;
  height: 0;
  background: #000;
}

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

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

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

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

JavaScript:

const slideGallery = document.querySelector(".slides");
const slides = slideGallery.querySelectorAll("div");
const scrollbarThumb = document.querySelector(".thumb");
const slideCount = slides.length;
const slideHeight = 720;
const marginTop = 16;

const scrollThumb = () => {
  const index = Math.floor(slideGallery.scrollTop / slideHeight);
  scrollbarThumb.style.height = `${((index + 1) / slideCount) * slideHeight}px`;
};

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

document.querySelector(".thumbnails").innerHTML += [...slides]
  .map(
    (slide, i) => `<img src="${slide.querySelector("img").src}" data-id="${i}">`
  )
  .join("");

document.querySelectorAll(".thumbnails img").forEach((el) => {
  el.addEventListener("click", () => scrollToElement(el));
});

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

scrollThumb();

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 Vertical Scroll lab. You can practice more labs in LabEx to improve your skills.

Other CSS Tutorials you may like