[CSS] BEMによるCSS設計


マークアップをはじめて一番最初に悩んでしまったこと
それは クラスの命名 でした。

CSS設計手法はいくつかありますが、今回は BEM を採用したので記事にまとめてみます。

BEMとは

Block(塊)、Element(要素)、Modifier(修飾)の略

xxx.html
このように表します
<div class = "Block__Element--Modifier">

Blockってなに?
Elementってなに?
Modifierってなに?
__ (アンダーバー)の意味は?
--(ハイフン)の意味は?

それぞれの意味を理解するために順を追って私なりに解説します。

Block / Element / Modifier を理解する思考手順

1. WEBページはBlock(塊)の集合体であることを理解する

WEBページはヘッダーやメインコンテンツ、サイドバー、フッターなどのBlockが
集まって構成されています。

header , aside , section , nav , footer , div (main, contents) など

これらは全てBlockとして扱います。

2. Block(塊)の中には機能や役割を持ったElement(要素)があることを理解する

ヘッダー、メイン、フッターなど大きな塊が Block
しかしBlockだけではWEBページは成り立たない。

Qiitaのヘッダーを見てみよう

サイトロゴや検索バーなど、Block(ヘッダー)を構成するElement(要素)があります。

input , button , img , svg , h , p , ul , li , a など

これらはElementとして扱われます

3. Block(塊)やElement(要素)を強調したり、状態を表すためにModifier(修飾)があることを理解する

「(複数タブがあって)現在のタブの位置を表す」
「一番上に表示されている記事(article)を区別する」

「このタイトルは大きく」
「このテキスト部分は赤く」
「ここだけ太字に」

これらは Modifiler として扱います

BEMの書き方

BlockとBlock / BlockとElementを繋ぐ際はアンダーバー2つで繋ぐ (使用頻度:高)

.block__block
.block__element
.block__block__element

Modifierはハイフン2つで繋ぎ、修飾を表す(使用頻度:少)

%h2.content__title--big      # 大きいタイトル
%p.content__text--alert        # 赤いテキスト(警告)
%span.content__text--emphasis  # 強調

文字の強調部分や、ここだけ大きく!、ここだけ赤く!ってときに使います。
なのであまり登場しないかも。

単語の区切りはハイフンを一つ表現してOK(使用頻度:少〜中)

.top-banner  # 上に配置するバナー。
.corporate-logo  # 企業ロゴ

多用は避けよう。原則、一つの単語にするように努力しよう。
どうしても「このブロックは2単語じゃないと表せない…」というときのみ使用します。


SCSSの記述はこんな感じになる

xxx.html.haml
.main
  .contents
    .contents__content
      %h2.contents__content__title
        タイトル
      %p.contents__content__text
        ネストが深いほどclass名が長くなるのは仕方ない
xxx.scss
.main {
  .contents {
    &__content{    
      &__title {
      }
      &__text {
      }
    }
  }
}

入れ子構造がHTMLと同じになるのでわかりやすい


例 :私がヘッダー作ったときの思考手順

実際のコードを眺めてどんな感じなのかを見てみよう

↓ヘッダー。これを目指す↓

↓ブロックを細分化するときには、まず大枠をイメージすると取り掛かりやすい

1. "ヘッダー"コンポーネントで一番でかい枠は
→"header"
2. 両サイドにpaddingを設けたいから"inner"を作る
→"header__inner"
3. "top"[ロゴと検索フォーム]、"nav"[ナビゲーションバー]がある
→"header_innertop" / "headerinner_nav"(.nav)
4. "top"には[ロゴ]、[検索フォーム]がある
→"header_innertoplogo" / "headerinnertop_search"
5. [検索フォーム]にはフォームタグがある
→"header_innertopsearch_form"
6. [フォーム]にはinputとbuttonがある
→"header_innertopsearchform_input"
→"header_innertopsearchform_button"
7. [ナビゲーションバー]部分も同じようにブロックを細分化

↓ 以下、実際のコード↓  ※画像はHTMLですが、実際のコーディングはHamlです

↓ SCSS (入れ子の関係がわかるので、構造が把握しやすい)

余談

blockをひたすら __ で連結させていくのは本当のBEMではないそうです。
ただし、今回課題として「SCSSを見ただけでHTMLの構造をわかるようにする」という指定があるので、この条件をクリアするためにガンガン要素を__で繋げました。