【CSS】JavaScriptを使わずにスロットマシンを作成してみた

CSSだけでスロットマシン

この記事を三行にまとめると

JavaScriptは使用しません
後続兄弟結合子を使います
一応目押しできます
この記事は以下の動画の中に出てきたサンプルコードを載せたものです。コピペなどが必要なときに使ってください。





アイコンについて

今回はGoogleのMaterial Symbolsを使用しています。
https://fonts.google.com/icons



HTML

<form>
  <input type="checkbox" id="rotate">
  <div id="main">
    <div class="panel flex">
      <input type="checkbox" id="left" class="reel-stop">
      <div class="reel">
        <div class="icons">
          <span class="material-symbols-outlined">notifications</span>
          <span class="material-symbols-outlined">counter_7</span>
          <span class="material-symbols-outlined">music_note</span>
          <span class="material-symbols-outlined">star</span>
          <span class="material-symbols-outlined">sunny</span>
          <span class="material-symbols-outlined">bolt</span>
          <span class="material-symbols-outlined">toys</span>
        </div>
      </div>
      <label class="stop" for="left"></label>
    </div>
    <div class="panel flex">
      <input type="checkbox" id="center" class="reel-stop">
      <div class="reel">
        <div class="icons">
          <span class="material-symbols-outlined">notifications</span>
          <span class="material-symbols-outlined">counter_7</span>
          <span class="material-symbols-outlined">music_note</span>
          <span class="material-symbols-outlined">star</span>
          <span class="material-symbols-outlined">sunny</span>
          <span class="material-symbols-outlined">bolt</span>
          <span class="material-symbols-outlined">toys</span>
        </div>
      </div>
      <label class="stop" for="center"></label>
    </div>
    <div class="panel flex">
      <input type="checkbox" id="right" class="reel-stop">
      <div class="reel">
        <div class="icons">
          <span class="material-symbols-outlined">notifications</span>
          <span class="material-symbols-outlined">counter_7</span>
          <span class="material-symbols-outlined">music_note</span>
          <span class="material-symbols-outlined">star</span>
          <span class="material-symbols-outlined">sunny</span>
          <span class="material-symbols-outlined">bolt</span>
          <span class="material-symbols-outlined">toys</span>
        </div>
      </div>
      <label class="stop" for="right"></label>
    </div>
  </div>
  <div id="buttons">
    <label id="start" class="button flex" for="rotate">START</label>
    <button id="reset" class="button flex" type="reset">RESET</button>
  </div>
</form>



CSS

* {
  box-sizing: border-box;
}

body {
  width: 360px;
  margin: 0 auto;
}

:root {
  --border: 4px solid #444;
  --boxshadow: 0 3px 5px rgba(0, 0, 0, .3);
}

.flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

input {
  display: none;
}
  
#main {
  display: flex;
  justify-content: space-around;
  margin: 40px 0 20px;
  padding: 20px;
  background: radial-gradient(circle, rgba(255, 242, 58, 1), rgba(224, 162, 8, 1) 80%);
  box-shadow: var(--boxshadow);
  border: var(--border);
  border-radius: 10px;
}

.panel {
  flex-direction: column;
  gap: 20px;
}

.reel {
  background: #fff;
  width: 60px;
  height: 80px;
  box-shadow: var(--boxshadow) inset;
  border: var(--border);
  border-radius: 10px;
  overflow: hidden;
  padding: 12px 0;
}

.material-symbols-outlined {
  font-weight: 700;
  font-size: 48px;
  height: 50px;
}

.stop {
  display: block;
  border: 2px solid #444;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  box-shadow: var(--boxshadow);
  pointer-events: none;
}

.button {
  width: 100%;
  height: 40px;
  color: #fff;
  border-radius: 10px;
  border: none;
  font-size: 20px;
}

.stop, .button {
  cursor: pointer;
  background: #eb6100;

  &:active {
    transform: translateY(2px);
    background: #f56500;
  }
}

.icons {
  text-align: center;
}

#buttons {
  height: 40px;
  overflow: hidden;
}

#rotate:checked {
  ~ #main {
    .icons { animation: slot .35s steps(7) infinite }
    .stop { pointer-events: all }

    .reel-stop:checked {
      ~ .reel .icons { animation-play-state: paused }
      ~ .stop { pointer-events: none }
    }
  }

  ~ #buttons #start { display: none }
}

@keyframes slot {
  from { transform: translateY(-300px) }
  to { transform: translateY(50px) }
}
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください