LISN.js

Edit on StackBlitz

"use client";
import {
  PagerComponent,
  PagerPageComponent,
  PagerSwitchComponent,
} from "@lisn.js/react";
// Don't load the default pager CSS otherwise we'd have to override quite a few
// properties. We need to set custom style for everything anyway.
// import "lisn.js/pager.css";

import Image from "next/image";

import styles from "./demo.module.css";

export default function Page() {
  return (
    <>
      <div className={styles.wrapper}>
        <PagerComponent className={styles.demo} config={{ useGestures: false }}>
          <div className={styles.tabs}>
            <PagerSwitchComponent className={styles.tab}>
              Limitless
            </PagerSwitchComponent>
            <PagerSwitchComponent className={styles.tab}>
              Imaginative
            </PagerSwitchComponent>
            <PagerSwitchComponent className={styles.tab}>
              Sleek
            </PagerSwitchComponent>
            <PagerSwitchComponent className={styles.tab}>
              Neoteric
            </PagerSwitchComponent>
          </div>

          <div className={styles.pages}>
            <PagerPageComponent className={styles.page}>
              {/* https://unsplash.com/photos/a-purple-and-green-abstract-background-with-lots-of-lines-pEgsWN0kwbQ */}
              <Image
                className={styles.background}
                src="/images/abstract-4.jpg"
                alt=""
              />
            </PagerPageComponent>

            <PagerPageComponent className={styles.page}>
              {/* https://unsplash.com/photos/purple-black-and-orange-abstract-paintin-arwTpnIUHdM */}
              <Image
                className={styles.background}
                src="/images/abstract-3.jpg"
                alt=""
              />
            </PagerPageComponent>

            <PagerPageComponent className={styles.page}>
              {/* https://unsplash.com/photos/a-very-long-line-of-yellow-lines-on-a-black-background-YeUVDKZWSZ4 */}
              <Image
                className={styles.background}
                src="/images/abstract-2.jpg"
                alt=""
              />
            </PagerPageComponent>

            <PagerPageComponent className={styles.page}>
              {/* https://unsplash.com/photos/a-close-up-of-a-red-and-black-substance-OOFSqPWjCt0 */}
              <Image
                className={styles.background}
                src="/images/abstract-1.jpg"
                alt=""
              />
            </PagerPageComponent>
          </div>
        </PagerComponent>
      </div>
    </>
  );
}
/* Container */
.wrapper {
  --animate-duration: 0.4s;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  width: 100dvw;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* Pager and pages */
.demo {
  max-height: 100%;
  width: 800px;
  max-width: 100%;
  z-index: 0;
}

.pages {
  height: 400px;
  box-shadow: var(--lisn-shadow);
  position: relative;
}

.page {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  transition-property: opacity;
  transition-duration: 0.3s;
  opacity: 0;
}

.page[data-lisn-page-state="current"] {
  opacity: 1;
}

/* Tabs */
.tabs {
  position: relative;
  display: flex;
  gap: 1vw;
  margin-bottom: -5px;
  z-index: -1;
}

.tab {
  --btn-color: #14061b;
  color: #ddd;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
  background: var(--btn-color);
  padding: 8px;
  padding-bottom: 11px;
  border: none;
  border-radius: 5px;
  transform: scale(0.9);
  transition-property: transform;
  transition-duration: 0.3s;
}

.tab:hover {
  --btn-color: #210d2b;
}

.tab[data-lisn-page-state="current"] {
  --btn-color: #392743;
  color: #fff;
  transform: scale(1);
}

.tab:first-letter {
  font-size: 1.3em;
  font-weight: 800;
}

/* Page content */
.pages,
.background {
  border-radius: 15px;
}

.background {
  pointer-events: none;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow-clip-margin: unset;
}

Edit on CodePen

document.addEventListener("DOMContentLoaded", () => {
  const pager = document.getElementById("demo");
  const pages = pager.querySelectorAll(".page");
  const switches = pager.querySelectorAll(".switch");
  new LISN.widgets.Pager(pager, {
    pages,
    switches,
    useGestures: false,
  });
});
<div id="demo">
  <div class="tabs">
    <button class="switch">Limitless</button>
    <button class="switch">Imaginative</button>
    <button class="switch">Sleek</button>
    <button class="switch">Neoteric</button>
  </div>

  <div class="pages">
    <div class="page">
      <!-- https://unsplash.com/photos/a-purple-and-green-abstract-background-with-lots-of-lines-pEgsWN0kwbQ -->
      <img class="background" src="images/abstract-4.jpg" alt="" />
    </div>

    <div class="page">
      <!-- https://unsplash.com/photos/purple-black-and-orange-abstract-paintin-arwTpnIUHdM -->
      <img class="background" src="images/abstract-3.jpg" alt="" />
    </div>

    <div class="page">
      <!-- https://unsplash.com/photos/a-very-long-line-of-yellow-lines-on-a-black-background-YeUVDKZWSZ4 -->
      <img class="background" src="images/abstract-2.jpg" alt="" />
    </div>

    <div class="page">
      <!-- https://unsplash.com/photos/a-close-up-of-a-red-and-black-substance-OOFSqPWjCt0 -->
      <img class="background" src="images/abstract-1.jpg" alt="" />
    </div>
  </div>
</div>
/* Pager and pages */
#demo {
  max-height: 100%;
  width: 800px;
  max-width: 100%;
  z-index: 0;
}

#demo .pages {
  height: 400px;
  box-shadow: var(--lisn-shadow);
}

#demo .page {
  box-shadow: none;
  transform: none !important;
  height: 100%;
  transition-property: opacity;
  transition-duration: 0.3s;
  opacity: 0;
}

#demo .page[data-lisn-page-state="current"] {
  opacity: 1;
}

/* Tabs */
#demo .tabs {
  position: relative;
  display: flex;
  gap: 1vw;
  margin-bottom: -5px;
  z-index: -1;
}

#demo .tabs button {
  --btn-color: #14061b;
  color: #ddd;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
  background: var(--btn-color);
  padding: 8px;
  padding-bottom: 11px;
  border: none;
  border-radius: 5px;
  transform: scale(0.9);
  transition-property: transform;
  transition-duration: 0.3s;
}

#demo .tabs button:hover {
  --btn-color: #210d2b;
}

#demo .tabs .switch[data-lisn-page-state="current"] {
  --btn-color: #392743;
  color: #fff;
  transform: scale(1);
}

#demo .switch:first-letter {
  font-size: 1.3em;
  font-weight: 800;
}

/* Page content */
#demo,
#demo .page .background {
  border-radius: 15px;
}

#demo .page .background {
  pointer-events: none;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow-clip-margin: unset;
}

Edit on CodePen

<div id="demo" data-lisn-pager="use-gestures=false">
  <div class="tabs">
    <button data-lisn-pager-switch>Limitless</button>
    <button data-lisn-pager-switch>Imaginative</button>
    <button data-lisn-pager-switch>Sleek</button>
    <button data-lisn-pager-switch>Neoteric</button>
  </div>

  <div class="pages">
    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/a-purple-and-green-abstract-background-with-lots-of-lines-pEgsWN0kwbQ -->
      <img class="background" src="images/abstract-4.jpg" alt="" />
    </div>

    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/purple-black-and-orange-abstract-paintin-arwTpnIUHdM -->
      <img class="background" src="images/abstract-3.jpg" alt="" />
    </div>

    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/a-very-long-line-of-yellow-lines-on-a-black-background-YeUVDKZWSZ4 -->
      <img class="background" src="images/abstract-2.jpg" alt="" />
    </div>

    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/a-close-up-of-a-red-and-black-substance-OOFSqPWjCt0 -->
      <img class="background" src="images/abstract-1.jpg" alt="" />
    </div>
  </div>
</div>
/* Pager and pages */
#demo {
  max-height: 100%;
  width: 800px;
  max-width: 100%;
  z-index: 0;
}

#demo .pages {
  height: 400px;
  box-shadow: var(--lisn-shadow);
}

#demo [data-lisn-pager-page] {
  box-shadow: none;
  transform: none !important;
  height: 100%;
  transition-property: opacity;
  transition-duration: 0.3s;
  opacity: 0;
}

#demo [data-lisn-pager-page][data-lisn-page-state="current"] {
  opacity: 1;
}

/* Tabs */
#demo .tabs {
  position: relative;
  display: flex;
  gap: 1vw;
  margin-bottom: -5px;
  z-index: -1;
}

#demo .tabs button {
  --btn-color: #14061b;
  color: #ddd;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
  background: var(--btn-color);
  padding: 8px;
  padding-bottom: 11px;
  border: none;
  border-radius: 5px;
  transform: scale(0.9);
  transition-property: transform;
  transition-duration: 0.3s;
}

#demo .tabs button:hover {
  --btn-color: #210d2b;
}

#demo .tabs [data-lisn-pager-switch][data-lisn-page-state="current"] {
  --btn-color: #392743;
  color: #fff;
  transform: scale(1);
}

#demo [data-lisn-pager-switch]:first-letter {
  font-size: 1.3em;
  font-weight: 800;
}

/* Page content */
#demo,
#demo [data-lisn-pager-page] .background {
  border-radius: 15px;
}

#demo [data-lisn-pager-page] .background {
  pointer-events: none;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow-clip-margin: unset;
}
Limitless
Imaginative
Sleek
Neoteric