【命名規則】BEMを使った書き方についてまとめてみた【CSS】

実務でCSSをガッツリ書くことになったので、復習の意を込めて自分用のチートシートを作成しました。
今回は現場でよく使われているBEMの書き方について調べたことのまとめです。

## BEMとは
BEMはBlock Element Modifierの略で、CSSを設計･命名していく手法です。

- Block： 大枠となる独立した要素
- Element： Block中の要素
- Modifier： BlockやElementのスタイル

保守性の高さから1番多く使われている命名規則だと思います。

## BEMを使う目的

BEMは名前の衝突を避けるために考案されたCSS設計です。

保守性の高さを解決するための手法は他にもあり、HTMLはシンプルがな書き方が求められますが、まだまだ決定打に欠けています。
BEMは見た目が汚いですが、シンプルを求めて面倒な目にあうよりは、少々汚くても扱いやすいBEMが多くの現場で採用されています。

### 命名規則の考え方

class名の命名規則にはいくつか種類がありますが、どの命名規則を採用するにしても、前提として考えることは以下です。

- 明確に決まっている
- わかりやすい
- 保守性が高い(管理しやすい)

BEM以外のOOCSSやSMACSS等の命名規則を使うとしても、上記はそもそも命名規則を考える目的になります。
手段を好き嫌いで選ばずに、その時々で最適だと思われる命名規則を採用しましょう。

## BEMの命名の仕方

class名であれば以下のように命名します。

```
class="block__element–-modifier"
```

最初にBEMは以下の３つの略だと説明しました。

- Block： 大枠となる独立した要素
- Element： Block中の要素
- Modifier： BlockやElementのスタイル

これらの要素を以下のルールに基づいて命名します。

- blockとelementはアンダースコア2つで区切る
- Elementとmodifierはハイフン2つで区切る
- ハイフンとアンダースコアは2つ
- block, element, modifierが複数単語になる場合、単語と単語の間はハイフン1つで区切る
- ハイフン1つの場合はElementとModifierの区切りではなく、ただの単語の区切りとして使用

### サンプルコード

以下ははBEM記法でclassを付けたサンプルです。

```
<section class="about">
  <div class="about__item">
    <h2 class="about__item-ttl">ここにタイトルが入る</h2>
    <p class="about__item-txt">テキストが入る。テキストが入る。</p>
    <a href="#" class="about__item-link about__item-link--red">MORE</a>
  </div>
</section>
```

## クラス命名でよく使われる単語

以下はクラス作成時に頻出するクラス名です。
ここにないような単語は[codic](https://codic.jp/)などで調べて組み合わせを考えてみましょう。

### Block

| 単語 | 意味 |
| --- | ---|
| section |区分・区画|
| content |文書の内容|
| article |記事|
| post |投稿|
| top |頂上・上部|
| home |トップページ|
| sidebar |補足記事|
| wrapper |内包する|
| wrap |wrapperの略語|
| container |wrapperの類語容器・入れ物wrapperはレイアウト的に、containerは意味的に使うことが多い|
| group |集まり|
| area |特定の場所・範囲|
| emphasis |強調・重視|
| catch |興味を惹く・関心をつかむ|
| note |注釈|
| description |概要|
| desc |descriptionの略語|
| introduction |前置き・導入|
| intro |introductionの略語|
| announce |お知らせ|
| information |情報|
| info |informationの略語|
| action |Call To Action重要度の高い|
| more |もっと多くの|
| feature |主要なもの|
| detail |詳細・細部|
| summary |概要・要約|

### Element

BEMのElementで使われるような名詞や形容詞など。

| 単語 | 意味 |
| --- | ---|
| inner | 内側の |
| outer | 外側の |
| body | 主要部分 |
| head | 上部 |
| foot | 下部 |
| heading | 見出し・表題 |
| title | 表題・題名 |
| lead | 見出しの補足・記事の要約 |
| list | 一覧・表 |
| menu | 一覧・表 |
| item | （表やデータなどの）項目 |
| unit | 1つの単位・1セット |
| column | 縦列 |
| col | columnの略語 |
| text | 本文 |
| caption | 画像・図表の補足文 |
| thumbnail | 縮小した画像 |
| thumb | thumbnailの略語 |
| avatar | 人の顔を示す画像 |
| feature | 特徴を補足する画像 |
| tel | 電話番号 |
| address | 住所 |
| date | 日付 |
| time | 日時 |
| category | 分類・部類 |
| cat | categoryの略語 |
| tag | 識別子 |
| next | 次の |
| previous | 前の |
| prev | previousの略語 |
| mask | 覆い隠す |
| overlay | かぶせる・上書きする |
| delimiter | アイテムの範囲や境界線を示すインターフェイス |
| separator | delimiterの類語で混ぜないように分離する目的で使います |
| divider | delimiterの類語でグルーピングするように分割する目的で使います |

### Modifier

| 単語 | 意味 |
| --- | ---|
| success | 成功|
| alert | 注意・警戒|
| attention | 配慮・気配り|
| error | 間違い・失敗|
| caution | 用心・警告|
| warning | 警告・予告|
| danger | 危険・驚異|
| tiny | とても小さい|
| xs | tinyの類語でExtra small（smallよりさらに小さい）こと|
| small | 小さい|
| medium | 中間|
| large | 大きい|
| huge | とても大きい|
| xl | hugeの類語でExtra large（特大・超大型）のこと|
| reverse | 反転する|
| push | 前方に押す|
| pull | 自分の方に引く|
| offset | 相殺する・埋めあわせる|
| left |  左側の|
| center | 真ん中|
| right | 右側の|
| top | 上部|
| middle | 真ん中|
| bottom | 下部|
| round | 角丸|
| circle | 円形|

### 分類

| 単語 | 意味 |
|---- |------|
| about |〜について|
| work |仕事・任務|
| product |製品|
| service |サービス|
news |お知らせ・近況|
| event |行事・出来事|
| history |歴史・沿革|
| archive |保存・保管・記録|
| concept |構想・概念・考え|
| recommend |おすすめ・推奨|
| table of contents | 目次|
| toc |Table of contentsの略語|
| index |索引・指標|
| contact |問い合わせ・連絡|
| inquiry |問い合わせ・質問・調査|
| access |交通手段|
| shop |店舗|
| related |関連のある|
| privacy |個人情報の利用・保護の方針|
| faq | Frequently asked questionsquestions（よくある質問）の略|
| qanda |Question and answer・Q&A・質問と回答|
| input |フォームの入力画面
| confirm |フォームの確認画面|
| finish |フォームの完了画面|
| search |検索する|
| result | 検索結果画面|
| cart |購入するアイテムを一時的に保存する画面|
| checkout |保存していたアイテムを購入する画面|

### 形容詞

名詞の性質や状態を修飾する品詞。「〜の」「〜な」。

| 単語 | 意味 |
| --- | ---|
| main | 主要な |
| primary | 主要な |
| secondary | 補助的な・第二の |
| tertiary | 第三の |
| quaternary | 第四の |
| common | 共通の |
| global | 全体的な |
| local | 局所的な |
| general | 一般的な |
| brand | ブランドの |
| site | サイトの |

### ステータス

状態を示す動詞や形容詞など。

| 単語 | 意味 |
| --- | ---|
| show | 見せる |
| hide | 隠す |
| open | 開く |
| close | 閉じる |
| current | 現在の |
| active | 活動中・有効な |
| disabled | 無効になっている |

### 文字を扱う要素

| 単語 | 意味 |
| --- | ---|
| link | アンカーテキスト |
| label | 分類する・項目名 |
| tag | 符号・識別子 |
| badge | 残数を示す数値 |
| copyright | 著作権表示 |
| tooltip | マウスオーバー時に補足情報を表示するインターフェイス |
| button | オン・オフの選択に使うインターフェイス |
| btn | buttonの略語 |

### イメージ

| 単語 | 意味 |
| --- | ---|
| image | 画像|
| img | imageの略語|
| icon | 対象の内容や機能などを小さな絵柄で表したもの|
| loading | 読み込み中であることを示すインターフェイス|
| logo | 社名や製品名などを図案化・装飾化した文字・文字列|
| map | 地図|
| chart | 理解しやすいような方法で情報を示すリストやグラフのこと|
| graph | chartの類語で視覚表現のための手段のこと|
| hero | キービジュアルになる大型の画像|
| banner | （主に宣伝用の）画像をともなうリンク|
| carousel | 画像などのコンテンツを上下左右にスライドさせて切り替えるインターフェイス|
| slider | carouselの類語|
| ticker | carouselの類語で自動でアイテムを左右に流しながら表示する。ユーザーは基本的にコントロールできない|
| lightbox | carouselの類語で、モーダルのjQueryプラグインのこと。主な用途はサムネイル画像をクリックしてモーダルを開き画像を大きく見せること|

### ナビゲーション

| 単語 | 意味 |
| --- | ---|
| navigation |  情報へ誘導するリンク |
| nav |  navigationの略語。 |
| global | navigation - ほとんどの画面で表示されている主要なナビゲーション |
| local | navigation - あるカテゴリ内専用のナビゲーション。グローバルナビゲーションの中や下に配置する場合や、サイドバーに配置する場合がある |
| mega | menu - 深い階層のカテゴリやページへのナビゲーション。ドロップダウン（クリックやマウスオーバー）で階層を表示していく。カテゴリやページ数の多いサイトのグローバルナビゲーションに使われることが多い |
| breadcrumb |  パンくずリスト。トップページから現在ページまでの階層構造を示したリンク |
| topicpath |  breadcrumbの類語 |
| springboard |  同じサイズのリンクを2×2や3×3のように配置した同じ重要度を持つ並列なナビゲーション |
| list | menu - 縦に並んだリスト型のリンクで、階層構造をもったナビゲーション |
| dashboard |  グラフやステータスなどを一つの画面にまとめたインターフェイス |
| pagination |  昇順にしたページ番号付きのナビゲーション |
| linear | navigation - その画面の前後に移動するためのナビゲーション。paginationとの違いはページ指定ができないこと |
| back | to-top - ページトップに戻るためのページ内リンク |
| tab |  書類などのインデックスタブを模した、画面内のコンテンツ表示を切り替えるインターフェイス |
| tabbar |  おもに画面下部に固定されたタブで、画面全体を切り替えるインターフェイス |
| segmented | control - 機能的にはtabと同じで、見た目がタブではなくボタンである点が違う |
| off | canvas - 表示領域外から画面の大半を覆い隠したり（オーバーレイ）、ずらすようにスライドしながら表示するナビゲーション |
| side | drawer - off-canvasの類語。drawerは「引き出し」の意味 |
| toggle | menu - 同一の操作で二つの状態を交互に切り換えるインターフェイスで、操作対象になるボタンを基準にナビゲーションを表示することが多い |
| sitemap |  サイト内のすべてのページへのリンクをリスト化したもの |
| sns |  ソーシャルネットワーキングサービス |

### フォーム

| 単語 | 意味 |
| --- | ---|
| form | 送信フォーム。 |
| login | ユーザー認証をするためのフォーム |
| signin | loginの類語 |
| logout | signout - ユーザー認証を解除すること |
| registration | ユーザー登録をするためのフォーム |
| signup | registrationの類語 |
| step |navigation - 複数画面にわたるフォームの順序や、現在地を示したナビゲーション |
| search |box - キーワード検索するためのフォームエリア |
| text |field - input[type="text"]のような利用者が編集する改行なしのテキストフィールド |
| textarea | textareaのような利用者が編集する複数行のテキストフィールド |
| checkbox | input[type="checkbox"]のような1つ以上の項目を選択するインターフェイス |
| radio | input[type="radio"]のような1つの項目を選択するインターフェイス |
| select | selectのような1つの項目を選択するインターフェイス。ラジオボタンと違い、（dropdownのように）項目が最初は隠れているのが特徴 |
| submit | 送信ボタン |
| reset | リセット（取り消し）ボタン |
| modify | 修正ボタン |

### その他

| 単語 | 意味 |
| --- | ---|
| cards | トランプのような積み重なったカードのメタファーをもつインターフェイス。|
| dropdown | 複数の項目を表示して、1つの項目を選択するインターフェイス。|
| pulldown | dropdownの類語。|
| accordion | 折りたたまれたコンテンツを選択することで表示させるインターフェイス。|
| scroll |tab - 表示領域よりも横に長いナビゲーションで、左右にスクロールすることで非表示部分を見ることができるインターフェイス。|
| dialog | （主に）注意や警告を知らせるために使用されるメッセージで、ユーザーに操作を要求するのが特徴。|
| toast | dialogの類語で、dialogとの違いは時間が経つと自動的に消えること。|
| popup |window - dialogの類語で、リンク先を別の小さなウィンドウで表示するインターフェイス。|
| toolbar | ユーザーが利用できるツールやアクションをまとめたインターフェイス。|
| comment | 記事に対する反応。|
| table | テーブル・図表。|
| timeline | チャットや年表のように時系列に並べたリスト。|

## まとめ

今回はBEMについて書きましたが、自分は割と独学で適当にやっちゃってたので、自分用のチートシートとして作成しました。

命名規則などについては他のブログやQiitaで良質な記事が大量にあるので、さらにわかりやすい記事を求める人はそちらに飛んで見ることをおすすめします！

お疲れさまでした！

## 参考させていただいた記事

- [Google HTML / CSSスタイルガイド](https://google.github.io/styleguide/htmlcssguide.html)
- [一番詳しいCSS設計規則BEMのマニュアル
](https://qiita.com/Takuan_Oishii/items/0f0d2c5dc33a9b2d9cb1)
- [これでもうCSSのクラス名は迷わない！BEMの命名規則をまとめたチートシート -BEM Naming Cheat Sheet](https://coliss.com/articles/build-websites/operation/css/bem-naming-cheat-sheet.html)
- [codic](https://codic.jp/)