BEMのBlockとElementについて、僕の考え。

2016年12月4日 / category:その他-lab

BEMで設計する際に、次のことで悩まされるようです。

  • Blockにするか、Elementにするか
  • クラス名、どうしよう。

BEMに限らず、コーディングは自分の中でルールを決めておくことで、作業がスムーズになります。
BEMとは設計の考え方であって、個々それぞれ設計が変わってきます。自分の中で、自分のBEMの考え方というものを確立させ、ルール化することができれば、悩むこともなくなり、コーディングがスムーズになります。

例えば、次のようなマークアップがあったとします。

<section>
<h2>タイトル</h2>
</section>

このマークアップに、BEMの設計でクラス名を追加すると次のようになります。

<section class="block">
<h2 class="block__title">タイトル</h2>
</section>

では、次のようなクラス設計は、どうでしょうか。

<section class="block">
<h2 class="block-title">タイトル</h2>
</section>

section要素、h2要素ともにBlock。
これはBEMの概念上、Blockを入れ子にすることについては問題なく、ElementがないBlockがあっても問題ありません。
BEMの設計としては間違っていない、と考えることもできます。
ただ、個人的には、とても違和感があります。h2要素はタイトルであり、タイトルはElementであるべきだと思うからです。

次の場合は、どうでしょうか。

<section class="blockA">
<h2 class="blockA__title">タイトルA</h2>
</section>

<section class="blockB">
<h2 class="blockB-title">タイトルB</h2>
</section>

タイトルAのh2要素は、Element。
タイトルBのh2要素は、Block。
こちらも同様に、BEMの設計としては間違っていない、と考えることもできます。
個人的には、h2要素がBlockになったり、Elementになったりと、考え方が変わってしまうことに違和感を覚えます。
また、クラス設計に悩んでしまう原因になります。

私の場合は、
HTMLのタグをあらかじめBlockかElementかを決めておく。
というルールを定めておくことで、コーディングがスムーズに行うことができています。
このルールを定める際に、2点ほど悩んだポイントがありますが、まずBlockとなるHTMLタグは次のものです。

■Block
header, footer, main, article, section, aside, div

続いて、Elementですが、これはたくさんありますので、主なHTMLタブのみ記述します。
(基本的には、上のBlock以外のHTMLタグが、Elementということになります。)

■Element
h, p, span, img, a, ul, ol, li, dl, dt, dd, figure, divなど

ここで先ほど述べた2点ほど悩んだポイントですが、
1点目は、div要素は、Block、Elementとどちらにもなりえるだろうという結論に至ったこと。
理想はやはりどちらかに統一したい。が、div要素だけは難しい。
マークアップをする際に、よく出てくるケースとして、次のことがあります。

A. section要素をdiv要素で囲みたい
B. section要素の中に、インナーとしてdiv要素を追加したい

まず、Aのケースをマークアップで書くと次のようになります。

<div>
<section>
<h2>タイトル</h2>
</section>
</div>

これにBEMを使ってクラス設計をすると次のようになります。

<div class="block-wrap">
<section class="block">
<h2 class="block__title">タイトル</h2>
</section>
</div>

おそらく、これは皆さん納得のクラス設計かと思います。
この場合、div要素はBlockになっています。

続いて、Bのケースの場合ですが、まずマークアップは次のようになります。

<section>
<div>
<h2>タイトル</h2>
</div>
</section>

これをもし「div要素はBlock」と統一した場合、次のようなクラス設計になります。

<section class="block">
<div class="block-inner">
<h2 class="block-inner__title">タイトル</h2>
</div>
</section>

h2要素のクラス名が、block-inner__titleです。
「-inner」取りたい・・・、と思うのは私だけでしょうか。
次のようなクラス設計も考えられます。

<section class="block-wrap">
<div class="block">
<h2 class="block__title">タイトル</h2>
</div>
</section>

h2要素のクラス名は、問題なさそうです。
ただ、section要素に「-wrap」がつくのは、少々違和感があります。

このケースの場合、div要素をElementとしてクラス設計すると次のようになります。

<section class="block">
<div class="block__inner">
<h2 class="block__title">タイトル</h2>
</div>
</section>

どうでしょうか。このクラス設計が1番しっくりくるような気がします。
ということで、div要素は、Block、Elementとどちらにもなりえるだろうという結論に至りました。

続いて、2点目ですが、
dl要素、ul要素、ol要素は、Block、Elementどちらか。
現在の私のルールでは、Elementです。
ただし、この考えは今でも悩んでおり、今後Blockになる可能性を否定できません。

例えば、次のようなある商品のリストをマークアップする場合、

<ul>
<li>商品A</li>
<li>商品B</li>
<li>商品C</li>
</ul>

現在の私の考えであれば、次のようなクラス設計にします。

<div class="product">
<ul class="product__list">
<li class="product__list-item">商品A</li>
<li class="product__list-item">商品B</li>
<li class="product__list-item">商品C</li>
</ul>
</div>

Blockであるdiv要素を追加しています。
ul要素をBlockとして考えた場合、次のようなクラス設計になると思います。

<ul class="product-list">
<li class="product-list__item">商品A</li>
<li class="product-list__item">商品B</li>
<li class="product-list__item">商品C</li>
</ul>

どちらでも問題なさそうです。

大事なことは、自分の中でルールを決めて統一するということです。
上の場合、どちらでも問題なそうですが、ul要素がBlock要素になったり、Element要素になったりとバラバラになってしまうと、悩む原因になってしまいます。

次の記事で「クラス名、どうしよう。」について書きたいと思います。

このエントリーをはてなブックマークに追加