SCSSとBEMでElementをBlockのModifierで変化させるように記述する方法

BEM を SCSS 記法で表現する時に、Block(ブロック)の Modifier(モディファイア)に対する Element(エレメント)を SCSS で、どのように書いたら良いかずっと悩んでいました。

以下のように、それぞれの Element に同じ Modifier を記述することも可能ですが、Block の Modifier で Element 全てを変化させたい、ということはよくあると思います。HTML に記述する際にも Block の Modifier なのに、Element にも同時に Block のための Modifier を追記する必要があります。Element も全てが変化する訳でもないので、Element に Modifier を追記したり、しなかったり…運用する上でも良いものとは思えません。

.block {
  &--modifier {
    // It will generate .block--modifier
  }
  &__element-A {
    // It will generate .block__element-A
    &--modifier {
      // It will generate .block__element-A--modifier
      // 
    }
  }
  &__element-B {
    // It will generate .block__element-B
    &--modifier {
      // It will generate .block__element-B--modifier
    }
  }
}

上記の問題を解決する方法がCSS-Tricksというサイトで紹介されていました。
Using Sass to Control Scope With BEM Naming | CSS-Tricks
一度ローカル変数に Block の名前を格納し、Element 内で変数を利用して Block を指定します。こうすることで Element 内で、Block の Modifier を指定することができます。

.block {
	$this: &; //$this変数に'.block'を格納する。
	&--modifier {
		// It will generate .block--modifier
	}
	&__element {
		// It will generate .block__element
		#{$this}--modifier & { // #{ }構文で文字列として出力。
			// It will generate .block--modifier .block__element   
		}
	}
}

上記の記述をすることで、[ .block–modifier .block__element ] として出力され、Block の Modifier に依存させた Element を指定できていることがわかります。

石井秀幸@WEBデザイナー
WordPress公式『横浜 WordPress Meetup』主宰/株式会社ノクチ基地 取締役/モンゼンクリエイティブ合同会社 代表。WEB制作に関する技術や役立つ情報を発信していきます。10年にわたるWordPress歴を背景に、幅広いアイデアを形にするお手伝いをしています。