-var elCount = 5

.carousel
  .carousel__stage
    -for(var n = 0; n < elCount; n++)
      input.carousel__item-input(
        type="radio"
        name="item"
        id="input_" + n
        checked=n === 0
      )
    -for(var n = 0; n < elCount; n++)
      .carousel__item-content #{n + 1}
    -for(var n = 0; n < elCount; n++)
      label.carousel__item-label(
        for="input_" + n
      )
      
View Compiled
$elCount: 5
$black: #191919
$red: #F15025
$grey: #E6E8E6
$dots: 6px

.carousel
  margin: auto
  width: 60vmin
  height: 35vmin
  background: $black
  position: relative
  box-shadow: 20px 20px $red
  
  &:before,
  &:after
    position: absolute
    font-size: 12px
    color: white
    text-align: center
    width: 100%

  &:before
    content: 'Pure CSS carousel'
    bottom: calc(100% + 4px)
    
  &:after
    content: 'Click on the dots to change slides'
    position: absolute
    top: calc(100% + 4px)
    animation: blink 0.6s ease infinite

  &__stage
    height: 100%
    overflow: hidden
    position: relative
  
  &__item
    &-input
      opacity: 0
      pointer-events: none
      position: absolute
      top: -9999px
      left: -9999px
      @for $n from 1 through $elCount
        &:nth-child(#{$n}):checked
          & ~ .carousel__item-label:nth-child(#{$elCount * 2 + $n})
            background: $red
            &:before
              display: block
          @for $j from 1 through $elCount
            & ~ .carousel__item-content:nth-child(#{$elCount + $j})
              transform: translate(#{-100% * ($n - $j)})
  
    &-content
      box-sizing: border-box
      width: 100%
      height: 100%
      position: absolute
      top: 0
      left: 0
      transition: transform 0.4s cubic-bezier(0.6, -0.28, 0.735, 0.045)
      font-size: 16vmin
      display: flex
      justify-content: center
      align-items: center
      text-shadow: 4px 4px $red
      color: white
      user-select: none
      will-change: transform
      @for $n from 1 through $elCount
        &:nth-child(#{$elCount + $n})
          z-index: $elCount - $n + 1
          background: transparentize($grey, 0.8 / $elCount * $n)
          
    &-label
      position: absolute
      width: $dots
      height: $dots
      border: 1px solid $red
      background: transparent
      border-radius: 50%
      z-index: 1
      bottom: 10px
      left: 50%
      cursor: pointer
      z-index: $elCount + 1
      @for $n from 1 through $elCount
        &:nth-child(#{10 + $n})
          transform: translateX(#{((-10px * $elCount) - (($n - 1) * -25px) - ($dots / 2))})

      &:before
        content: ''
        position: absolute
        top: 0
        left: 0
        width: 100%
        height: 100%
        border-radius: 50%
        background: $red
        animation: ripple 0.6s cubic-bezier(0.075, 0.82, 0.165, 1) forwards
        display: none

@keyframes blink
  0%, 100%
    opacity: 0.5
  50%
    opacity: 0.9

@keyframes ripple
  0%, 100%
    opacity: 0
  15%
    opacity: 0.6
  0%
    transform: scale(0)
  100%, 85%
    transform: scale(5)

html, body
  width: 100%
  height: 100%
  display: flex
  font-family: 'Sulphur Point', sans-serif
  background: $black
View Compiled
/*
  no JS >|
*/

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.