CSS設計の類はもっとカスタムデータ属性を活用するべきでは

## カスタムデータ属性とは
HTML5で定義されたカスタムデータ属性、当然皆さんご存知のことかと思います。
HTMLにプライベートな値を設定できるという仕様です。
`data-`から始まる属性です。 このように書きます。

```html:html
<div class="hoge" data-type='fuga'>🐳</div>
```

この値は、次のようにしてjavascriptやcssから触ることができます。

```js:js
// data-typeを持つ要素を取得
var elem = document.querySelector("[data-type]");
// data-typeの中身を取得する

console.log(elem.dataset.type); // fuga
// data-typeを変更する
elem.dataset.type = 'piyo'; // <div data-type='piyo' />に

```

```scss:scss
// data-typeの文字サイズを大きく
.hoge {
  &[data-type] {
    font-size: 2em; // data-typeを持つ要素の文字サイズを大きく
  }
  // data-typeがpiyoなら末尾にヒヨコを追加
  &[data-type='piyo']::after {
    content:"🐤";
  }
}
```

細かい仕様や利用可能なブラウザーは他の記事を参考にしていただくとして、
この指定方法とても便利だと思いませんか？


## カスタムデータ属性を使った書き換え
例えば次のようなコードがあったとします。

```html:html
<div class="block is-hide"> ... </div>
```

```scss:scss
.block {
  display:block;
  &.is-hide {
    display:none;
  }
}
```

これをデータ属性付きの方法で書き換えると次のようになります。

```html:html
<div class="block" data-is-hide="true"> ... </div>
```

```scss:scss
.block {
  display:block;
  &[data-is-hide="true"] {
    display:none;
  }
}
```
data属性に書き換えるだけなので変更も容易です。
さらに特に意識しなくてもCSSの名前が衝突することがなくなりますし、classが短くて済みます。

class名の操作をしなくていいので、javascriptで操作する場合も手軽になります。

```js
const BlockElement = document.querySelector(".block");
let isHide = false;
button.addEventListener("click", () => {
  BlockElement.dataset.isHide = isHide = !isHide;
},false);
```

## Reactと組み合わせても便利
Reactのjsxは、基本的にはsrcなどの予約された属性以外のものを利用することができませんが、data属性なら自由に指定することができます。
次のように書けるので、jsxでstyleを直接当てることなく見た目を変更することも可能です。

```html
<div className="block" data-is-hide={this.state.isHide}>
  ...
</div>
```

わざわざ条件分岐とかつけなくてもいいわけです

```html
// こんなことしなくてもいい
<div className=`block ${this.state.isHide ? 'is-hide': ''}`>
  ...
</div>
```

## data属性がcssで操作できるということは・・・？
こんなこともできると思います。

```html:html

<div class="block" data-weather="cloudy"></div> // ☁︎
<div class="block" data-weather="sunny"></div> // ☀️
<div class="block" data-weather="rainy"></div> // ☂
<div class="block" data-weather="cloudy-sunny"></div> // ☁︎☀️
<div class="block" data-weather="sunny-cloudy"></div> // ☀️☁︎
<div class="block" data-weather="sunny-rainy"></div> // ☀️☂
<div class="block" data-weather="rainy-cloudy"></div> // ☂☁︎
```
```scss:scss
.block {
  $wathers : (
    'cloudy':'☁️',
    'sunny' : '☀️',
    'rainy' : '☂'
  );
  
  @each $before, $before_icon in $wathers {
    &[data-weather="#{$before}"]::before {
      content: $before_icon;
    }
  }
  @each $before, $before_icon in $wathers {
    @each $after, $after_icon in $wathers {
      &[data-weather="#{$before}-#{$after}"]::after {
        content: $before_icon + $after_icon;
      }
    }
  }
}
```
これだけ複雑なことをしても、一切classは汚れません。

## グリッドシステムも簡単に（？）
12分割のグリッドシステムもdata属性を使えばより簡単に指定することができます。

```html:html
<div class="row">
    <div class="row__col" data-column="1/3">1/3</div>
    <div class="row__col" data-column="1/3">1/3</div>
    <div class="row__col" data-column="1/3">1/3</div>
</div>

<div class="row">
    <div class="row__col" data-column="2/8">2/8</div>
    <div class="row__col" data-column="9/12">9/12</div>
</div>
```

```scss:scss
.row {
  $min-columns : 1;
  $max-columns : 12;
  width: 100%;
  display:flex;
  &__col {
    margin: auto;
    @for $max_columns from $min-columns through $max-columns {
      @for $i from 1 through $max_columns {
        &[data-column="#{$i}/#{$max_columns}"] {
          @if $i != $max_columns {
            width: ($i / $max_columns * 100%);
          }
        }
      }
    }
  }
}
```


## 最後に
というわけで状態の指定にカスタムデータ属性を使うともう少し幸せになるのではないかという提言です。