CSSでパタパタ動くランキングボードを作った

この記事は [CSS アドベントカレンダー 2019](https://qiita.com/advent-calendar/2019/css)の11日目の記事です。

#はじめに
12月になると流行語大賞をはじめとする、様々な〇〇大賞が発表されます。
今回は、そんなときに使われるランキングボードをCSSで作りました。

#CSSで作ったらこうなった
オレンジの「PUSH」ボタンを押すとランキングがパタパタと動き出します。
今年の流行語大賞をランキングボードに出してみます。
（※ スマホでは上手く表示されないかもしれません。。）

<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="result" data-user="saka212" data-slug-hash="PowZppx" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="CSS Ranking Board">
  <span>See the Pen <a href="https://codepen.io/saka212/pen/PowZppx">
  CSS Ranking Board</a> by saka212 (<a href="https://codepen.io/saka212">@saka212</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#ソース
カスタマイズに必要な部分のHTMLとCSSを載せます。
全体はちょっと長いのでcodepenで。
https://codepen.io/saka212/pen/PowZppx

##ランキングが動き出す仕組み
```css:css
input[type="checkbox"] {
  display: none;
}

label {
  display: inline-block;
  box-sizing: border-box;
  width: 80px;
  height: 50px;
  margin-right: 5px;
  line-height: 50px;
  background: #ffa500;
  border: solid 1px #ffa500;
  border-radius: 4px;
  border-bottom: 4px solid #d37800;
  text-shadow: 1px 1px 1px rgba(0,0,0,0.2);
  color: #fff;
  text-align: center;
  font-weight: bold;
  vertical-align: top;
  cursor: pointer;
}


.btn:checked + label + .frame .flip:nth-of-type(1) {
  /* animation: keyframe名 周期 開始タイミング 回数 アニメショーン終了後のスタイル指定 */
  animation: frame-rotate var(--duration) calc(var(--delay) * 0) var(--count) forwards;
}
.btn:checked + label + .frame .flip:nth-of-type(2) {
  animation: frame-rotate var(--duration) calc(var(--delay) * 1) var(--count) forwards;
}
.btn:checked + label + .frame .flip:nth-of-type(3) {
  animation: frame-rotate var(--duration) calc(var(--delay) * 2) var(--count) forwards;
}
.btn:checked + label + .frame .flip:last-child {
  display: none;
}
```
チェックボックスを隠し、ボタン化したラベルを押すことで、ランキングがパタパタと動きます。
動きの流れを簡単に説明すると...

1.チェックボックスとラベルタグを関連付ける。
　　↓
2.関連付けることで、ボタン化したラベルをクリックするとチェックが入る。
　　↓
3.チェックされたときに適用されるCSSに、`animation`プロパティを書いておくことでアニメが動く。

表示したいパタパタの数の合わせて、
`.btn:checked + label + .frame .flip:nth-of-type(1) {...}`
の部分は増やしておきます。`animation`プロパティの値は、CSSカスタムプロパティで設定すると便利です。


##ランキング内容を変えて遊びたいとき
```html:html
<div class="row">
  <input type="radio" id="btn1" class="btn">
  <label for="btn1">PUSH ME</label>
  <div class="frame">
    <div class="flip" data-txt="ONE TEAM" data-txt-next="令和"></div>
    <div class="flip" data-txt="令和" data-txt-next="タピる"></div>
    <!-- ↓↓ この 「data-txt-next」にパタパタが止まった止まったときに表示したいテキスト -->
    <div class="flip" data-txt="タピる" data-txt-next="ONE TEAM"></div>
    <!-- ↓↓ この「data-txt」にボタンを押す前に表示するテキスト -->
    <div class="flip open" data-txt="大賞"></div>
  </div>
</div>
```
ランキングひとつ分のhtmlです。
３行のランキングを表示しているので、このhtml部分を３つ用意しています。
ボタンを押す前に表示するテキストを、
`<div class="flip open" data-txt="..."></div>`の`data-txt="..."`
に書きます。
パタパタが止まったときに表示したいテキストは、そのひとつ上のdivの`data-txt-next="..."`に書きます。

#感想
rotateを使ったアニメーションはパズルですね。
よくよく整理しながら進めていかないと、何を作っているかわからなくなります。
リアリティーを出せるように、いろいろなやり方をためしているうちに、自分の頭の中もパタパタしてきたので「それっぽさ」が出る方向に転換しました。
もっとシンプルな作り方もあるかもしれません。

#おわりに
[「2019年ティーンが選ぶトレンドランキング」](https://www.mynavi.jp/news/2019/11/post_21861.html)は、ほとんどわかりませんでした...。