はじめに
タイトルについて記事にしました。
この記事で得る内容は以下の通りです。
・ CSSの命名規則BEMの概要・命名規則・HTMLとSCSSでの書き方
概要
HTMLにクラス名をつける時の代表的な命名規則には以下の3つがあります。
この記事ではBEMについて深堀りをしたいと思います。
・ BEM(Block-Element-Modifier):ベム
・ OOCSS(Object Oriented CSS):オーオーシーエスエス
・ SMACSS(Scalable and Modular Architecture for CSS):スマックス
CSSの命名規則について
命名規則が統一されていれば、HTMLを書いている時にクラス名を何にするか悩まなくなり、素早くHTMLのマークアップを行えるようになります。
BEM
BEM(ベム)は、Block、Element、Modifierの頭文字をとったもので、厳格なクラスの命名規則が
特徴のCSS設計です。ページを構成する要素をこの3つのどれかに当てクラス名をつけます。
BEMを使うメリット
クラスの命名が簡単になる
CSSの設計においては、命名規則が最も難しいとされています。
BEMでは、Block、Element、Modifierの3つに分類して考え、これらのみでクラスを命名することで
クラス名で悩むことがなくなります。
要素の再利用がしやすくなる
共通の要素を別の場所で再利用しようとしても、要素がHTMLに依存していると
同じCSSを書かなければなりません。しかし、BEMを使うことでクラスの命名がHTML構造に依存せずに
要素を再利用しやすくなります。
BEMのデメリット
クラス名が冗長で、全ての要素にクラス名を付与するのでHTMLが読みにくくなります。
また、BootstrapはOOCSSを採用しており、BEMとの相性がいいとは言えません。
BEMを構成する要素
個性的(?)なキャッチフレーズが印象の株式会社hogeの適当に作ったHP構成です。
これを元にBEMを構成する3つの要素を説明します。
※赤枠がBlock、緑枠がElement、紫枠がModifierを示しています。
Block
要素の大元となるブロック要素です。パーツとして独立完結していて場所を問わず機能します。
Block内にBlockが入れ子になっていてもOKです。
Element
Elementは必ずBlockの中に存在します。
同じElementが複数存在しても良いですし、Element内にElementが入れ子になっていてもOKです。
Modifier
パーツ構成は同じですが、見た目や動きが違うパーツを作成する際にModifierを使用します。
BlockもしくはElementに付与し、1つのパーツに複数Modifierを付与してもOKです。
BEMの命名規則
Block、Element、Modifierの命名規則について説明します。
Block
例えば上記のようなロゴは、ヘッダーのロゴなのでHeaderLogoと命名します。
クラス名の単語が2つ以上の場合は、単語の間にキャメルケースまたはスネークケースでつなぐか
『-』ハイフンを入れます。
<div class="HeaderLogo"></div>
もしく下記のように書きます。
<div class="Header-logo"></div>
BEMで全てのデザインを管理できればよいのですが、BEMから外れてデザインをすることに備え
BEMとそれ以外を区別するためBlock名をパスカル記法(最初を大文字)にすると分かりやすくなります。
Element
ElementはBlock名の後に『_』アンダースコア2つでつなぎます。
このアンダースコア2つをセパレーターや区切り文字といい、後述のModifierの区切りや
名前の区切りと判別できるようにします。
<div class="HeaderLogo">
<div class="HeaderLogo__picture">
<img class="Logo__img" src="logo.jpg" alt="ロゴ">
</div>
<div class="HeaderLogo__text">
<div class="Logo__title">株式会社hoge</div>
<div class="Logo__subtitle">フューチャーを、未来する</div>
</div>
</div>
Modifier
ModifierはBlock名やElement名の後に『-』ハイフンを2つでつなぎます。
<div class="About">
<div class="About__title">ABOUT</div>
<p class="TopTitle">・hogefuga</p>
<div class="About__title">ABOUT</div>
<p class="TopTitle--square">■hogefuga</p>
</div>
SCSSの記述
簡単にですが、下のようなhtmlにscssで記述しました。
<div class="HeaderLogo">
<div class="HeaderLogo__picture">
<img class="Logo__img" src="logo.jpg" alt="ロゴ">
</div>
<div class="HeaderLogo__text">
<div class="Logo__title">株式会社hoge</div>
<div class="Logo__subtitle">フューチャーを、未来する</div>
</div>
</div>
.HeaderLogo {
display: flex;
justify-content: center;
align-items: center;
background: #eee;
border-radius: 5px;
height: 100px;
width: 350px;
padding: 10px;
&__picture {
display: block;
margin-right: 30px;
}
&__text {
.Logo__title {
color: green;
}
.Logo__subtitle {
color: red;
}
}
}
SCSSで記述する際のルール
element、modifierは親セレクタから参照し、ネストを使って定義する
* modifierである.HeaderLogo__picture--sampleは適当に今作りました
.HeaderLogo {
// 省略
&__picture {
display: block;
&--sample {
color: red;
}
}
}
element内で更にelementをネストさせて定義してはいけない
下の例ではElement(.HeaderLogo__picture)の中にElement(.HeaderLogo__picture__subpicture)がネストしており、
これはHTMLとSCSSを分離させるという意味でよくありません。
.HeaderLogo {
// 省略
&__picture {
display: block;
&__subpicture {
padding: 10px;
}
&--sample {
color: red;
}
}
}
HTMLとSCSSの構造を分けると、デザイン仕様が変わっても少ない修正で済みます。
elementがBlock以外に親を持ってしまうとHTMLとSCSSを分離できなくなってしまい、コードの修正や拡張しにくいコードとなってしまいます。