Handy libraries

Swiper.js

Swiper.js is a JavaScript library offering a touch-enabled, responsive, free and lightweight touch and scroll slider. It is fully customizable and supports many use cases. It requires minimal JavaScript, CSS, and a simple HTML structure. To set up a Swiper slider, either download the package and link the CSS and JS files, fetch the files from the CDN. Depending on which functionalities you want to use, you might need to import additional files.

<!-- Link the downloaded files -->
<script src="/assets/js/swiper/swiper-bundle.min.js"></script>
<link rel="stylesheet" href="/assets/js/swiper/swiper-bundle.min.css"">

<!-- or Import from CDN -->
<script src="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css"">

Here is a basic example of a Swiper with draggable slides:

<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">
      <img src="assets/media/placeholder-a.jpg" alt="…" />
    </div>
    <div class="swiper-slide">
      <img src="assets/media/placeholder-b.jpg" alt="…" />
    </div>
    <div class="swiper-slide">
      <img src="assets/media/placeholder-c.jpg" alt="…" />
    </div>
    <div class="swiper-slide">
      <img src="assets/media/placeholder-d.jpg" alt="…" />
    </div>
    <div class="swiper-slide">
      <img src="assets/media/placeholder-e.jpg" alt="…" />
    </div>
    <div class="swiper-slide">
      <img src="assets/media/placeholder-f.jpg" alt="…" />
    </div>
  </div>
</div>
+
.swiper {
  width: 100%;
  aspect-ratio: 3/2;
}
+
const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  // Add the grab cursor
  grabCursor: true,
});

Swiper.js is very flexible, and you can add more features to your slider, such as pagination indicators, navigation buttons, scrollbars, and more. Here is a more complex example combining and customising some of these features:

<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">
      <img src="assets/media/placeholder-a.jpg" alt="…" />
    </div>
    …
  </div>

  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>

  <!-- Added for the navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>
+
/* Styling the navigation buttons */
.swiper-pagination,
.swiper-button-prev,
.swiper-button-next {
  color: deeppkin;
  user-select: none; /* Disable selection if clicking too fast */
  font-weight: bold;
}
+
// Create the Swiper
const swiper = new Swiper(".swiper", {
  direction: "horizontal",
  loop: true,

  // Add mousewheel support
  mousewheel: true,
  
  // Enable the navigation buttons
  navigation: {
    addIcons: false, // Disable the default navigation icons
    nextEl: ".swiper-button-next",
    prevEl: ".swiper-button-prev",
  },

  // Enable the pagination
  pagination: {
    el: ".swiper-pagination",
    type: "fraction",
  },
});
              

Scrollama.js

Scrollama.js is a lightweight, dependency-free, vanilla JavaScript for creating scroll-driven animations. It lets you run a function when the desired element enters or leaves the viewport, and when the element progresses through a seciton of it. To use it, simply fetch the JS file and link it to your page:

<script src="https://unpkg.com/scrollama"></script>

Here a basic example rotating and changing the hue of an image as the element enters the page:

<!-- A class to be used for the animation -->
<div class="scrollama-step">
  <img src="assets/media/placeholder-a.jpg" alt="…" />
</div>
+
// Create the Scrollama instance
const scrollama = scrollama();

// Setup the instance, pass callback functions
scrollama
  .setup({
    step: ".scrollama-step", // the class or id of the element to be animated
    progress: true, // enable the progress indicator
    offset: .9, // where the scroll should be observed
  })
  // The callback function for every step progress event
  .onStepProgress((arguments) => {

    // Extract the required values from the arguments object
    // The progress value is a number between 0 and 1
    const { element, progress } = arguments;

    // Set the hue of the image
    element.style.filter = "hue-rotate(" + progress + "turn)";
    element.style.rotate = (1 - progress) ** 2 + "turn";
    img.style.scale = (1 - progress) ** 2;
  })
…

Scrollama can also be very usefull to update a nagivation bar, since you trigger the callback function when the element enters a section of the page. Here an example adding the active class to the navigation item:

<div class="layout-wrapper">
  <nav>
    <ul>
      <!-- custom `data-id` attribute to select it more easily -->
      <li data-id="placeholder-a">A</li>
      <li data-id="placeholder-b">B</li>
      <li data-id="placeholder-c">C</li>
      <li data-id="placeholder-d">D</li>
    </ul>
  </nav>
  <div class="scroll-container">
    <!-- each image has the id of the navigation item it belongs to -->
    <img id="placeholder-a" class="scrollama-step" src="assets/media/placeholder-a.jpg" />
    <img id="placeholder-b" class="scrollama-step" src="assets/media/placeholder-b.jpg" />
    <img id="placeholder-c" class="scrollama-step" src="assets/media/placeholder-c.jpg" />
    <img id="placeholder-d" class="scrollama-step" src="assets/media/placeholder-d.jpg" />
  </div>
</div>
+
const scrollama = scrollama();
scrollama
  .setup({
    step: ".scrollama-step",
    container: ".scroll-container",
  })
  .onStepEnter((response) => {
    const { element, index, direction } = response;

    // Remove the active class from all the navigation items
    document.querySelectorAll(".active").forEach((item) => item.classList.remove("active"));

    // Add the active class to the navigation item
    const navItem = document.querySelector(`nav li[data-id="${element.id}"]`);
    navItem.classList.add("active");
  });

Lozad.js

Lozad.js is a beginner-friendly, lightweight and high-performance JavaScript library for lazy loading images. To use it, fetch the JS file and link it to your page:

<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>

Lozad.js work both with static images and responsive images. Here is how to use it:

<!-- lazy load a static image -->
<img class="lozad" data-src="assets/media/placeholder-b.jpg" alt="…" />

<!-- lazy load a responsive image -->
<img 
  class="lozad" 
  data-src="assets/media/placeholder-e.jpg" 
  data-srcset="assets/media/resized/placeholder-e-480w.jpg 480w, 
               assets/media/resized/placeholder-e-800w.jpg 800w, 
               assets/media/resized/placeholder-e-1200w.jpg 1200w, 
               assets/media/resized/placeholder-e-1920w.jpg 1920w, 
               assets/media/resized/placeholder-e-2560w.jpg 2560w" 
  alt="…" />

<!-- lazy load a responsive image with multiple sources -->
<picture>
  <source 
    class="lozad" 
    data-srcset="assets/media/resized/placeholder-f-480w.webp 480w, 
                 assets/media/resized/placeholder-f-800w.webp 800w, 
                 assets/media/resized/placeholder-f-1200w.webp 1200w, 
                 assets/media/resized/placeholder-f-1920w.webp 1920w, 
                 assets/media/resized/placeholder-f-2560w.webp 2560w" 
    type="image/webp" />
  <source 
    class="lozad" 
    data-srcset="assets/media/resized/placeholder-f-480w.jpg 480w, 
                 assets/media/resized/placeholder-f-800w.jpg 800w, 
                 assets/media/resized/placeholder-f-1200w.jpg 1200w, 
                 assets/media/resized/placeholder-f-1920w.jpg 1920w, 
                 assets/media/resized/placeholder-f-2560w.jpg 2560w" 
    type="image/jpeg" />
  <img class="lozad" data-src="assets/media/placeholder-f.jpg" alt="…" />
</picture>
+
const observer = lozad(); // lazy loads elements with default selector as '.lozad'
observer.observe();
… … …

Neodrag.js

Neodrag.js is a lightweight, dependency-free, vanilla JavaScript library for rendering elements draggable. It supports both mouse and touch. It allows you to define a drag handle, add bounds, limit the axis of movement, and more. To use it, fetch the JS file and link it to your page:

<script src="https://unpkg.com/@neodrag/vanilla@latest/dist/umd/index.js"></script>

Here is a basic example of a draggable element limited to the bounds of its parent:

<span class="draggable">Drag me</span>
+
const draggableElement = document.querySelector('.draggable');
const drag = new NeoDrag.Draggable(
  draggableElement,
  {
    axis: 'both', // Default value
    bounds: 'parent'
    defaultPosition: {
      x: Math.random() * (
        draggableElement.parentElement.clientWidth - 
        draggableElement.clientWidth
      ),
      y: Math.random() * (
        draggableElement.parentElement.clientHeight - 
        draggableElement.clientHeigh
      t)
    }
  }
);
Drag me!