クラス設定ルール : クラス名(クラス設計)ルール

前回の記事では、クラス名の固定化について解説しましたが、それだけではまだクラス名のルールは十分ではありません。
コーディング作業を進めていく際に、次の迷い(問題)が出てくると思います。

そもそもクラス設定が必要かどうかの判断が迷う。

では、クラスを設定するタイミングはいつでしょうか。
まず、前提として、BEM設計の場合、CSSで要素(タグ)を指定する場合、必ずクラス指定にしなければいけません。
これについては、後ほど改めて解説します。

それでは、BEM設計で構築していない場合の例で、コーディングのフローを再現し、どのタイミングでクラス設定をするかみてみます。

例:リスト要素の中に画像とリンクテキストが配置されているレイアウトのコーディングフロー。

<ul>
<li></li>
</ul>

まずは、リスト要素なので、ここまでコードを書くでしょう。

<ul>
<li><figure><img src="画像パス"></figure><a href="#">リンクテキスト</a></li>
</ul>

続いて、リストアイテムの中に配置する画像とリンクテキストの要素(タグ)を書くと思います。
それから、デザインを確認し、頭の中でどういうCSSが必要かを整理し、クラス名を必要な要素(タグ)に設定します。

<ul class="list">
<li><figure class="pic"><img src="画像パス"></figure><a href="#" class="link">リンクテキスト</a></li>
</ul>

こんな感じ。
クラス設定をするタイミングは、マークアップが完了してから・・・というのが一般的ではないでしょうか。

デザインが複雑になってくると、頭で考えたCSSではうまくいかず、要素(タグ)に設定したクラス名を削除したり、もしくは追加してクラス名を設定したり、、、というフローを繰り返す。
これが一般的なコーディングフローだと思います。

このコーディングフローでは「この要素にはクラスが必要だろう」「この要素には必要ないだろう」と頭で考える時間(迷いの時間)と、先ほど述べた頭で考えたCSSではうまくいかず、クラス名を削除したり、追加したりと繰り返す作業が生じてしまいます。
これは大変非効率です。

吉本式BEM設計(BEM設計ベース)では、次のルールを決めています。

クラス設定ルール 1
必ずクラスを設定する要素(タグ)と、必要なとき以外にはクラスを設定しない要素(タグ)を決めておく

このルールを決めておくことで、作業効率が大幅に改善されます。
それではこのルールについて、解説していきます。

クラス設定ルール

必ずクラスを設定する要素(タグ)と、必要なとき以外にはクラスを設定しない要素(タグ)の分け方は簡単です。

ブロックレベルの要素(タグ)には、必ずクラスを設定します。
インラインレベルの要素(タグ)には、必要なとき以外にはクラスを設定しません。

主なブロックレベルの要素(タグ)
header, footer, main, section, article, aside, nav, div, h1~h6, p, figure, table, tr, th, td, dl, dt, dd, ul, ol, li, iframe, form...
主なインラインレベルの要素(タグ)
a, span, img, input, em, strong...

CSSのプロパティが必要・不要関係なく、ブロックレベルの要素(タグ)には、必ずクラスを設定してください。
このルールを決めることで、先ほどのコーディングフローがどうなるか。
フローを再現してみます。

例:リスト要素の中に画像とリンクテキストが配置されているレイアウトのコーディングフロー。

<div class="block">
<ul class="block-list">
<li class="block-item"></li>
</ul>
</div>

クラス名を含め、一気にここまで書けます。
ul要素、li要素のクラス名(Element名)は、前回の記事で解説した通り、固定ですので迷うことはありません。
(Block名をどうするか・・・で少し迷うかもしれませんが、、、)

<div class="block">
<ul class="block-list">
<li class="block-item"><figure class="block-pic"><img src="画像パス"></figure><a href="#">リンクテキスト</a></li>
</ul>
</div>

続いて、ここまで書きます。
これでマークアップの記述が完了ですが、同時にクラス設定も完了しています。
img要素・a要素にもクラスを設定しなければいけなくなる、という状況(デザイン)は、あまり出てきません。
その理由として、もう一つのルールを決めています。
そのルールについて、解説します。

SCSS(CSS)のタグ指定

この記事の冒頭で、BEM設計の場合、CSSで要素(タグ)を指定する場合、必ずクラス指定にしなければいけません。
と解説しました。
SCSSの記述については今後の記事で詳しく解説しようと思いますが、上のマークアップのSCSSを記述すると次のようになります。

.block{
	&-list{
		//ul要素のスタイル
	}
	&-item{
		//li要素のスタイル
	}
	&-pic{
		//figure要素のスタイル
	}
}

img要素、a要素にどうしてもスタイルを設定しなくてはいけなくなった場合、BEM設計で対応すると、img要素、a要素にクラスを設定して、そのクラス指定でSCSSに記述しなくてはいけません。

<div class="block">
<ul class="block-list">
<li class="block-item">
<figure class="block-pic"><img src="画像パス" class="block-img"></figure>
<a href="#" class="block-link">リンクテキスト</a></li>
</ul>
</div>
.block{
	&-list{
		//ul要素のスタイル
	}
	&-item{
		//li要素のスタイル
	}
	&-pic{
		//figure要素のスタイル
	}
	&-img{
		//img要素のスタイル
	}
	&-link{
		//a要素のスタイル
	}
}

こんな感じになります。
まず、なぜBEM設計ではスタイルを設定する場合、必ずクラス指定をしなければいけないのか。

.block{
	ul{
		//ul要素のスタイル
	}
	li{
		//li要素のスタイル
	}
	figure{
		//figure要素のスタイル
	}
	img{
		//img要素のスタイル
	}
	a{
		//a要素のスタイル
	}
}

上のように、タグ指定するのはBEM設計ではNGです。
理由は、タグに依存してしまうとタグが変更になった場合、SCSS側も変更しなくてはいけなくなる、という問題を回避するための設計にしているためです。
設計的にはとても素晴らしい考え方ですが、これを忠実に守り、全ての要素にクラスを設定してしまうと、マークアップ側がクラスだらけになってしまい、結果、美しくないソースコードになってしまいます。
というのが、私の実感でした。

そして、私の実務経験上、次の3つの結論を出しました。

1. インラインレベルのタグに関しては、タグ依存しても問題ない。
2. タグの変更が必要になるケースはあまり出てこない。
3. タグの変更が必要になっても、そこまで作業負荷はない。

ただし、タグに変更が入り、BEM設計にしておいてよかったと思うケースは出てきます。
変更が必要になる可能性があるのは、Blockだったり、ブロックレベルのElementだったりするケースがほとんどで、インラインレベルの要素(img要素、a要素、span要素など)に対し、タグの変更が必要になるケースはほぼありません。

結果、吉本式BEM設計(BEM設計ベース)では、次のルールを決めました。

クラス設定ルール 2
基本的にはインラインレベルのタグは、タグ指定でSCSS(CSS)を記述する。

このルールを設定することで、先ほどのマークアップは、次のようになります。

<div class="block">
<ul class="block-list">
<li class="block-item"><figure class="block-pic"><img src="画像パス"></figure><a href="#">リンクテキスト</a></li>
</ul>
</div>

ブロックレベルの要素にはクラス名が設定され、インラインレベルの要素にはクラス設定はしない。
ルールは、シンプルです。

SCSSは、次のようになります。

.block{
	&-list{
		//ul要素のスタイル
	}
	&-item{
		//li要素のスタイル
		a{
			//a要素のスタイル
		}
	}
	&-pic{
		//figure要素のスタイル
		img{
			//img要素のスタイル
		}
	}

}

インラインレベルの要素に関しては、直接タグ指定になっています。
この方法で基本的にはデザインを忠実に再現することができますが、中にはimg要素、a要素にクラスを設定しなければ難しいケースもあります。
インラインレベルの要素に、クラス設定はしてはいけないというルールは定めていませんので、必要なケースが出てきた場合は、クラス設定しましょう。