BEM 風に CSS を書くとき、孫要素はどうしてる?

CSS, SCSS

先日 BEM で CSS を書くとき、孫要素はどうしてる?といった記事を読みました。せっかっくなので「はて自分はどうしてるかな」と考えてみることにします。

BEM ?

BEM は CSS のクラス命名手法の一つで、Blocks, Elements and Modifiers を組み合わせて命名します。3つの頭文字をとって BEM。

http://getbem.com/introduction/ より

具体的には次のように書きます。B, E, M を組み合わせて CSS を組み立てて行きます。

.block {}
.block__element {}
.block--modifier {}

.menu {}
.menu__item {}
.button {}
.button--theme-green {}

孫の不在

私も BEM っぽい書き方、あくまでも「っぽい」書き方をしますが、 blocks と elements だけでは間に合わず困ってしまう時がしばしばあります。それは孫が必要になった時。block と element は言わば親子ですが、そのさらに下に関連する要素が必要な時です。

「孫は存在してはならず、新しい別の block をつくりなさい。」というのが BEM 原理主義だと聞いたこともあります。ただ「そんなこと言われても、だってこれ孫じゃん」という場面にはよく出くわします。冒頭の記事も同じような問題を抱えていて、いくつかのアイディアが載っていました。

  1. 孫と子は区別なく平坦にする
  2. 新しい block を追加する
  3. アンダースコア2つをさらに続ける
  4. ハイフンでつなげる
  5. 新しい別の文法を導入する(アンダースコア1つで繋げる、など)

ハイフンでサブブロックを作る

改めて自分の過去の実例を振り返ってみたところ、私は2番目と4番目の折衷案のような方法を取っていました。

元記事の例。

.post {}
.post__meta {}
.post__meta-category {}
.post__meta-date {}

次のように解釈しているようです。ちょっとズルいというか、言い訳がましいというか、分かりにくいというかなんというか。

  1. postは block
  2. meta-categoryは element。 meta かつ category

一方、私の場合。

.post {}
.post-meta {}
.post-meta__category {}
.post-meta__date {}
  1. post-metaがある意味 block
  2. categoryが element

どうやら私は.block-subblock__elementと解釈しているようです。.block__elementという大枠は崩したくない、と考えているのでしょうか。アンダースコア前後でぷっつり分ける、としたいのだと思います。

sass で書くと差がでるかもしれません。

// 「meta-category がひと塊り」と分かりにくい
// 上に遡る途中で element と block が混在する
.post{
	&__meta{
		&-category{
			
		}
		&-date{
			
		}
	}
}

// アンダースコア2つから上は全部ブロックなので分かり易い
// 極論 element だけ見ていれば良い。block はパンくずみたいなもの
.post{
	&-meta{
		&__category{
			
		}
		&__date{
		
		}
	}
}

私は-subblockを挟んであげるとしっくりきます。

我ながら「どっちも一緒だよ」とも思いますが、うまく言えないけれどやっぱり差があります。しっかり説明できるまでにはしばらく時間がかかりそうなので、まずは言葉を磨く前に、BEM でもなんでもなくクチャクチャなこの WordPress テーマを書き直すところから始めたいと思います。