【CSS アニメーション】上下逆方向の無限スライド

## はじめに
スライダーを実装する場合はJSを使用することが多いですが、
スライドをループするだけなので、JSを使用せずCSSアニメーションのみで実装してみました。


実際の動きはこちらから
[CodePen](https://codepen.io/yaajitaake4/pen/ZEMzGVz)

## 実装

### HTML

```html
<div class="slide">
    <div class="slide-wrap top">
      <ul>
        <li>画像１-1</li>
        <li>画像1-２</li>
        <li>画像1-３</li>
        <li>画像1-４</li>
        <li>画像1-５</li>
      </ul>
      <ul>
        <li>画像１-1</li>
        <li>画像1-２</li>
        <li>画像1-３</li>
        <li>画像1-４</li>
        <li>画像1-５</li>
      </ul>
    </div>
    
    <div class="slide-wrap bottom">
      <ul>
        <li>画像2-１</li>
        <li>画像2-２</li>
        <li>画像2-３</li>
        <li>画像2-４</li>
        <li>画像2-５</li>
      </ul>
      <ul>
        <li>画像2-１</li>
        <li>画像2-２</li>
        <li>画像2-３</li>
        <li>画像2-４</li>
        <li>画像2-５</li>
      </ul>
    </div>
</div>
```

### CSS
```css
* {
  margin: 0;
  padding: 0;
}

ul,
li {
  list-style: none;
}

li {
  background-color: lightblue;
}

.slide {
  margin-top: 3px;
}

.slide-wrap {
  display: flex;
}

.slide-wrap.bottom {
  margin-top: 3px;
  justify-content: flex-end;
}

.slide-wrap ul {
  display: flex;
}

.slide-wrap.top ul:first-child {
  animation: slideTop 50s -25s linear infinite;
}

.slide-wrap.top ul:last-child {
  animation: slideTop2 50s linear infinite;
}

.slide-wrap.bottom ul:first-child {
  animation: slideBottom 50s linear infinite;
}

.slide-wrap.bottom ul:last-child {
  animation: slideBottom2 50s -25s linear infinite;
}

.slide-wrap li {
  width: 19.7436vw;
}

.slide-wrap.top li {
  margin-right: 4px;
}

.slide-wrap.bottom li {
  margin-left: 4px;
}

@keyframes slideTop {
  0% {
    transform: translateX(100%);
  }
  to {
    transform: translateX(-100%);
  }
}

@keyframes slideTop2 {
  0% {
    transform: translateX(0%);
  }
  to {
    transform: translateX(-200%);
  }
}

@keyframes slideBottom {
  0% {
    transform: translateX(0%);
  }
  to {
    transform: translateX(200%);
  }
}

@keyframes slideBottom2 {
  0% {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}
```


## 押さえておく点

同じ画像群を二回用意

```html
 <ul>
    <li>画像１-1</li>
    <li>画像1-２</li>
    <li>画像1-３</li>
    <li>画像1-４</li>
    <li>画像1-５</li>
  </ul>
  <ul>
    <li>画像１-1</li>
    <li>画像1-２</li>
    <li>画像1-３</li>
    <li>画像1-４</li>
    <li>画像1-５</li>
  </ul>
```


二回用意したHTMLに対して@keyframesで移動方向(transform)と移動距離(~%)をそれぞれ指定
    
```css
@keyframes slideTop {
  0% {
    transform: translateX(100%);
  }
  to {
    transform: translateX(-100%);
  }
}

@keyframes slideTop2 {
  0% {
    transform: translateX(0%);
  }
  to {
    transform: translateX(-200%);
  }
}
```

二回用意したHTMLに対してアニメーションする時間などを指定

```css
.slide-wrap.top ul:first-child {
  animation: slideTop 50s -25s linear infinite;
}

.slide-wrap.top ul:last-child {
  animation: slideTop2 50s linear infinite;
}
```


　簡単に説明すると二回用意したHTMLそれぞれに開始地点と終了地点の異なるアニメーションを設定し、それぞれが終了地点に到達すると再び開始地点から終了地点までのアニメーションを繰り返します。
こうすることで画像が途切れることなくループする動きを再現しています。

また下記プロパティをホバーアクションと併用することで一時停止も可能になります。
```css
.slide-wrap.top ul:first-child:hover {
    animation-play-state: paused;
}
```

## 終わりに
JSに頼らずともCSSでアニメーションが実装できるのはかなり便利で楽でした。
使えるCSSプロパティが増えてきているので、そのうち色々試していきたいと思います。


## 参考
https://developer.mozilla.org/ja/docs/Web/CSS/animation

https://developer.mozilla.org/ja/docs/Web/CSS/@keyframes