読者です 読者をやめる 読者になる 読者になる

波打際のブログさん

主に、プログラミング備忘録など。

俺のBEMは間違っているがわかりやすい

はじめに

 私はデザイナーではないです、cssを全く理解してないエンジニアです。そんなエンジニアが最近scssでBEMを使う時に主張したいことがあったのですが、ネット上にそんな記事はなく [要出典] とか [独自研究] とかつけられそうなので主張しておきます。

前提としてBEMは神

 Block-Element-Modifier の概念を作ることで、統一された明快なDOM構造を定義することが出来ます。

バリデーション結果に応じてアイコンを切り替える例

form.slim
.form
  .form__field
    .form__field__status
    input type='text'
form.scss
.form {
  .form__field {
    .form__field__status {
      background-image : url('ok.png');
    }
    &.form__field--ng {
      .form__field__status {
        background-image : url('ng.png');
      }
    }
  }
}

BEMに基づいて命名されているという前提が頭に入っていれば、バリデーション結果に応じて `.form__field` に `.form__field--ng` をつけたり外したりすることで、アイコンを切り替えれることが15秒くらいで理解できると思います。

最高です。秩序のないcssの世界に秩序と平和をもたらしてくれました。そんな最高なBEMを間違った用法で使いたいというのが今回の主張になります。

主張

`.form__field__status` ← これ長いからやあよ

 BEM唯一の難点です。階層が深くなるほどエレメントのチェインが長くなります。

そこでこうしたい
.form
  .form__field
    .field__status
    input type='text'

Block-Element-Modifier と Element-Element-Modifier の2種類を用いて BEMBEEM にしたい。

聞かれること/言われること

ブロックが明確ではない

Q. `.field__status` が `.form` ブロックのエレメントであることがわかりにくい。
A. そのようなケースは下記のようにブロックの中に親ブロックのエレメントが混ざっている等、構造がおかしいケースでしか存在しないと考えています。

.block1
  .block2
    .block2__element
    .block1__element
  .block1__element

また、クラスがブロックかどうかはチェインしているかどうかで判断できます。

エレメントのチェインをしなければ正しいBEMで見た目すっきり

ブロックにわけよう

Q. ブロックを分ければチェインはしなくてすむよね?
A. 階層的に意味のある構造をブロックに分割することで複雑になりリファクタしにくくなると考えています。

.form {
  .form__field {

  }
}

.field-status {
  
}

formのfieldでしか使わないstatusをブロックに分けることで影響範囲(使用範囲)が不鮮明になります。例えば3年後にformを撤去することになった際に.field-status が適切に撤去されるでしょうか?どこか他の場所から参照されることを恐れてそのままにしてしまう気がします。

階層を浅くしよう

Q. `.form__field` と `.form__status` のように浅い階層にすればチェインしなくてすむよね?
A. 階層的に意味のある構造から階層を取り除くことで複雑になりリファクタしにくくなると考えています。

.form {
  .form__field {

  }
  .form__status {
    
  }
}

このscssを見た時、`.form__status` がフィールドのバリデーション状態を表すことを理解できる人は居るのでしょうか?

これらの解決策はBEMと見た目を守れても、「意味的に正しく明快な構造」と言う重大な要素を守れていないです。

BEMに反している

Q. その書き方はBEMではない。
A. はい。しかしBEMを厳密に守ろうとするために、構造が複雑になったり、意味が無いクラスができたり、影響範囲が不鮮明になることは本末転倒だと思います。正しいBEMを書きたいわけじゃなくて、統一された明快なslimとscssを書きたいです。(俺のBEMは間違っているがわかりやすい)

Q. みんながオレオレルールを作るのは良くない。
A. その通りで何でもかんでもオレオレルールを作れば秩序が崩れます。しかし、明らかな問題があって、その解決策(オレオレルール)が明快で個人の裁量に左右されない(誰がやっても同じ書き方ができる)ものであれば、問題と共通認識を持つコストとのトレードオフだと思います。

結局この記事は何?

 今後 Block-Element-Modifier と Element-Element-Modifier でやっていきたいと考えています…が!従属等の構造的意味合いを崩してまでBEMを守ろうとする考え方が一般的です。

 ということは、気づいたり指摘されていないだけで Element-Element-Modifier の概念を導入すると破綻してしまうケースが出てくるのでは?と疑問が浮かびました。

しかし、BEMとして間違っている以外の理由が思いつかないのです。そこで、何か問題にお気づきの方にサンプルコードとかと一緒にぜひコメントしていただければと考え記事にしました。