<input type="checkbox">単品とCSSだけでトグルスイッチを作る


CSSを完全に理解していた頃作ったCSSトグルスイッチがあまりに冗長なコードだったので、CSSを理解した今リメイクを始めたところinput単品でできてしまった
#よくあるコード
調べるとよく出てくるのがこのタイプ
中の人が最初に書いたトグルスイッチもこのタイプ

```html
<style>
  .toggle{display:none;}
  .toggle+label{…}
  .toggle+label>div{…}
  .toggle:checked+label{…}
  .toggle:checked+label>div{…}
</style>
<input type="checkbox" class="toggle" id="id">
<label for="id"><div></div></label>
```
inputは非表示にして後続のlabelとdivで頑張るやつ
とても分かりやすいコード

個人的なこれの欠点はinputの後にlabelたちを書かなければならないところ
少なくとも中のdivくらいは::beforeで代用したいところ

#リメイク開始
##::beforeで代用
labelの中のdivを::beforeに置き換えて消す
::beforeは元の要素の子要素

```html
<style>
  .toggle{display:none;}
  .toggle+label{…}
  .toggle+label::before{content:"";display:block;…}
  .toggle:checked+label{…}
  .toggle:checked+label::before{…}
</style>
<input type="checkbox" class="toggle" id="id">
<label for="id"></label>
```
ちょっときれいになった
##idを消したい
中の人はJSでよくidを使うので無駄なところでidの名前候補を消費したくない
labelでinputを囲むのを好まない人もいるようだが個人的には好き

```html
<style>
  .toggle>input{display:none;}
  .toggle::before{…}
  .toggle::after{…}
  .toggle:has(>input:checked)::before{…}
  .toggle:has(>input:checked)::after{…}
</style>
<label class="toggle"><input type="checkbox"></label>
```
あまり知られていないがCSSには[:has](https://developer.mozilla.org/ja/docs/Web/CSS/:has)という擬似クラスがある
:isの親要素版と例えるのが良いかもしれない

こんな便利なものがなぜ知られていないかというと
![FAD38478-81B8-4C71-B378-362C07675BF6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479627/8f1c0b6c-6431-8575-98e2-fe421f699c42.jpeg)
そう、まだ誰も対応していないのである(2021/9/6)

困った。

::beforeをなんとかしてinputを絡めて捕まえたい

```html
<style>
  .toggle>input{display:none;}
  .toggle::before{…}
  .toggle::after{…}
  /*.toggle>input:checked-*::before{…} +のノリで-セレクタが欲しい*/
  .toggle>input:checked+*::after{…}
</style>
<label class="toggle"><input type="checkbox"></label>
```
無理に決まってます
そもそも擬似要素に隣接する別要素に絡めて捕まえることが無理

困った。
##えっ
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="VwWmYoz" data-editable="true" data-user="mcbeeringi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mcbeeringi/pen/VwWmYoz">
  input checkbox pseudo element</a> by McbeEringi (<a href="https://codepen.io/mcbeeringi">@mcbeeringi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

完全勝利
あとはappearance:none;して好き勝手CSSすればなんでもできちゃう
##完成
::beforeでスライドする部分を作って変数で外からサイズを変えられるようにしてその他いろいろ整えて完成
::afterは使ってないので文字を入れる余地もある
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="MWobwwW" data-editable="true" data-user="mcbeeringi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mcbeeringi/pen/MWobwwW">
  </a> by McbeEringi (<a href="https://codepen.io/mcbeeringi">@mcbeeringi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
コード自由に使ってもらって構いません
#まとめ
- 少なくとも最新のsafari,chrome,firefoxではinput[type=checkbox]でも擬似要素は使える
- appearance:none;最強(safariは-webkit-必須)

読んでいただきありがとうございます