BEMのModifierを data- 属性で管理する方法

classがいっぱいでコードが読みにくい

ボタンの基本的なスタイルを書いて、Modifierでバリエーションを作ろうと思ってこんなコードを書きました。

<a href="#" class="c-button c-button-small c-button--icon">ボタン</a>
.c-button {
  position: relative;
  display: inline-block;
  width: 100%;
  max-width: 350px;
  padding: 10px 20px;
  color: white;
  text-align: center;
  background-color: #065da3;

  //サイズ(小)
  &--small {
    max-width: 200px;
  }

  //アイコン画像付き
  &--icon {
    &::before {
      position: absolute;
      top: 50%;
      right: 10px;
      display: block;
      font-family: "Font Awesome 5 Free";
      font-weight: 900;
      content: "\f061";
      transform: translateY(-50%);
    }
  }
}

HTMLにclassがいっぱいで読みにくい!

(これぐらいなら、気にならない方がほとんどだと思いますが…)

違う書き方はないか調べていくうちに、カスタムデータ属性を使った方法があることを知りました。

カスタムデータ属性を使って、Modifierを管理する

カスタムデータ属性を使って、先ほどのコードを書き換えました。classの数がModifierの数だけ増えないので、特にHTMLがすっきりしたと思います。

<a href="#" class="c-button" data-size="small" data-icon="arrow">ボタン</a>
.c-button {
  position: relative;
  display: inline-block;
  width: 100%;
  max-width: 350px;
  padding: 10px 20px;
  color: white;
  text-align: center;
  background-color: #065da3;

  // サイズ(小)
  &[data-size="small"] {
    max-width: 200px;
  }

  // アイコン画像付き
  &[data-icon="arrow"]::before {
    position: absolute;
    top: 50%;
    right: 10px;
    display: block;
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    content: "\f061";
    transform: translateY(-50%);
  }
}

カスタムデータ属性を使ったメリット

Modifierの役割をカスタムデータ属性に移すことにより、classが増える事を防ぐ

カスタムデータ属性の形式から、どの要素にどんな影響を与えるかが分かりやすい

<!-- data-size="small" → サイズに関する変更 -->
<!-- data-icon="arrow" → アイコンに関する変更 -->
<a href="#" class="c-button" data-size="small" data-icon="arrow">ボタン</a>

他にもメリットはあるのですが、カスタムデータ属性の形式から、要素に与える影響を推測しやすいのが良いと思います。