Sass3.3の新機能とBEM
現在RCでリリースの近いSass3.3ですが、新機能でBEMを取り入れた命名がしやすくなるようなので、正式リリースに備えて紹介&メモします。
BEMとは?
Block、Element、Modifierの頭文字。
厳格な命名規則でCSSのクラス名に高い透明性を持たせ、複数名のエンジニアで開発・運用する際など規模の大きなプロジェクトに適した命名規則。
詳細に解説されている方が沢山いらっしゃるので、ここでは具体的な説明を省きます。
Sass3.3でBEMを使った命名がしやすい訳
Sass3.3で追加された#{&}(インターポレーション)と@at-rootによって、BEMの規則で記述しやすくなっています。
- #{&}:現在のセレクタ名を取得
- @at-root:記述上はブロックのセレクタでネストしていても入れ子にならない
@at-rootでネストして記述すると、明示的に入れ子にしなかった時と同じ結果になります。
/* Sass 3.2.x以前 */ .block { background: #ccc; .block__element { background: #000; } /* Sass 3.3 */ .block { background: #ccc; @at-root { #{&}__element { background: #000; } } }
下記コードは#{&}と@at-rootを使ってBEMっぽく記述した例になります。
- Sass
-
.block { background: #ccc; $block: #{&}; @at-root { #{&}__element { display: block; padding: 10px; background: #000; color: #fff; } #{&}__element--modifier { @extend #{$block}__element; background: #333; } } }
- CSS(出力結果)
-
.block { background: #ccc; } .block__element, .block__element--modifier { display: block; padding: 10px; background: #000; color: #fff; } .block__element--modifier { background: #333; }
BEM用のmixin
Sass3.3でBEMの規則で記述する際に@at-rootの記述を省けるmixin。
modifierにelementを継承する際にインターポレーション(@extend #{&}__element)ではコンパイルエラーとなるため、変数より参照する@extend #{$block}__elementとしています。
@extend .block-element 等、直接書くよりは変数を利用した記述の方がメンテナンス性が高いですが、@extend等でもインターポレーションが使えるようになるとより良いと思います。
@mixin block($name) { .#{$name}{ @at-root{ @content; } } } @include block('block') { background: #ccc; $block: #{&}; #{&}__element { display: block; padding: 10px; background: #000; color: #fff; } #{&}__element--modifier { @extend #{$block}__element; background: #333; } }