JSFiddle - React, Tailwind, and code Playground

by HDL52

HTML

<div id="grid-container">
  <div class="grid">
    <div class="row forward">
      <div class="box fill1"></div>
      <div class="box fill2 "></div>
      <div class="box fill3"></div>
      <div class="box fill4 in-viewport"></div>

      <div class="box fill1"></div>
      <div class="box fill2"></div>
      <div class="box fill3"></div>
      <div class="box fill4"></div>
    </div>

    <div class="row backward">
      <div class="box fill1"></div>
      <div class="box fill2"></div>
      <div class="box fill3"></div>
      <div class="box fill4"></div>

      <div class="box fill1 "></div>
      <div class="box fill2"></div>
      <div class="box fill3"></div>
      <div class="box fill4"></div>
    </div>
  </div>
</div>

CSS

:root {
  --noItems: 4;
  --itemsWidth: 130px;
  --gap: 10px;
  --marqueeSpeed: 20s;
  --containerBG: #233d4d;
  --fill1: #fe7f2d;
  --fill2: #fcca46;
  --fill3: #a1c181;
  --fill4: #619b8a;
}

body {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: #151515;
}

#grid-container {
  width: calc(calc(var(--noItems) * calc(var(--itemsWidth) + var(--gap))));

  border: var(--gap) solid var(--containerBG);
  overflow: hidden;
  background: var(--containerBG);
  border-radius: var(--gap);
}

.grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-row-gap: var(--gap);
  width: 200%;
  /* ❗️as having 2 sets of items per row❗️*/
}

.row {
  display: flex;
  overflow: hidden;
}

.box {
  width: var(--itemsWidth);
  height: 100px;
  margin-right: var(--gap);
  border-radius: var(--gap);
}

.fill1 {
  background-color: var(--fill1);
}

.fill2 {
  background-color: var(--fill2);
}

.fill3 {
  background-color: var(--fill3);
}

.fill4 {
  background-color: var(--fill4);
}

.forward {
  animation: forward-marquee var(--marqueeSpeed) linear infinite;
}

.backward {
  animation: backward-marquee var(--marqueeSpeed) linear infinite;
}

@keyframes forward-marquee {
  0% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(-50%);
  }
}

@keyframes backward-marquee {
  0% {
    transform: translateX(-50%);
  }

  100% {
    transform: translateX(0);
  }
}

JavaScript

// https://codepen.io/BarbWire/pen/gOEbgVe