<div class="btns">
  <button data-starter>애니메이션 시작</button>
  <button data-container="start">변환 없음, 애니메이션 없음</button>
  <button data-container="transform">애니메이션 전 (0%)</button>
  <button data-container="composition" class="active">애니메이션 후 (100%)</button>
</div>
<ul class="units">
  <li>100px</li>
  <li>200px</li>
  <li>300px</li>
  <li>400px</li>
  <li>500px</li>
  <li>600px</li>
  <li>700px</li>
  <li>800px</li>
  <li>900px</li>
</ul>
<ul class="marks">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
<div class="container start">
  <div class="item">
    replace
  </div>
  <div class="item">
    add
  </div>
  <div class="item">
    accumulate
  </div>
</div>
<div class="container transform">
  <div class="item">
    replace
    (100x50)
  </div>
  <div class="item">
    add
    (200x100)
  </div>
  <div class="item">
    accumulate
    (200x100)
  </div>
</div>
<div class="container composition zup">
  <div class="item">
    replace
    (200x100)
  </div>
  <div class="item">
    add
    (400x200)
  </div>
  <div class="item">
    accumulate
    (300x150)
  </div>
</div>
// Init~ Don't touch here!
$color: #121212;
body {
  padding: 20px;
  background-color: #121212;
  font-family: 'NanumSquareRound',sans-serif;
  color: $color;
}

.btns {
  display: flex;
  gap: 10px;
  margin-bottom: 30px;
}
button {
  --btn-color: #6c6665;
  --shadow-color: #55504f;
  flex-shrink: 0;
  height: 40px;
  padding: 0 20px;
  border: none;
  outline: none;
  border-radius: 10px;
  background-color: var(--btn-color);
  box-shadow: 
    0 6px 0 var(--shadow-color),    
    0 6px 10px rgba(0,0,0,.2);
  font-size: 16px;
  color: #fff;
  cursor: pointer;
  transition: .1s;
}
button:hover {
  filter: brightness(130%);
}
button:active {
  transform: translateY(4px);
  box-shadow: 
    0 4px 0 var(--shadow-color),
    0 3px 5px rgba(0,0,0,.2);
}
button[data-starter] {
  --btn-color: crimson;
  --shadow-color: #9e1832;
  margin-right: 20px;
}
button.active {
  --btn-color: royalblue;
  --shadow-color: #3254b8;
}

$width: 100px;
$height: 50px;
.container {
  // border: 10px solid rgba(black, .1);
  border-radius: 10px;
  display: grid;
  grid-template-columns: repeat(10, $width);
  grid-template-rows: repeat(8, $height);
  grid-auto-flow: column;
}
.item {
  grid-column: 1 / 2;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 20px;
  box-sizing: border-box;
  position: relative;
  font-size: 12px;
  font-weight: 900;
  color: $color;
  text-align: center;
  text-shadow: 3px 0 0 rgba(white, .3);
  cursor: pointer;
  @for $i from 0 through 2 {
    $nth: $i + 1;
    &:nth-child(#{$nth}) {
      grid-row-start: $nth + $i;
      grid-row-end: $nth + $i + 1;
    }
  }
  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    border: 4px solid rgba($color, .7);
    border-radius: 10px;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    z-index: -1;
  }
  $colors: (tomato, orange, limegreen, dodgerblue, hotpink, darkgray, crimson, orangered, lawngreen, aqua, royalblue, wheat, brown, gray, salmon, deeppink, gold, springgreen, slateblue, darkslategray);
  @each $color in $colors {
    $index: index($colors, $color);
    &:nth-child(#{$index})::before {
      background-color: rgba($color, .8);
    }
  }
  &::after {
    content: "";
    width: 10px;
    height: 50%;
    background: white;
    position: absolute;
    top: 16px;
    left: 16px;
    border-radius: 100px;
    opacity: .3;
    z-index: -1;
  }
}

.units {
  margin-bottom: 20px;
  display: grid;
  grid-template-columns: repeat(10, $width);
  li {
    font-size: 20px;
    font-weight: bold;
    color: #333;
    transform: translateX($width - 26px);
  }
}

.marks {
  position: absolute;
  display: grid;
  grid-template-columns: repeat(10, $width);
  grid-auto-rows: $height;
  li {
    position: relative;
    border-left: 4px dashed #333;
    border-top: 4px dashed #333;
    transform: translateX(-2px);
    z-index: -2;
    font-size: 16px;
    font-weight: bold;
    color: #555;
    display: flex;
    justify-content: center;
    align-items: center;
    &:nth-child(10n+1) {
      border-left: none;
    }
    &:nth-child(n+71) {
      border-bottom: 4px dashed #333;
    }
  }
}

// Test here!
.container {
  position: relative;
  &.start {
    opacity: .3;
    position: absolute;
  }
  &.transform {
    opacity: .3;
    position: absolute;
    .item {
      width: $width;
      height: $height;
      animation-name: heropy;
      animation-duration: 3s;
      animation-fill-mode: both;
      animation-play-state: paused;
      transform: translateX(50px) scale(2);
      transform-origin: 0 0;
    }
    .item:nth-child(1) { animation-composition: replace; }
    .item:nth-child(2) { animation-composition: add; }
    .item:nth-child(3) { animation-composition: accumulate; } 
  }
  &.composition {
    opacity: .3;
    .item {
      width: $width;
      height: $height;
      animation-name: heropy;
      animation-duration: 3s;
      animation-fill-mode: both;
      transform: translateX(50px) scale(2);
      transform-origin: 0 0;
    }
    .item:nth-child(1) { animation-composition: replace; }
    .item:nth-child(2) { animation-composition: add; }
    .item:nth-child(3) { animation-composition: accumulate; } 
  }
  &.zup { 
    opacity: 1;
    z-index: 1;
  }
}

@keyframes heropy {
  0% {
    transform: translateX(50px) scale(1);
  }
  100% {
    transform: translateX(100px) scale(2);
  }
}
View Compiled
const containerEls = document.querySelectorAll('.container')
const cotainerEl = document.querySelector('.container.composition')
const btnEls = document.querySelectorAll('.btns [data-container]')
const startBtnEl = document.querySelector('.btns [data-starter]')

startBtnEl.addEventListener('click', () => {
  cotainerEl.classList.remove('composition')  
  setTimeout(() => {
    cotainerEl.classList.add('composition')  
  })
})

btnEls.forEach(btnEl => {
  btnEl.addEventListener('click', () => {
    const { container: containerName } = btnEl.dataset
    btnEls.forEach(b => b !== btnEl && b.classList.remove('active'))
    btnEl.classList.toggle('active')
    containerEls.forEach(containerEl => {
      containerEl.classList.remove('zup')
      if (btnEl.classList.contains('active') && containerEl.classList.contains(containerName)) {
        containerEl.classList.add('zup')
      }
    })      
  })
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.