【CSS】JavaScriptを使わずに三並べを作ってみた

正式名称は三並べ? マルバツゲーム?

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

CSSだけで三並べを作ります
今回も後続兄弟結合子が肝です
ちゃんと勝敗の判定もできます
この記事は以下の動画の中に出てきたサンプルコードを載せたものです。コピペなどが必要なときに使ってください。





HTML

<form>
  <input type="checkbox" id="maru1">
  <input type="checkbox" id="maru2">
  <input type="checkbox" id="maru3">
  <input type="checkbox" id="maru4">
  <input type="checkbox" id="maru5">
  <input type="checkbox" id="maru6">
  <input type="checkbox" id="maru7">
  <input type="checkbox" id="maru8">
  <input type="checkbox" id="maru9">
  <input type="checkbox" id="batsu1">
  <input type="checkbox" id="batsu2">
  <input type="checkbox" id="batsu3">
  <input type="checkbox" id="batsu4">
  <input type="checkbox" id="batsu5">
  <input type="checkbox" id="batsu6">
  <input type="checkbox" id="batsu7">
  <input type="checkbox" id="batsu8">
  <input type="checkbox" id="batsu9">

  <div id="board">
    <div id="square1" class="square">
      <label for="maru1" class="maru"></label>
      <label for="batsu1" class="batsu"></label>
    </div>
    <div id="square2" class="square">
      <label for="maru2" class="maru"></label>
      <label for="batsu2" class="batsu"></label>
    </div>
    <div id="square3" class="square">
      <label for="maru3" class="maru"></label>
      <label for="batsu3" class="batsu"></label>
    </div>
    <div id="square4" class="square">
      <label for="maru4" class="maru"></label>
      <label for="batsu4" class="batsu"></label>
    </div>
    <div id="square5" class="square">
      <label for="maru5" class="maru"></label>
      <label for="batsu5" class="batsu"></label>
    </div>
    <div id="square6" class="square">
      <label for="maru6" class="maru"></label>
      <label for="batsu6" class="batsu"></label>
    </div>
    <div id="square7" class="square">
      <label for="maru7" class="maru"></label>
      <label for="batsu7" class="batsu"></label>
    </div>
    <div id="square8" class="square">
      <label for="maru8" class="maru"></label>
      <label for="batsu8" class="batsu"></label>
    </div>
    <div id="square9" class="square">
      <label for="maru9" class="maru"></label>
      <label for="batsu9" class="batsu"></label>
    </div>
  </div>

  <div id="dialog">
    <div id="message"></div>
    <button type="reset" id="reset">RESET</button>
  </div>
</form>



CSS

input { display: none }

#board {
  display: inline-grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-gap: 2px;
  border: 2px solid;
  background: black;
  margin-top: 20px;
}

.square {
  background: white;
  position: relative;
  text-align: center;
  font-size: 65px;
}

label {
  display: block;
  position: absolute;
  inset: 0;
  cursor: pointer;
}

#maru1:checked ~ #board #square1,
#maru2:checked ~ #board #square2,
#maru3:checked ~ #board #square3,
#maru4:checked ~ #board #square4,
#maru5:checked ~ #board #square5,
#maru6:checked ~ #board #square6,
#maru7:checked ~ #board #square7,
#maru8:checked ~ #board #square8,
#maru9:checked ~ #board #square9 {
  &::before { content: '\025cb' }
  label { display: none }
}

#batsu1:checked ~ #board #square1,
#batsu2:checked ~ #board #square2,
#batsu3:checked ~ #board #square3,
#batsu4:checked ~ #board #square4,
#batsu5:checked ~ #board #square5,
#batsu6:checked ~ #board #square6,
#batsu7:checked ~ #board #square7,
#batsu8:checked ~ #board #square8,
#batsu9:checked ~ #board #square9 {
  &::before { content: '\02715' }
  label { display: none }
}

.batsu { display: none }

input:checked ~ #board .batsu { display: block }
input:checked ~ input:checked ~ #board .batsu { display: none }
input:checked ~ input:checked ~ input:checked ~ #board .batsu { display: block }
input:checked ~ input:checked ~ input:checked ~ input:checked ~ #board .batsu { display: none }
input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ #board .batsu { display: block }
input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ #board .batsu { display: none }
input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ #board .batsu { display: block }
input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ #board .batsu { display: none }

#dialog {
  background: rgba(0, 0, 0, .8);
  position: fixed;
  inset: 0;
  display: none;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  color: #fff;
  font-size: 40px;

  #message::before {
    content: '引き分けです';
  }

  #reset {
    width: 300px;
    height: 40px;
    margin-top: 20px;
    cursor: pointer;
  }
}

#maru1:checked ~ #maru2:checked ~ #maru3:checked,
#maru4:checked ~ #maru5:checked ~ #maru6:checked,
#maru7:checked ~ #maru8:checked ~ #maru9:checked,
#maru1:checked ~ #maru4:checked ~ #maru7:checked,
#maru2:checked ~ #maru5:checked ~ #maru8:checked,
#maru3:checked ~ #maru6:checked ~ #maru9:checked,
#maru1:checked ~ #maru5:checked ~ #maru9:checked,
#maru3:checked ~ #maru5:checked ~ #maru7:checked {
  ~ #dialog { 
    display: flex;
    #message::before { content: '\025cbの勝ちです'}
  }
}

#batsu1:checked ~ #batsu2:checked ~ #batsu3:checked,
#batsu4:checked ~ #batsu5:checked ~ #batsu6:checked,
#batsu7:checked ~ #batsu8:checked ~ #batsu9:checked,
#batsu1:checked ~ #batsu4:checked ~ #batsu7:checked,
#batsu2:checked ~ #batsu5:checked ~ #batsu8:checked,
#batsu3:checked ~ #batsu6:checked ~ #batsu9:checked,
#batsu1:checked ~ #batsu5:checked ~ #batsu9:checked,
#batsu3:checked ~ #batsu5:checked ~ #batsu7:checked {
  ~ #dialog { 
    display: flex;
    #message::before { content: '\02715の勝ちです'}
  }
}

input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ input:checked ~ #dialog {
  display: flex;
}
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください