CSS の状態管理にカスタムデータ属性を使う
はじめに
少し前に何かで見かけて試してみたいなと思っていた CSS の状態管理にカスタムデータ属性を使う方法について調べてまとめてみました。
カスタムデータ属性とは
data-* グローバル属性はカスタムデータ属性と呼ばれる属性の組を作り、HTML と、スクリプトによって使用されるであろう DOM 表現との間で、固有の情報を交換できるようにします。すべてのカスタムデータは、属性を設定した要素の HTMLElement インターフェイスを通して使用できます。HTMLElement.dataset プロパティがそれらへのアクセス手段を提供します。
Mozilla Developer Network - data-*
簡単に言えば HTML Element に対して <div data-hoge="fuga">
のような独自に属性を設定できる機能です。
サンプル
カスタムデータ属性でボタンの文字色を toggle するサンプルがこちら。
See the Pen Custom Data Selector by nuko’s kitchen (@nukos) on CodePen.
カスタムデータ属性の使い方
カスタムデータ属性を HTML に設定し、CSS/JavaScript(jQuery) から参照する方法をお復習いします。
HTML
<button class="button" data-is-active="true"></button>
CSS
CSS は属性セレクタを使って柔軟に制御できます。
.button[data-is-active=true] {
color: red;
}
javaScript
素の JavaScript では getAttribute
と setAttribute
が使えます。また dataset
を使うことでより簡単にカスタムデータ属性を操作できますが Internet Explorer 11 以上 でないと使えません。dataset
の場合、ハイフン -
で繋がれたカスタムデータ属性 is-active
はローワーキャメルケース isActive
で取得することができます。
var element = document.querySelector(".button");
//get
var attr = element.getAttribute('data-is-active');
var attrCamel = element.dataset.isActive;
//set
element.setAttribute('data-is-active', true);
element.dataset.isActive = true;
jQuery
jQuery の場合は data()
と attr()
の2つの方法があり、それぞれ挙動が違うので注意が必要です。attr()
は DOM のカスタムデータ属性を直接書き換えますが data()
は jQuery オブジェクト内のキャッシュを優先的に使用し、キャッシュが存在しないときのみカスタムデータ属性から値を取得します。
//get
var data = $('.button').data("is-active");
var attr = $('.button').attr("data-is-active");
//set
$('.button').data("is-active", true);
$('.button').attr("data-is-active", true);
カスタムデータ属性を JavaScript だけで使う場合は data()
を使えば良いですが、 CSS からも使う場合、DOM の カスタムデータを書き換えないと変更を検知してもらえないので attr()
を使うことが必須となります。 jQuery オブジェクトからも参照したい場合は状態を変更するときに data()
と attr()
どちらも行わなければなりません。
$('.button')
.data("is-active", true)
.attr("data-is-active", true);
冗長ではありますが jQuery の場合は独自に拡張を作らない限りこうするしかありません。蛇足ですが、プロパティを制御する prop()
は JavaScript のプロパティを制御するものなのでカスタムデータ属性には使えません。
セレクタを定義する Mixin
CSS のカスタムデータ属性セレクタの指定を簡略化するために Mixin を作ってみました。
状態の有効・無効にした際のスタイルを以下のように指定します。
.example {
@include data-state('active') {
color: red;
}
@include data-state('active', false) {
color: black;
}
}
プリコンパイルされた CSS はこのようになります。
.example[data-is-active=true] {
color: red;
}
終わりに
jQuery の場合、data属性の変更方法が冗長なところはありますが、カスタムデータ属性を使うことで状態を class 以外のところで管理できるので class が汚れにくく、JavaScript からの制御もし易くなりますね。