<label class="checkbox">
  <input type="checkbox" id="overflow" checked /> Hide image overflow
</label>

<div class="container">
  <h2 class="title">Welcome to the Snuggle Zone</h2>
  <div class="carousel-viewport">
    <ul class="items">
      <li class="item">
        <img src='https://images.unsplash.com/photo-1611003228577-e610e9a727c5?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMjgzMzExNw&ixlib=rb-1.2.1&q=80&w=1200' width="1200" height="675" alt=''>
      </li>
      <li class="item">
        <img src='https://images.unsplash.com/photo-1611507929918-08ee0bcb42d7?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMzE4OTc4OQ&ixlib=rb-1.2.1&q=80&w=1200' width="1200" height="675" alt=''>
      </li>
      <li class="item">
        <img src='https://images.unsplash.com/photo-1589441161120-8781d5644435?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMzE4NzY1MQ&ixlib=rb-1.2.1&q=80&w=1200' width="1200" height="675" alt=''>
      </li>
      <li class="item">
        <img src='https://images.unsplash.com/photo-1518914781460-a3ada465edec?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYyMzE4OTg0MA&ixlib=rb-1.2.1&q=80&w=1200' width="1200" height="675" alt=''>
      </li>
    </ul>
  </div>
  <button class="carousel-control prev" title="Go to previous item">
    <svg viewBox="0 0 256 512">
      <path d="M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z" />
    </svg>
  </button>
  <button class="carousel-control next" title="Go to next item">
    <svg viewBox="0 0 256 512">
      <path d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z" />
    </svg>
  </button>
  <ol class="carousel-dots">
    <li class="dot active">1</li>
    <li class="dot">2</li>
    <li class="dot">3</li>
    <li class="dot">4</li>
  </ol>
</div>
@import url("https://fonts.googleapis.com/css2?family=Gorditas&display=swap");

.container {
  display: grid;
  grid-template: "container" 1fr;
  place-items: center;
  place-content: center;
  overflow: hidden;
  max-height: clamp(450px, 50vh, 600px);
}

.container > * {
  grid-area: container;
  max-width: 1000px;
}

.title {
  place-self: start center;
}

.carousel-control.prev {
  place-self: center left;
}

.carousel-control.next {
  place-self: center right;
}

.carousel-dots {
  place-self: end center;
}

/* Other element styles */

* {
  box-sizing: border-box;
}

body {
  --space: 6rem;
  --bg-color: papayawhip;
  display: grid;
  place-items: center;
  padding: var(--space) 0;
  grid-gap: var(--space);
  background-color: var(--bg-color);
  font-family: "Helvetica", sans-serif;
  line-height: 1.2;
}

.checkbox {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1;
  cursor: pointer;
  user-select: none;
  background-color: inherit;
  padding: 1rem;
  opacity: 0.9;
}

.container {
  --border: 4px dashed dodgerblue;
  position: relative;
  border-top: var(--border);
  border-bottom: var(--border);
  margin: 0 auto;
  width: 100%;
  color: white;
}

.title {
  position: relative;
  font-family: "Gorditas", sans-serif;
  font-size: clamp(1rem, 4vw, 2.5rem);
  padding: 1rem;
  text-align: center;
  z-index: 1;
}

.carousel-viewport {
  position: relative;
  overflow: hidden;
  margin: 0 auto;
  z-index: -1;
}

.carousel-viewport .items {
  position: relative;
  display: flex;
  transition: transform 500ms cubic-bezier(0.25, 1, 0.5, 1);
}

.carousel-viewport .item {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  min-width: 100%;
  transform: translateZ(0);
}

.carousel-viewport img {
  object-fit: cover;
  width: 100%;
  height: 100%;
  user-select: none;
}

.carousel-control {
  --size: clamp(2.5rem, 8vw, 4rem);

  position: relative;
  cursor: pointer;
  display: flex;
  align-content: center;
  justify-content: center;
  color: white;
  fill: currentcolor;
  background: dodgerblue;
  border: none;
  width: var(--size);
  height: var(--size);
  padding: 0.25rem;
  touch-action: manipulation;
  transform: translateY(0);
}

.carousel-control:active {
  transform: translateY(1px);
}

.carousel-control svg {
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.carousel-dots {
  display: flex;
  gap: 1rem;
  padding: 1rem;
}

.carousel-dots .dot {
  --size: 1rem;
  padding: 0;
  font-size: 0;
  color: transparent;
  border: 3px solid white;
  background-color: white;
  border-radius: 50%;
  width: var(--size);
  height: var(--size);
}

.carousel-dots .dot.active {
  background-color: dodgerblue;
}

/* aspect-ratio fallback */
@supports not (aspect-ratio: 16 / 9) {
  .carousel-viewport .item::before {
    content: "";
    float: left;
    padding-top: 56.25%;
  }

  .carousel-viewport .item::after {
    content: "";
    display: block;
    clear: both;
  }
}
/* Overflow toggle */
const hideOverflow = document.getElementById("overflow");

hideOverflow.addEventListener("click", () => {
  document.querySelector(".container").style.overflow = hideOverflow.checked
    ? "hidden"
    : "visible";
});

/* Carousel */
const items = document.querySelector(".items");
const dots = document.querySelectorAll(".dot");
const prev = document.querySelector(".prev");
const next = document.querySelector(".next");
const total = items.children.length - 1;
const active = "active";
let current = 0;

const setActiveDot = () => {
  dots.forEach((button, i) => {
    i === current
      ? button.classList.add(active)
      : button.classList.remove(active);
  });
};

const scrollToCurrent = () => {
  items.style.transform = `translateX(${current * -100}%`;
  setActiveDot();
};

const scrollPrev = () => {
  if (current === 0) return;
  current--;
  scrollToCurrent();
};

const scrollNext = () => {
  if (current === total) return;
  current++;
  scrollToCurrent();
};

prev.addEventListener("click", scrollPrev);
next.addEventListener("click", scrollNext);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.