JavaScriptに関するお知らせ

SINCE2019
>
【CSS】ReactやVueのCSS設計でBEMがイマイチな理由

【CSS】ReactやVueのCSS設計でBEMがイマイチな理由


こんにちは!BEMと2年付き合って別れたMizutani(@sirycity)です。wordpressとかだと結構使うけど。

今回はReactとかvueのCSS設計ではBEMイマイチじゃない?って話です。

結論

BEMの擬似的スコープや状態の明示はJSでできるようになったのでBEMはだいぶ不要

BEMって?

概要

BEMの説明なんぞググれば相当詳しいのが出てきますが要点を抑えるとこんな感じ。

  • CSS設計手法の一つ
  • シングルクラス(1つのHTMLタグに1つのクラスを付ける)
  • 名前の付け方が独特 [block]__[element]--[modifier]

[block]__[element]--[modifier] の3つについてはこんな感じ

  • blockとelementはスコープ(「この中でしかCSSが作用しない」みたいな感じ)
  • blockは大きめのスコープ、elementはblockの中にある小さめのスコープ
  • blockが<ul> elementが<li> みたいな感じ
  • modifierは状態を表す ...例を見たほうが分かりやすいかも

BEMの例。こんな感じ

<ul class="ul">
  <li class="ul__li">なんかの項目</li>
  <li class="ul__li">なんかの項目</li>
  <li class="ul__li">なんかの項目</li>
  <li class="ul__li">なんかの項目</li>
  <li class="ul__li--red">赤い項目</li>
  <li class="ul__li--large">大きい項目</li>
</ul>

BEMの良い所

BEMの良い所は色々あるけど結局はこれに尽きる

「適用されているスタイルが分かりやすい」

クラスが1つしかない上、クラス名が場所と状態を表しています

上の例だと赤い項目のとこに適用されてるスタイルを知りたければ.ul__li--redを見ればok。逆に.ul__liが適用されている箇所を知りたくてもulの中のliの場所にあるんだなーってすぐ分かる。

そして--redを見ればなんとなく赤くなってんだなーってのがすぐ分かる。

この分かりやすさがBEMの長所!とにかくどこに何があるかが分かりやすい。BEMはその長すぎる名前によってCSSに本来存在しないスコープと状態を擬似的に作っているんですね!

モダンフロントエンドでBEMはイマイチ

やっと本題に入ります。ReactやvueのモダンフロントエンドでBEM使うのがあんまり良くないと思う理由。

cssスコープを小さくできる仕組みがある

cssはグローバルスコープです。これはcssの致命的な弱点の一つですが、前述の通りBEMは命名規則によりスコープを作り出しています。

でもモダンフロントエンドにはスコープを切れる仕組みがある。そう、普通にスコープ切れるの。reactならjsx、vueならscopedみたいに。svelteとかは最初から切れてる。

スコープが切れるんだったらBEMのうちBEの意味はないです。さっきのul liの例でも、スコープが切れていたらこれでいいんです。

<ul class="ul">
  <li class="li">なんかの項目</li>
  <li class="li">なんかの項目</li>
  <li class="li">なんかの項目</li>
  <li class="li">なんかの項目</li>
  <li class="li--red">赤い項目</li>
  <li class="li--large">大きい項目</li>
</ul>

状態をJSで明示できる

従来のフロントエンドでは、JSによるCSSの操作は手続き的でした。こんな感じに。

ここで重要なのは、CSSのmodifierを見ればこのスタイルがいつ使われるか分かるってことっすね。

--closedならメニューが閉じてる時に適用されるスタイルなんだなーって分かる。

<nav class="menu--closed">MENU</nav>
.menu--closed {
  display: none;
}
.menu--opened {
  display: block;
}

一方、モダンフロントエンドではJSによるCSSの操作は宣言的(というか関数型)アプローチをとることが多いです。

reactだとこんな感じ。

<nav style={{display: isOpened ? 'block' : 'none'}}>MENU</nav>

ここで重要なのが、JSの値が分かればどのスタイルが適用されるかが分かる、つまり別にCSSに状態を明示しなくてもいつ使われるか分からなくならないってことです。

modifierが不要というよりも、modifierが担っていた役割はJSが引き継いだって感じっすね。

さいごに

てな感じで、reactやvueとかでBEMが不要だと思う理由についてでした。

じゃあどうやってCSS設計せいって話ですが、近日中に自分の例を上げようかと思います!以上。

グッバイBEM、wordpress案件でまた会おう



PREV
2020-05-15
【JS】Next.jsとGatsby.js(SSRと静的化)の比較と選び方

NEXT
2020-05-19
【JS】IntersectionObserverで複数を監視