Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

カスタムデータ属性とは

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

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

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

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

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

カスタムデータ属性を使った書き換え

例えば次のようなコードがあったとします。

html
<div class="block is-hide"> ... </div>
scss
.block {
  display:block;
  &.is-hide {
    display:none;
  }
}

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

html
<div class="block" data-is-hide="true"> ... </div>
scss
.block {
  display:block;
  &[data-is-hide="true"] {
    display:none;
  }
}

data属性に書き換えるだけなので変更も容易です。
さらに特に意識しなくてもCSSの名前が衝突することがなくなりますし、classが短くて済みます。

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

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

Reactと組み合わせても便利

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

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

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

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

data属性がcssで操作できるということは・・・?

こんなこともできると思います。

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
.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
<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
.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%);
          }
        }
      }
    }
  }
}

最後に

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

trkbt10
愛知県の音大を卒業後、クソ田舎岐阜の大垣の企業に入社。今は東京で働いている。
http://xn--9i8hku.ws/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした