# CSSの設計

# はじめに

今この文章を読んでいる人ならば、少なくとも CSS には触れたことがあると思います。
CSS はとても簡単に記述できますが、それゆえに CSS は「壊れやすい」のです。

# CSSの問題点

なぜ CSS は壊れやすくなってしまうのでしょうか。
CSS には以下のような問題点があげられます。

- すべてがグローバルスコープ
- 複雑化する Web 開発

## すべてがグローバルスコープ

ある程度のプログラミングの経験があるほうなら、この一行だけでことの重大さがわかるでしょう。CSS は読み込まれたスタイリングのすべてが適用されます。

互いのスタイリングが干渉しあって、なぜかスタイリングが適用されないのでやむなく `!important` する、スタイルを変更したら想定外の箇所に影響が及んでしまったなどの経験があるのではないでしょうか？

[shadow DOM](https://developer.mozilla.org/ja/docs/Web/Web_Components/Using_shadow_DOM)によるスタイルのスコープ化という手段もありますが、まだすべてのブラウザでサポートをしているわけではありません。

## 複雑化するWeb開発

CSS が日本で使われるようになったのが 2002 年頃ですが、当時と比べて Web 開発の場面は大きく異なっています。

「見出しがあって、続く本文があって、その中にさらに小見出しがあって・・・」という文書的な使われ方が一般的でした。しかしいまやコンテンツをアニメーションしたり、ユーザーの操作に合わせて表示させる内容を切り替えるなど、リッチな Web アプリケーションが当たり前のように求められるようになりました。

数百ページに及ぶ Web サイト、頻繁に変更される状態など、さまざまな要素が複雑に絡み合っており、CSS 提唱当時には想定されていなかったような進化をしているため、CSS の管理が追いつかない状態になってしまっています。

# CSS設計の誕生

そのような状態に対する解決策として、CSS の設計が誕生しました。今までも会社・個人単位で CSS を管理する工夫は行われていましたが、以下のような問題点がありました。

- 規則をきちんと整理できていないと、一人で開発するときですら記述にブレが生じる
- ドキュメント化されていないと、他社と協力して作業する際に記述にブレが生じる
- 考えが甘すぎて、そもそも規則として機能しない
- 新たにプロジェクトに参画した際に学習コストが生じる

既存の優れた CSS 設計を適用することで、このような問題点を解決できます。

CSS 設計の有名所では、以下があげられます。

- OOCSS
- BEM
- SMACSS
- FLOCSS

# CSS設計の共通の考え方

CSS の設計思想には、以下の 4 つの考え方が共通して存在しているといえます。

- 予測しやすい（可読性）
- 再利用しやすい（再利用性）
- 保守しやすい（メンテナンス性）
- 拡張しやすい（拡張性）

## 予測しやすい(可読性)

機能追加・見た目の変更・修正をする際に「どのスタイルが変更されるのか」または「どのスタイルは変更されないのか」が理解できる状態。

## 再利用しやすい（再利用性)

汎用的なスタイルは,定義した CSS の形を変えずに，どのような場合でも複数箇所で使い回すことができる状態。

## 保守としやすい(メンテナンス性）

既存の CSS のリファクタリングをできるだけ行わずに,新しい見た目や機能を追加できる状態。

## 拡張しやすい（拡張性）

機能の追加・修正などの拡張をすることを前提として,他のどの開発者がアサインされたとしても低学習コストでソースコードを理解し，サイトの拡張ができる状態。

それでは、代表的な CSS の設計を簡単に紹介します。

# OOCSS (Object Oriented CSS)

[http://oocss.org/](http://oocss.org/)

OOCSS は Object Oriented CSS（オブジェクト指向 CSS）の略で、名前通りスタイリングにオブジェクトを指向を取り入れた設計です。OOCSS の歴史はかなり古く、明確に規則と呼べるものも多くはありませんが、後続の CSS の設計に大きな影響を与えました。

レゴのように自由に組み合わせる部品をつくり、マルチクラスの設計になります。

OOCSS の目的としているところは以下のとおりです。

1. ストラクチャーとスキンの分離
2. コンテナとコンテンツの分離

##  ストラクチャーとスキンの分離

「ストラクチャー」はインターフェースが持つ不変的な形を定義し,「⁠スキン」はそのまま、その都度変わる固有の見た目を定義します。

例えばボタンという部品の基本形となるスタイルを定義して、色や大きさなどの見た目を定義するスタイルを後から付け加えるようにして再利用がしやすいようになっています。

「ストラクチャー」はオブジェクト指向におけるインターフェースで「スキン」がインターフェースを継承したクラス、と当てはめることができるでしょう。

## コンテナとコンテンツの分離

コンテナは大まかに「エリア」、コンテンツはボタンなどの「モジュール」が当てはまります。

コンテンツはなるべく再利用できるように設計するので、特定のエリアに依存しないようにスタイリングをします。そのため、ID セレクターのような詳細なセレクターは使用しません。

一方でコンテナに対してはレイアウトに対するスタイリングを行い、例えばグリッドレイアウトなどでコンテンツを配置します。

# BEM（Block Element Modifier）

[https://en.bem.info/](https://en.bem.info/)

BEM は、他の設計手法に比べて厳格で、独特な命名規則を用いることで有名です。世界的にも OOCSS に匹敵するほど名前が知られています。

BEM（Block Element Modifier）の名前のとおり、モジュールを Block、Element、Modifier に分けて分解し定義します。

大まかに、分類すると Block はヘッダー、ナビゲーションなどの大きな括り、Element は Block の中のボタンなどの要素、Modifier 部品の見た目や状態の変更に用いられます。

BEM では、クラスセレクターの使用が基本となり、要素型セレクターや ID セレクターの使用は推奨されていません。また詳細度を均一に保つことで Modifier や Mix による上書きをしやすくしています。

また**Block__Element--Modifier**という命名規則に従ってクラス名がつけられます。

例えば、ヘッダーの中に小さなボタンを配置する場合、次のようなクラス名がつけられます。

```html
header__button--small
```

さらに、Modifier 名は省略してはいけないという規則があります。例えば、上記の例で Block と Element を省略した `.small` というクラスを作成したくなりますが、名前の衝突・どのクラスに対する Modifire なのか見分けがつかない・コードが検索しづらいなどの理由から数章されていません。

そのため、クラス名が長くなってしまうという欠点もあります。

規則が少し緩やかになった、MindBEMding と呼ばれるものが登場し、こちらの命名規則が現在主流となっています。

# SMACSS（Scalable and Modular Architecture for CSS）

[https://smacss.com/](https://smacss.com/)

SMACSS は Scalable and Modular Architecture for CSS（拡張可能でモジュール的な CSS 設計）の略です。
OOCSS と同じくマルチクラスでスタイルを適用します。

SMACSS の特徴は、CSS のコードを役割に応じて以下の 5 つにカテゴライズしたことです。

- ベース
- レイアウト
- モジュール
- 状態（ステート）
- テーマ

## ベース

ベースはプロジェクトの表示のスタイルを定義します。body 要素に背景色を設定する、a タグのスタイルを設定するなどを行います。
またリセット CSS を使用する場合もベースルールとして含めます。

## レイアウト

レイアウトは、ヘッダーやフッター、メインエリアなどの大枠を構成するものに対するものです。レイアウトルールでは、ページ内に一度しか使用されないことが多いので、ID セレクターによるスタイリングが許容されています。

またレイアウトルールにおいてクラスセレクターを使用する際には `l-` という接頭辞をつけることが推奨されています。

## モジュール

モジュールはレイアウトの中で使用されるボタンなどの再利用可能な部品です。
モジュールには接頭辞をつけません。

## 状態（ステート）

ステートはエラー、アクティブなどの状態を表すスタイリングです。状態スタイルはレイアウトやモジュールに割り当てることができ、JavaScript に依存します。

例えば、入力フォームでバリエーションエラーが発生した際には、JavaScript でそれに該当するスタイリングを適用することが求められます。

接頭辞には `is-` が用いられます。

## テーマ

最後にテーマルールです。サイト内のレイアウトや色を上書きする際に使用されます。ライトテーマとダークテーマを入れ替えるようなケースがわかりやすいでしょう。

接頭辞には `theme-` を使用します。

# FLOCSS（Foundation Layout Object CSS）

[https://github.com/hiloki/flocss](https://github.com/hiloki/flocss)

最後に、FLOCSS です。FLOCSS は日本人によって作成されており、ドキュメントも日本語で参照することが可能です。

OOCSS や SMACSS、BEM などのコンセプトを取り入れた設計思想で、SMACSS のようなレイヤー構成と BEM の命名規則を採用しています。こちらもマルチクラスでスタイルを適用させます。

FLOCSS は次の 3 つのレイヤーと、Object レイヤーの子レイヤーで構成されます。

- Foundation
- Layout
- Object
  - Component
  - Project 
  - Utility 

## Foundation

SMACSS のベースと同じくプロジェクトの基本的なスタイルを適用します。

## Layout

ページを構成するヘッダー、フッター、メインエリアなどのスタイルを定義します。
こちらも同じく ID セレクタの使用が許容され、クラスセレクタを使用する場合には `l-` の接頭辞を使用します。

SMACSS との違いとして、グリッドレイアウトのためのモジュールは Object/Component レイヤーとして定義します。

## Object

オブジェクトは OOCSS に従い、再利用可能なジュアルパターンをすべて Object と定義します。
Object はさらに次の 3 つのレイヤーに分けられます。

- Component
- Project
- Utility

### Component

Component は Object の中でもっとも小さな単位のモジュールです。ボタンなどが相当します。
これは Atomic Design における Atom に相当するもとの考えられます。

`c-` の接頭辞が使用されます。

### Project

プロジェクト固有のパターンであり、いくつかの Component が集まって構成されます。
例えば、記事一覧や、ユーザープロフィール、画像ギャラリーなどコンテンツを構成する要素などが該当します。

`p-` の接頭辞が使用されます。

### Utility

Utility はいわゆるヘルパークラスに相当します。

`u-` の接頭辞が使用されます。

## 命名規則

命名規則は基本的に MindBEMding のアイディア取り入れています。

さらに、Modifier の命名の派生パターンとして JavaScript で操作されるスタイルには `-is` 接頭辞を与えることができます。

## おわりに

CSS の設計がなぜ必要なのかと代表的な CSS の設計を見てきました。

さらに CSS の開発を効率化してくれるツールや、スタイルガイドジェネレーターなど触れていない箇所も多くあります。

「なんとなく CSS を書いていた」状態から「しっかりと CSS を設計できる」状態に切り替えられるようにしたいです。
  