JSFiddle - React, Tailwind, and code Playground

HTML

<div class="carousel">
  <img class="slide" src="https://source.unsplash.com/random?1" />
  <img class="slide" src="https://source.unsplash.com/random?2" />
  <img class="slide" src="https://source.unsplash.com/random?3" />
  <img class="slide" src="https://source.unsplash.com/random?4" />
  <img class="slide" src="https://source.unsplash.com/random?5" />
</div>

SCSS

$max_carousel_slides: 20;
$fade_in_duration: 1000;
$display_duration: 3000;

@for $i from 2 through $max_carousel_slides {
  $total_duration: ( $display_duration + $fade_in_duration ) * $i;
  .carousel > .slide:nth-last-child(#{$i}):first-child {
    animation: carousel-slide-#{$i};
    animation-delay: $fade_in_duration * 1ms;
    animation-duration: $total_duration * 1ms;
    animation-fill-mode: forwards;
    animation-iteration-count: infinite;
  }
  @keyframes carousel-slide-#{$i} {
    0% { left: 0; }
    49.9% { left: 0; }
    50% { left: $i * 100%; }
    100% { left: $i * 100%; }
    @for $j from 1 through $i {
      $fade_in_end_percent: ( $display_duration + $fade_in_duration ) * $j / $total_duration * 100;
      $fade_in_start_percent: $fade_in_end_percent - $fade_in_duration / $total_duration * 100;
      $margin_percent_last: -($j - 1) * 100%;
      $margin_percent_next: -$j * 100%;
      #{$fade_in_start_percent}% {
        margin-left: $margin_percent_last;
      }
      #{$fade_in_end_percent}% {
        margin-left: $margin_percent_next;
      }
    }
  }
}

.carousel {
  height: 33vw;
  padding: 0;
  white-space: nowrap;
  font-size: 0;
  overflow: hidden;
}

.carousel > .slide {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
  object-fit: cover;
  font-size: 1rem;
  background-color: #ccc;
}