BEM記法は不要かもしれない
現在でもたまに使われるBEM記法。これはいつから出たのだろうと思い、少し調べてみました。
すると、2009年頃から出来たもののようです。
2009年と言えばWindows 7の時代
2009年と言えば、今(2024年)から15年前の話ですが、このころのインターネット環境は、どうだったのかも少し調べてみた所、Windows 7が発売された年のようですね。
この頃と言えば、HTMLは4、CSSは2の時代です。
PCもWindows 7が発売されたばかりでもあるため、処理性能も今ほど高速でもなく、今は亡きIEも活躍していた時代、さらに言うとストレージはHDDがまだ主流だった時代(この頃からもSSDはあるぜと言うのなら、それが果たして一般に流通していたのかを考えてみてください)。
そんな環境だからこそ、CSSセレクタはクラスだけにして少しでも処理を速くしようと、かつクラスだけで要素の概要を把握出来るようにしようという努力の元、BEM記法などの設計思想が生まれたのではないかと思います。
ネストがないCSSだからこそ生まれたのではないか
CSSはその当時、ネストなど無く、CSS割り当て対象に対して都度セレクタを書いていく方式です。
親要素さえしっかり定義されていれば、後は要素セレクタをつなげていけばいいのですが、先述の通りクラスセレクタ以外のセレクタは重いという事情もあったのでしょう。
なら、クラスセレクタだけでなんとか整理しようと生まれたのがBEM記法ではないのかと思います。
しかし、今はもうそのような時代ではなくなってきています。
BEM記法の問題点
BEM記法の難点は、クラスがとにかく長くなる事。これにより、コードの可読性が著しく低下します。
そしてなにより、一個人が指定した「Block」「Element」「Modifier」の名前が、信用に値するかという事です。
HTMLは色々な表現をするため、DOM要素やネストされる数も増えてきています。
そのため、「Block__Element--Modifier」の3要素だけでは足りないため、「Block__Element__Element__Element--Modifier」となってもいいそうです。
つまり「Block」が最上位の親要素、「Element」が途中経過までに存在する要素、「Modifier」が実際にCSSを適用する目標でしょうか。
それなら「.parent__div__ul__li--p」と、実際に要素セレクタをそのまま書いてもいいわけですが…
それなら普通に要素セレクタでもいい気がします。
しかし、「Element」「Modifier」に都度何等かの名前を付けなくてはならないと思っている人は、その作業が面倒になり、デタラメな名称になっていくのではないかと思います。
そのような状況で付けられた名前は、当然信用に値しないため、HTMLの知識がある人間なら必ず知っているdiv等の要素セレクタを使った方が、はるかに信用できるのです。
クラスセレクタ以外のセレクタは処理が重いと言うのなら、その端末はもうハー〇オフに捨ててきた方がいいです。
それでも他のセレクタが重いと言う人は、ハード〇フでジャンクPCを買ってきて、そのPCで制作・検証を行ってください。
あと、調べ物をしている時に、まれにあるけど、サンプルコードのCSSでBEM記法が使われている。
いやこの場合、要素セレクタを使ってくれないと、どの要素にどのCSSを割り当てたらいいのか、わかんないよ。
せめてCSSだけでなくHTMLのサンプルも用意しておいてほしい。
SCSS(Sass)とBEM記法との相性は最悪
これまでにいくつかSCSSでBEM記法が使われた場面、もしくはサンプルコードを見てきました。
もしかしたら、BEM記法はSCSSには向いていないのではないかと。
特によくあるのが
.Block{
&__Element{
&--Modifier{
}
}
}
この形式です。
クラスが分割されているため、クラス名でそのまま検索する事が出来ませんし、なにより要素セレクタがないため、クッソ長くなったHTMLのクラス名を確認して追いかける必要があります。
『BEM記法を書くのが便利』と言われていますが、それはあくまでも”BEM記法を書くのが便利”であって、最終的に可読性の高いコードが仕上がるわけでもありません。
このような書き方をせずとも、ネストが出来るようになったCSS、もしくはSCSSでは普通に要素セレクタをネストさせればいいのです。
要素セレクタが重いと言っている人は…以下略
にも拘わらず、古の記法を呼び起こし、ネストが可能という特性までつぶしてしまう必要もないでしょう。
あと、SCSS自体の話ですが、正直、親メソッド「&」に文字を結合できなくしてほしいです。
「&__Element」と書く事で、親セレクタに対し「__Element」を追加した文字列になりますが、これは本当にコンパイルエラーにすらなってほしいです。
今はBEM記法は必要なのか
ネストが出来るようになった、宣言やプロパティが増えたなどはありますが、CSSの基本的な記法は今でもあまり大差はありません。
基本的には、セレクタで対象を指定しては、それに適用するスタイルを書いていくという方法です。
ならBEM記法は今もなお現役かと言われれば、個人的にはもう引退させてあげてもいいんじゃないと思います。
BEM記法をかじった人が考えたElement個体の名前よりも、要素セレクタを使った方がはるかに信用できますし、長いクラス名もない方が、HTMLも可読性がいいですし、なによりネストが出来る現在のCSS、もしくはSCSSならBEM記法も必要ありません。
今の端末は、CSSのセレクタぐらいでは、どうって事のないスペックをしたものばかりですし、それで影響の出る端末は、もうセキュリティの面からして危険な古いジャンク品です。
代替案
何度も言いますが、ネストが出来るようになったCSS、もしくはSCSSがあれば、BEM記法はもう必要ありません。
ならBEM記法なしにどうすればいいのかという話ですが、簡単です。
まず親セクションに対しIDを指定します。
IDはアンカーリンクのためだけにあるのではなく、れっきとしたセレクタです。
しかも、同じページに1つしか存在してはいけないという原則もあるため、CSSもIDを親セレクタにしていれば、ほかの箇所に影響を与える事は、まずありません。
次に子要素にはむやみにクラスを付けるよりも要素セレクタを使ったほうが、CSS側でもHTMLのどの要素に割り当てているのかが、わかりやすくなります。
divの中のdivのように、子要素にも同じ要素があるのなら、その親要素に対してクラスを付けるのもいいですが、子セレクタ等の要素を限定するセレクタがCSSにはあります。
それらを駆使して、子要素の同要素に影響を与えないようにすればいいです。
新しいCSSや、SCSSのようにネストが出来るのであれば、HTMLと同じように要素セレクタでネストしていけばいいのです。
CSSを割り当てない要素もセレクタを作り、CSSもHTMLと同じ構造を作るのです。
こうする事で、直感的に両者の把握が出来るようになります。
設計手法があれば良くなるものではない
BEM記法に限らず、とりあえず何等かの設計手法を用いればよいという考えは、逆に複雑で冗長なコードを作り出してしまい、後の変更で大きな問題と化してしまいます。
作って納品するだけなら、まだ問題はないかもしれませんが、その後の保守が問題になってきます。
私は新規案件よりも既存の保守が多かったため、そういったコードを多く見てきました。
その手法を取り入れる前に、それが何のためにあるのか、もしそれがその手法を取り入れなければ解決できないのであれば、取り入れるべきですが、
もしそうではなく、自動的に改善されるものであると思っているのなら、その手法を取り入れるのは避けるべきです。
無意識で作るコード程、悪いコードはありません。
大切なのは、何等かの設計手法を持ち込むのではなく、そもそもわかりやすいコードを書くのを心がける事です。
文字だけの世界で、どうすればよくなるのかを考える事、まずそれが大事です。