今回はCSS設計の1つ「BEM」について解説していきます。
あ、そういうのは中級者とかになってから覚える予定なので…。
むしろ、初心者こそBEMを覚えるべきです。
BEMを覚えればコーディングの効率が上がるのはもちろん、受注できる案件の幅も広がります。
また「classの命名に悩む」「修正するときにclassを探すのに時間がかかる」といったストレスも無くなるので、今よりコーディングが楽しくなるでしょう。
早めに覚えておくと強力な武器になりますので、ぜひ当記事を活用してBEMを学んでみてください。
BEM(ベム)とは?
「BEM」はHTMLやCSSでコーディング効率を高めるために考えられたCSSの設計方法です。
CSS設計には他にもSMACSS(スマックス)やOOCSS(オーオーシーエスエス)といった物もありますが、とりあえず人気の高いBEMを覚えておけば困りません。
なんか難しそうだな…
そんなことは無いので安心してください。
「class(クラス)名を決めるルールを知っておいたほうが、命名する時に迷わなくて楽っしょ!」くらいの考えでOKです。
BEMを使えるようになると、下記のような悩みは全て解決します。
- class名を考えるときに手が止まる
- コーディングのスピードを上げたい
- デザイン修正に対応しやすいCSSが書きたい
またクラウドソーシングでコーディング案件を探すと「BEMでコーディングが出来る方を優先します」という募集文もあるくらいなので、この機会に覚えておいて損は無いはずです。
BEMでclass名を決めるルール
それでは早速BEMでclass名を決めるルールについて説明していきます。
BEMではclass名をBlock(固まり)、Element(要素)、Modifier(修飾子)という3つの概念に沿って命名します。
まだよくわからないと思いますが、ここでは以下のHTMLを見て、なんとな~くイメージだけ持っておいて下さい。(※後ほど例とあわせて詳しく解説します)
<div class="block">
<p class="block__element">BEMを学ぼう!</p>
<p class="block__element--modifier">簡単に覚えられます</p>
</div>
Block(固まり)
BlockはWebサイト上に配置するパーツの名称として設定します。
- Blockのルール
-
- ブロック名はユニーク(1サイト内に同名のブロックは1つのみ)
- ブロックの中に他のブロックを作成しても良い
Element(要素)
ElementはBlockを構成する細かい部品の名称として設定します。
- Elementのルール
-
- Elementの前は「__(アンダーバー2つ)」で区切る
- 別Block同士ならElement名は重複しても良い
- 必ずBlockの中に作成する
Modifier(修飾子)
Modifierは「BlockやElementと基本形状は同じだが、色やサイズなどの一部スタイルが異なるもの」に設定します。
- Modifireのルール
-
- Mofifireの前は「–(ハイフン2つ)」で区切る
- Block、Elementのどちらに作成しても良い
- 別Block、別Element同士ならModifire名は重複しても良い
BEMでclassの命名を行うメリット
次にBEMでclassの命名を行うメリットについて解説します。
- クラス名の命名に迷わない
- 他のスタイルと干渉しない ※実例あり
- 一度作成したスタイルを流用できる ※実例あり
- 複数人で作業を行う際に、共同作業者にも命名ルールが理解しやすい
① クラス名の命名に迷わない
BEMの命名規則に沿ってコーディングをすることで、いちいちclass名を考えるために手を止めることが無くなります。
以前まで、あるていど規模が大きい(下層ページが多い)サイトをコーディングする際にclassの命名規則を決めずに進めてしまい、後半になって「このclass名はもう使っているから…」と命名に迷ってしまうことがありました。
他人が制作したサイトの改修を行う際にも、すでに使用されているclass名と重複して想定外のレイアウト崩れを引き起こしたり…。
その点、BEMならルールに沿ってclass名を決めるだけなので、重複することはまずありません。
② 他のスタイルと干渉しない ※実例あり
BEMの命名規則なら<h1>や<p>といったHTMLの要素に直接スタイルを指定することが無いため、スタイルが干渉することがありません。
少し伝わりづらいかもしれないので、実例を交えてご説明します。
例えば以下のコードのように<p>に対して直接スタイルを指定すると、同じブロック内に再度<p>を配置する際に干渉してしまいます。
<div class="box">
<p>Twitterはじめました</p>
<a href="https://twitter.com/dogiblo" target="_blank">アカウントを見にいく</a>
<p>Web系について呟いています</p>
</div>
</div>
.box p {
font-size: 16px;
font-weight: bold;
}
「Twitterはじめました」のテキストを太字にしたいのですが、上のCSSだと「Web系について呟いています」のテキストにもfont-weight: bold;
が適用されて太字になってしまいます。
これをBEMのコードに書き換えてみましょう。
BEMでのコーディング
<div class="box">
<p class="box__text--bold">Twitterはじめました</p>
<a href="https://twitter.com/dogiblo" target="_blank">アカウントを見にいく</a>
<p class=box__text--normal">Web系について呟いています</p>
</div>
</div>
.box_text--bold {
font-size: 16px;
font-weight: bold;
}
.box__text--normal {
font-size: 16px;
}
.box__bold
と.box__normal
に個別でスタイルを指定するので、干渉がおこらないことがわかります。
理屈はわかるけど、全部こうやって記述するの面倒くさいな
上のシンプルな構造だけで見ると、そのように思うかもしれません。
でも実際のWebサイト制作では、プロジェクトの規模が大きくなるにつれてクラスが乱立されてくるので「絶対にスタイルが干渉しない」というのは、それだけで大きなメリットになります。
③ 一度作成したスタイルを流用できる ※実例あり
BEMでは、一度作成したスタイルを他のパーツでも流用できるようにクラスを命名していきます。
こちらも具体例を交えてご説明します。
<section class="profile">
<h2>プロフィール</h2>
</section>
<section class="product">
<h2>商品</h2>
</section>
<section class="contact">
<h2>お問い合わせ</h2>
</section>
.profile h2 {
font-size: 20px;
color: #000;
borer: 1px solid #00F;
}
.product h2 {
font-size: 20px;
color: #F00;
}
.contact h2 {
font-size: 20px;
color: #000;
borer: 1px solid #00F;
}
「プロフィール」と「お問い合わせ」の<h2>は同じスタイル、「商品」の<h2>には異なるスタイルを当てたいときのコーディング例です。
上例のCSSは.profile h2
と.contact h2
でまったく同じ記述を繰り返しており、.product h2
でもfont-size: 20px;の記述が他の<h2>と重複していますね。
これだと仮に<h2>タグの文字サイズに変更が出た場合に1つ1つ数値を修正しなければなりませんし、なにより同じコードを何回も入力するのは非効率です。
これをBEMのコードに書き直してみましょう。
BEMでのコーディング
<section class="profile">
<h2 class="title title--border">プロフィール</h2>
</section>
<section class="product">
<h2 class="title title--caution">商品</h2>
</section>
<section class="contact">
<h2 class="title title--border">お問い合わせ</h2>
</section>
.title {
font-size: 20px;
color: #000;
}
.title--border {
borer: 1px solid #00F;
}
.title--caution {
color: #F00;
}
なんか、<h2>にクラスが2つ付いてない?
すべての<h2>にtitleクラスを付与し、それとは別に「プロフィール」と「お問い合わせ」の<h2>にtitle–borderクラス、「商品」の<h2> にtitle–cautionクラスを付与しています。
これはマルチクラス設計と言って、CSSで記述の重複を防ぐのに重宝します。
- .title(ベースとなるスタイル)
全ての<h2>で共通するfont-size: 20px;
と、ベースの文字色となるcolor: #000;
を指定 - .title–border(ベースにバリエーションを加えるスタイル)
「プロフィール」と「お問い合わせ」の<h2>で共通するborder: 1px solid #00F;
を指定 - .title–cautionクラス(ベースにバリエーションを加えるスタイル)
「商品」の<h2>に当てるcolor: #F00;
を指定
見比べていただければわかると思いますが、記述の重複が無くなりCSSがとてもスッキリしましたね。
修正前のコーディング
.profile h2 {
font-size: 20px;
color: #000;
borer: 1px solid #00F;
}
.product h2 {
font-size: 20px;
color: #F00;
}
.contact h2 {
font-size: 20px;
color: #000;
borer: 1px solid #00F;
}
BEMでのコーディング
.title {
font-size: 20px;
color: #000;
}
.title--border {
borer: 1px solid #00F;
}
.title--caution {
color: #F00;
}
もちろん他のパーツの中でもこれらのクラスを流用できるし、新たにベースは同じで装飾が異なる<h2>が必要になった際にもバリエーションクラスを追加して拡張できる点で優秀です。
BEMの構造はマルチクラス設計と相性が良いので、ぜひ使いこなせるようになって欲しいです。
ちなみにBEMやマルチクラス設計のデメリットはHTMLに記述するクラスが冗長になること。
この辺はコーダーの好みや、プロジェクトの大きさによって優先するポイントが変わってくると思いますので、使用するかは適宜検討して頂ければと思います。
④ 共同作業者にも命名ルールが理解しやすい
1つのサイトを複数人で分担コーディングする案件や、既存サイトを他の作業者が改修する場合にもBEMが活躍します。
BEMで命名されたclassは「Block、Element、Modifier」の3つの概念に沿って法則的に記述されているので、誰でもひと目見ただけで「なるほど、このclassはこのブロック用ね」と理解しやすくなるからです。
作業者全員がBEMの命名規則でコーディングを進めると以下のようなトラブルを未然に防ぐことができます。
- 自分が記述したcssが他の作業者の作成したページを崩してしまった
- HTMLの要素(<p>や<h1>など)に直接スタイルが当たっているので、毎回打ち消しを書いている
- 同じレイアウトが何度も出現しているにも関わらず、それぞれが別々のコードで作成している
クラウドソーシング等でコーディング案件を探すと「BEMでコーディングが出来る方を優先します」という募集文をよく見るのは、こういった理由からです。
BEMのデメリット
先ほども少し触れましたが、BEMのデメリットは一つ一つのclass名が長くなってしまうという点です。
比較的規模の大きいサイトではBEMのメリットが大きく働きますが、LPなどのように1ページで完結するサイトの場合は無理にBEMでなくても良いかもしれません。
このあたりは実際に使っているうちに「このサイトはBEMの方が良さそうだ!」とわかってくるようになるでしょう。
さいごに
BEMを紹介する記事って意外と少ないな~と感じていたので(僕が見つけられてないだけかも)、拙いながら概要を説明させていただきました。
CSS設計についてもっと学んでみたいと思った方には以下の書籍がオススメです。
約80ページにわたって実例を交えたBEMの設計方法を解説しているので、とても読み応えがあります。
実用性のあるテクニックもたくさん紹介されているので、「コーディングのレベルを上げたい!」という人はぜひ読んでみて下さい。
それでは、今回はこの辺で失礼します!