CSSセレクターにdata属性を使いたいマーカッパーの話

こんにちは、株式会社アームズでフロントエンドの仕事をしております、中村です。
普段は会社のブログくらいしか書いていないのですが、なんだか楽しそうだったのでアドベントカレンダーに参加させていただきます。

さて、今回はCSSセレクターについて書きたいと思います。
あくまで私がこう考えてますよ、という話なので考え方が違えば書き方も変わってくるかと思います。
一例としてお楽しみください。

## CSSセレクターについての基本的な考え方
CSSセレクターでよく使うのはクラスと要素型じゃないでしょうか。

### クラスと要素型
要素型は全体のベースに、クラスを使って独自のパーツを作っていきます。
独自のパーツをクラスで作りたいのはセレクターの入子が少ない方が照合時間が少なく済むためです。

### ID
IDはアンカーリンクなど、他の使い道が色々とあるので、私はスタイルシートのセレクターには極力使わないようにしています。
優先度も高くなるので混在すると設計しにくい、という理由もあります。あまり気にせず書きたいし、後々の更新作業で邪魔になることが多い気がします。（!importantの多用が発生しやすく、最終的に詰む）

### 擬似表記
:hover、:disabledなど、要素の状態に合わせてスタイルを変えたい時に使います。

### 擬似要素
::before、::afterなどは実際のHTMLに含まれない要素になります。
装飾のイラストなど、それ自体に意味を持たない（スクリーンリーダーなどで読めなくても大丈夫・読めてしまうと逆に混乱させてしまう要素）などに使用することが多いです。

他にもいろいろありますので、これから勉強する方は知っておくと便利です。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_selectors

## 本題のdata属性を使うことについて
属性セレクターの一つです。
属性セレクターはHTMLタグの属性の値によってスタイルを変えたい時に使用します。
``` css
a[href="https://example.org"]{ color: green;}
```
この例で言うと特定のリンク先のみ色を変えたいなど、そういったことに使えます。
リンク先がpdfだったり、target属性によってアイコンを変えることは多いかと思います。

https://developer.mozilla.org/ja/docs/Web/CSS/Attribute_selectors

data属性はHTMLの標準タグで意味づけされていない情報を持たせたい時などに使えます。

https://developer.mozilla.org/ja/docs/Learn/HTML/Howto/Use_data_attributes

MDNの例を参考に見ていきましょう。
（CSSセレクタとしての書き方、Javascriptでの取得の仕方などはMDNのページをご覧ください）

```html
<article
  id="electric-cars"
  data-columns="3"
  data-index-number="12314"
  data-parent="cars">
  ...
</article>
```

  data-columns="3"
  data-index-number="12314"
  data-parent="cars"

columns、index-number、parentの３種類ですね。
columns、parentはレイアウトスタイルに使いそうです。
index-numberはarticle要素の番号のようですね。
idとクラスでできるじゃん・・・初めの頃はそんな風に思っていました。

しかしこれ、CMSを使用したサイトなど、動的なページを作る際には使いやすいなと思いました。
例えば記事一覧のカテゴリーの表示などです。

カテゴリーはジャンルやエリアなど、さまざまな情報がありグループ分けをすると見やすかったりします。
クラスだけで実装すると、カテゴリーの内容を判定し、個別のスタイル用のクラスを付与します。手間が多いですね。

### クラスを使ったの場合
```html
<ul class="category">
    <li class="category__item is-apple">りんご</li>
    <li class="category__item is-banana">バナナ</li>
    <li class="category__item is-cucumber">きゅうり</li>
</ul>
```
```css
 .category__item.is-apple,
  .category__item.is-banana {
   color: red;
 }
 
 .category__item.is-cucumber {
   color: green;
 }
```
クラスの命名規則を守るため、カテゴリの名前（wordpressでいうところのスラッグなど）をそのまま使えない場合、出力する際に判定処理が必要です。（ここだけ命名規則から外す、というのもありですがあまりやりたくないです。）


### data属性を使った場合
```html
<ul class="category">
    <li class="category__item" data-category="apple">りんご</li>
    <li class="category__item" data-category="banana">バナナ</li>
    <li class="category__item" data-category="cucumber">きゅうり</li>
</ul>
```
```css
.category__item[data-category="apple"],
.category__item[data-category="banana"],
{
   color: red;
 }
 
.category__item[data-category="cucumber"] {
   color: green;
 }
```
クラスは基本レイアウト、data属性は情報の内容のよる識別という役割分担ができるので圧倒的に読みやすいです。
値もそのまま出力するだけで良いのも一手間少なく済みます。
※カテゴリーグループ（fruit、vegetablesなど）のデータを持っている場合はそれを使うとよりシンプルに作れます。

## まとめ

フロントエンドエンジニアがHTML・CSSを作り、バックエンドエンジニアが当て込むということも多いので、クラスを付与して欲しいと伝えるよりも、カテゴリの値はdata-categoryに出力してほしいと伝えた方がシンプルで当て込みする際に他の必要なクラスを消してしまう、といったミスも予防できます。

他にも、「クリックした時の処理は別のボタンでも、押した時に再生させるアニメーションが同じな場合」などにも使用したこともあります。
スタイルシートとは別の役割をつけたい時にも、情報の内容によって管理できるのは便利で拡張性もあるなと思います。
クラスはスタイルシート、data属性はjavaScriptになどの使い分けをしても良さそうです。

全てクラスで実装するのではなく、情報に合わせた設計を行うと、より使いやすいコードがかけるのではないでしょうか。
マークアップは標準要素だけのものではないなと思った次第です。
というわけで私もどんどん活用したいと思っています。

data属性はだいぶ前からあるので今更かなと思いつつ、お気持ち表明したいなと思ったので語らせていただきました。
お付き合いいただきありがとうございました。


## 最後に

弊社のブログもよろしければ見ていってください。
https://tech.arms-soft.co.jp/