【CSS】CSS Togglesを使えば、Check BoxでON/OFFを表現しなくてもよくなくなるらしい

## 概要
みなさんは、HTMLとCSSでON/OFFを表現する際、どのように実装しているでしょうか？

多くの方は、HTMLで`<input type=checkbox>`とCSSの擬似クラス`:checked`を使って、
実装しているのではないでしょうか？

実は、2022年4月28日に Tab Atkins Jr. (Google)とMiriam E. Suzanne (Invited Expert)によって、
CSS Togglesという、CSSだけでON/OFFの値を定義して、変更をできるようにするための草案が提出されました。

https://tabatkins.github.io/css-toggle/

:::note warn
この内容は実践的に使える内容ではなく、公式に提案するための草案になります。
`JS-polyfill`を使ってデモを作成しているので、ご注意ください。
:::

この記事では、CSS Togglesの具体的な内容の紹介と実装方法の解説を行います。

## CSS Togglesとは？
CSS Togglesとは、CSSだけで、ON/OFFを使えるように、
トグル機能を一般化して、任意の要素にON/OFFの状態を適用できるようにした機能になります。

具体的には、
`toggle-root`で、名前を定義して、
`toggle-trigger`でステータスを変更し、
擬似クラス`:toggle()`でスタイルに反映する。

といった具合です。


## 実装方法
### 1. Toggleを作成する
cssのプロパティに以下のように記載することで、Toggleを作成できます。

```CSS
/* toggle-root: name value at max group scope overflow; */
.example {
    toggle-root: toggle 0 at 1 toggleGroup wide cycle;
}

/* 省略形：0~1のtoggle、groupなし、wide、cycle*/
.example {
    toggle-root: toggle;
}
```

||役割|値|
|----|----|----|
|name|toggleの名前|String|
|value|on/offの値|Integer<br>0：非アクティブ(デフォルト値)<br>1以上：アクティブ|
|max|valueの最大値|Integer(デフォルト値：1)|
|group|トグルグループ|String|
|scope|トグルを使う範囲|wide：その要素と子孫要素、兄弟要素、兄弟要素の子孫要素(デフォルト値)<br>narrow：その要素と子孫要素|
|overflow|値を超えた時の値|cycle：最大値・最小値を超えると0に戻る<br> cycle-on：最大値を超えると1に戻り、最小値を超えると最大値<br> sticky：最大値を超えると最大値に戻り、最小値を超えると0に戻る|

※ トグルグループでは、特定の値が０→1に変化した時に、グループの他の値は0にリセットされます。

### 2. Toggleをアクティブにする
Toggleのvalueを変更することができます。

```CSS
/* toggle-trigger: name action value; */
.example {
    toggle-trigger: toggle next 1;
}

/* 省略形：next 1*/
.example {
    toggle-trigger: toggle;
}
```

||役割|値|
|----|----|----|
|name|toggleの名前|String|
|action|togleのvalueを増やすか減らすか|next：増加する(デフォルト値)<br>pre：減少する|
|value|どのくらい変化させるか|Integer (デフォルト値：1)|

### Toggleを要素に反映させる
`:toggle()`を使って、Toggleの値に応じてスタイルを変更させることができます。

```CSS
/* toggleの値が1のとき */
.example:toggle(toggle 1) {
    ...
}
```

## 使用例
### ライトモード/ダークモードを切り替える
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYVYMrB" data-user="sp_degu" 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/sp_degu/pen/eYVYMrB">
  Untitled</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

※ 背景しか変わらないです

### アコーディオン
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="OJQJZLL" data-user="sp_degu" 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/sp_degu/pen/OJQJZLL">
  Qiita - Dark Mode</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

※ スタイルは凝ってません

## まとめ

今回は、CSS Togglesについて紹介しました。

CSS Togglesはまだまだ、正式なものではないですが、
checkboxを使って、アコーディオンを作っていたり、Toggleボタンを作っていたことを考えると、
セマンティックやアクセシビリティ的にはとても嬉しいですね。


[デモページ](https://toggles.oddbird.net/)では、アコーディオンやToggleボタンだけではなく、
タブ表現やチェックボックス的な表現も紹介されていました。

まだまだ、色々なissueが立てられており、開発途中なようですが、
今から実装させるのが楽しみですね!

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510

### Ref
https://tabatkins.github.io/css-toggle/

https://github.com/oddbird/css-toggles

https://css.oddbird.net/toggles/explainer/

https://toggles.oddbird.net/