コンポーネント設計について初心者が考える　〜CSS設計の教科書〜

## この記事を読んでわかること
- コンポーネント設計の概要
- 設計手法について（BEM、FLOCSS）
- コンポーネント作る際の極意

**注意**
こちらの記事は「CSS設計の教科書」の内容を引用している箇所がありますが、初心者の解釈が間違えている可能性もありますので、詳しくは書籍をご確認ください。
## コンポーネントってそもそも何？
:::note info
**コンポーネント（component）**
部品、パーツという意味。WEB制作でいうテキスト、見出し、ボタンなどを指す
:::

初心者だとデザインとそっくりに作ることを目指しがちですが、WEBサイトは作成して終わりではありません。
継続的に改修を行い、デザインや内容は変わっていきます。その際、自分が見てパッと理解できる、また自分以外の改修に携わる誰かが分かる設計を目指す必要があります。

この**コンポーネント設計**では、作ったその先のことを考えた、分かりやすく修正しやすい設計を目指しています。

### どんなメリットがある？
WEB制作においてコンポーネント設計を行うことのメリットは以下の３つが挙げられます。

<font color=orange>**1.要素を使い回ししやすくなる**</font>
例えば、同じような形で色だけ異なるボタンがあったとします。
その時、①1つ1つクラスを命名して作っていくのと、②枠組みはおなじ指定で作って、色だけそれぞれに指定する方法、どちらがいいでしょうか？

この先同じボタンを増やそうとなったときに、②の方が枠組みのクラスを指定し、色の指定を新しく作ればいいので、指定する数は減りますよね。

制作が複雑に、規模が大きくなっていけば行くほどこの考えは必要になります。

<font color=orange>**2.修正・変更がしやすくなる**</font>
ボタンの例と近いですが、例えばボタンの枠の幅や形を変更したいとなった時、②のように記述していれば、枠組みのCSSを変更するだけで、全てのボタンのスタイルを変更することができます。
これが複数の箇所でコンポーネントを使い回すメリットになります。
そのためには、最初の設計がとても大切になります。

<font color=orange>**3.読みやすいCSSになる**</font>
前述した通り、保守をしていく際に作った本人、または全く知らない人がコードを見ることになります。誰が見ても「あ、こういうことね」と理解しやすくなるためにも、無駄な記述を減らし、何度も同じことを繰り返さないで制作を進めることが大切です。
その考えに適しているのが、コンポーネント設計です。


## どんなやり方で開発をすべき？
[CSS設計の教科書](https://www.amazon.co.jp/Web%E5%88%B6%E4%BD%9C%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AECSS%E8%A8%AD%E8%A8%88%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%A2%E3%83%80%E3%83%B3Web%E9%96%8B%E7%99%BA%E3%81%AB%E6%AC%A0%E3%81%8B%E3%81%9B%E3%81%AA%E3%81%84%E3%80%8C%E4%BF%AE%E6%AD%A3%E3%81%97%E3%82%84%E3%81%99%E3%81%84CSS%E3%80%8D%E3%81%AE%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95-%E8%B0%B7-%E6%8B%93%E6%A8%B9/dp/4844336355)では、どうやって設計をし、コンポーネントを作っていくのかという疑問に対して、以下の3つの意見を述べています。

:::note warn
**最適化を焦らない**
メンテナンス性と再利用性をはじめから意識し、全ての要素が再利用できるかも！と考えていると、結局使わないで考える時間が無駄になることもあります。
:::

じゃあ、焦らず待てばいいのね、と待っていたら、タイミングはいつ分かるの？って思いますよね。それに関して述べているのが次の意見です。

:::note warn
**Rule of three**
パターンが初めて出てきた時は無視、3度目としてパターンが登場して初めてリファクタリングすべきという考え方です。
:::
タイミングを逃して気づいたら修正するのに全て書き直す方が早いという状況に陥ることもあるそうです :sweat_drops: 

そして次の原則を意識することで、コードの品質を保つ、つまり綺麗な状態をキープすることにつながります。

:::note warn
**SOLID原則**
1. Single Responsibility Principle（単一責任の原則）
2. Open/Closed Principle（解放／閉鎖の原則）
3. Liskov Substitution Principle（リスコフの置換原則）
4. Interface Segregation Principle（インターフェース分離の原則）
5. Dependency Inversion Principle（依存関係逆転の原則）
:::

CSSの設計において取り入れやすいのは1と2です。
つまり、
+ **1.　見た目のルールと配置のルールを分離してクラスを当てよう**
+ **2.　ベースとなるルールはできる限り変更しない**
+ **2.　拡張（見た目や大きさなど）ルールは上書き・拡張しやすくあるべき**

とまとめることができます。

SOLID原則に関しては下記の記事がわかりやすかったので、気になる方はこちらをご参照ください。

https://qiita.com/baby-degu/items/d058a62f145235a0f007

## CSS設計の概念-BEM-
それでは、こちらからCSS設計の概念（アイデア）を見ていきましょう。

### BEMとは
このBEMはフロントエンド開発で使われている命名規則のことを言います。
![表作成 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/5a39738f-ab00-4091-bbca-e233fb2e5bd8.png)

実際の例で考えてみましょう。

![スクリーンショット 2025-05-21 11.43.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/87e030d3-a452-437c-8d6b-217527b2813f.png)
この図をBEMの法則に当てはめて分解すると、以下のようになります。
![表作成 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/578a6160-7a6e-4ac6-be3a-0e8f1c2b1e23.png)

<table>
  <thead>
    <tr>
      <th>用語</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> Block </td> <td>要素をまとめる存在。mainやarticle、aside、sectionなどがある。</td>
  </tr>
  <tr>
    <td> Element </td> <td>タイトルや文章、ボタンなど細かな部品のこと。</td>
  </tr>
  <tr>
    <td> Modifier </td> <td>各要素の装飾（色など）の指定に使う。</td>
  </tr>
</table>

### 命名の仕方
命名には法則があり、「Element」か「Modifier」かによって異なります。

```
class="block__element--modifier"

class="block--modifier"
```

BlockはElementを要素にもつ親要素のため、上下関係があります。
したがって下がって見えるアンダースコア2つを使用します。

![表作成 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/3a40fcc5-47d6-4336-8231-e738651d0c29.png)

一方ModifierはBlockやElementに対し装飾する役割で、対等であるため＝のようなハイフン2つを使用します。
![表作成 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/c7c4540e-506f-48a1-a0a3-7985e6dd29ce.png)

このようにBlockを接頭語（先頭につける）とすることによって、どのコンポーネントを構成する要素かわかる命名ができ、かつそれらはBEMのどれとなるのか理解することができます。

クラス名でよく使われる単語などについてまとめた記事があったので、こちらも参考にしてください。

https://qiita.com/takahirocook/items/01fd723b934e3b38cbbc

## CSS設計の概念-FLOCSS-
こちらもBEMと同じくコンポーネント設計のアイデアの1つです。
これはOOCSS（オブジェクト指向CSS）、SMACSS（パターンを抽出するカテゴライズが特徴の手法）、BEMなどの手法の考え方を取り込んでできたアイデアです。

### FLOCSSのFLOとは
FLOCSSには3つのレイヤーに分類されるという考え方をしており、FLOがそれぞれのレイヤーの頭文字となっています。

![表作成 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/8bef1e21-82bf-4ca8-a521-72e5e550900c.png)

分類はこの図のとおりです。Objectに関しては、さらに以下の3つに分類できます。

<table>
    <caption>Objectの中の分類</caption>
  <thead>
    <tr>
      <th>用語</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> Component 　</td> <td>再利用ができる最小限のパーツ。マージンやサイズを定義せず、親要素から指定する。</td>
  </tr>
  <tr>
    <td> Project </td> <td>記事一覧やユーザープロファイル、画像ギャラリーなどコンテンツを構成する具体的な要素。</td>
  </tr>
  <tr>
    <td> Utility </td> <td>ComponentとProjectでは対処できない、特定のスタイル調整のためのクラス。</td>
  </tr>
</table>

### FLOCSSにおける命名の仕方
基本的にはBEMの考え方です。ただし、プレフィックス（接頭辞）をつけることが推奨されています。
<table>
  <thead>
    <tr>
      <th>レイヤー</th> <th>接頭辞</th>
    </tr>
  </thead>
  <tr>
    <td> Layout 　</td> <td>l-*</td>
  </tr>
  <tr>
    <td> Component  </td> <td>c-*</td>
  </tr>
  <tr>
    <td> Project </td> <td>p-*</td>
  </tr>
  <tr>
    <td> Utility </td> <td>u-*</td>
  </tr>
</table>

それぞれのレイヤーに応じて役割を明確にするため、このような命名規則を持っています。

実際の例で見てみましょう。
以下の図のようなカードを作成するとします。この時、カードは「**Project**」のレイヤーに分類されます。
![表作成 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/d0056a77-a351-4ad5-a5a9-89fbe224868b.png)

この場合の命名は```class="p-card"```となります。

### 実際の現場では

https://webdesign-trends.net/entry/15813

こちらのサイトでうまく運用するコツとして2つ紹介されています。

<font color=orange>**JavaScript関連のクラスは「js-*」をつける**</font>
こうすることでCSSとJavascriptを切り離して考えることがしやすくなります。
アクティブかどうかなどの状態を表す場合は「**is**-active」のように接頭辞をつけます。

<font color=orange>**チーム内でのルール作りも大切**</font>
FLOCSSがさまざまな手法のアイデアを取り入れているように、人や会社によっていろんな解釈があります。したがって、管理しやすい方法を選択することが、スムーズな開発につながるのです。

## コンポーネントを作る際のポイント
### 適切にわかりやすい命名をしよう
BEMやFLOCSSを正しく活用しながら、他の開発者もわかるような命名をしないと、コンポーネントの役割を理解できなかったら、せっかく作っても意味がありません。
正しく学んで、あとは実践あるのみ。色々なサイトでどんなクラス名を指定しているのか、見てみると勉強になりそうです。

### 全体を把握することを意識しよう
これは私が練習をしている時にやってよかった方法なのですが、デザインを見た時にグルーピングすることです。どうやったかというと、「ここはヘッダーだな」「ここはリストで囲む感じが良さそうだな」「ここはフレックスで横並びにできるようにdivで囲んでおこう」といった形で紙に書き出していきます。

最初のうちはどれがどれとグループになれるのか、全然わかりませんでしたが、全体がどうなっているのか考えることで、だんだんと「これとこれはまとめられるな＝**汎用性の有無**」を理解できるようになっていきました。

俯瞰してみることはプロジェクトが大きくなればなるほど意識が大切になっていくと思います。

## まとめ
初心者の方はわかってくれると思いますが、始めてすぐは、何がなんだかわからず、とりあえずお手本と似たような見た目で作っていました。
それからだんだんと、「これとこれ、一緒の形（サイズ）だから、まとめた方がいいよな」というような思考に変化していき、「こういうのって、ルールあるんじゃない？」と思い立って、この本に辿り着きました。
正直どの要素が同じグループにできて、再利用できるクラスを指定できるか、なんて全然分かりません。
ただ、こういった概念を知って、それを意識していくことで、自ずと体（というかタイピングする指が）覚えていくのかもしれないな、と真っ暗なトンネルで出口が光っているのがわかっただけよかったかなと思います。![Image_fx (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065192/d0c068ae-b0e1-4e42-8feb-a7a00393fa3c.jpeg)

## 参考
今回読んだ本について記載しています

https://qiita.com/sun_22/items/a8f3288f5c295552c89b

参考にしたサイト

https://regolith.diezon.co.jp/column/ec24_component