LessでBEMってみたらかなりさくさくコーディングできた!という話

BEMを使ったCSSのクラス設計(MindBEMding)ですが、これをSassでやろうとすると、結構泣けてきます。

たとえばこんな感じになるんでしょうかね。

$block: ".block";
#{$block} {
	display: block;
}
#{$block}__element {	
	border: 1px solid #CCC;
}

#{$block}__element_modifier {
	border-color: #FFF;
}

また、Sass 3.3以降だと、

.block {
	display: block;
	@at-root {
		#{&}__element {
			border: 1px solid #CCC;
			@at-root {
				#{&}--modifier {
					border-color: #FFF;
				}
			}
		}
	}
	
	//もしくはこんな感じ
	@at-root {
		#{&}__element {
			border: 1px solid #CCC;
		}

		#{&}__element--modifier {
			border-color: #FFF;
		}
	}
}

こんな感じで、BEMれるようです。
参考: BEMという命名規則とSass 3.3の新しい記法 – アインシュタインの電話番号

ただ、@at-rootなどを乱発したり、いちいちshiftをおしながら#{&}って入力していくのは、ちょっと大変すぎるなと個人的には感じます。というかめんどくさい。せっかくネストして楽にかけるはずのCSSが、より大変になっている気がしてしまいまして。

LESSでやってみる

Lessだと、こんな感じに書けて、

.block {
	display: block;
	&__element {
		border: 1px solid #CCC;
		&--modifier {
			border-color: #FFF;
		}
	}
}

このソースを、lessをcssに変換(less2css) | Magonote-toolsにコピペするなり、普通にlessで走らせるなりすると、

.block {
  display: block;
}
.block__element {
  border: 1px solid #CCC;
}
.block__element--modifier {
  border-color: #FFF;
}
 

こうなります。こんな感じでLessはネストしつつ、しっかりBEMなCSSが出力されます。非常に直感的です!

留意点

SassとLessの大きな違いとなっていたextendがLess1.4から実装されましたが、&を含むセレクタのextendはできないようです。また、実際に出力されるセレクタを指定してもextendはできないようです。

なので、.block__element–modifierに.block__elementのスタイルを継承するようなことはできず、html側で両方のclassを指定する必要があります。

BEMという命名規則とSass 3.3の新しい記法 – アインシュタインの電話番号でも言及されていた、HTMLが冗長になってしまうと言う問題に対処することは難しいです。

まとめ

Windowsでも導入が簡単・JavaScriptとの相性が良いなどのSassには無いメリットもあるし、Compassでよく使うMixin等の移植もそこまで難しくないです。CssSpriteもCompass以外のツールで対応できますしね。

Sassに比べるとCompassのようなフレームワークが無かったり、extendもSassのほうが若干協力だとかで
なかなかLessを使おうという場面は少ないとは思いますが、それでもBEMとの相性がよいというのはなかなか見逃せない部分じゃないかなと思います。

LessのextendもSassには無い書き方があったりしておもしろいですし、用途によって使い分けるとなかなか楽しいんじゃないですかね。