blog

CSS の状態管理にカスタムデータ属性を使う

    • Ryuichi Nonaka

    はじめに

    少し前に何かで見かけて試してみたいなと思っていた 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 では getAttributesetAttribute が使えます。また 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 からの制御もし易くなりますね。

    参考サイト

    コメント・フィードバック