CSSアーキテクチャの種類
CSSアーキテクチャとして有名なもの、新しく注目されているものをいくつかピックアップし、その特徴を紹介します。ここで紹介するのはBEM、OOCSS、SMACSS、FLACSS、RSCSSの5種類です。
BEM(Block__Element--Modifier)
BEMの概要
BEM(Block Element Modifier)はBlock、Element、Modifierの3つの要素を使ってクラスを命名する設計手法です。
- Block
枠組みとなる要素 - Element
Blockを構成する子要素 - Modifier
BlockやElementから派生する別バージョン
BEMは他のCSSアーキテクチャと比べて登場が早く、最も有名なCSSアーキテクチャです。BEMの公式ドキュメントでは、アーキテクチャの目的として次の3点を挙げています。
- 高速な開発と長期間メンテナンスできる設計
BEMでは規則が明快です。そのため、命名やファイル構造で悩むことが少なく、開発速度の向上が期待できます。また、規則が厳格なため、メンテナンス時の設計のブレを防ぐことができます。 - チームのスケーラビリティ
BEMはチームの共通言語の役割を担います。BEMを理解しているメンバーであれば、スムーズにプロジェクトに参加できます。 - コードの再利用性
パーツの独立性が高いため、コードの再利用が容易です。
BEMのコード例
ここで少しBEMの命名規則を説明しましょう。まず、サイトの構成要素をヘッダー、ナビゲーション、コンテンツ、フッタなどのパーツに分割します。BEMではこれらのパーツをBlockと呼びます。Block名に使う単語が複数ある場合はハイフンでつなげます。たとえばサイトナビゲーションの名前であれば、.site-navといったクラス名になります。
nav.site-nav
この.site-nav内に主要ページのリンクリストを配置するとしましょう。BEMでは、Block内に入る要素をElementと呼びます。このElementのクラス名は、親要素の名前と連結させた名前になります。たとえば、リンクリストのElement部の名称をlinklistとした場合、Block部のsite-navと連結して.site-nav__linklistとなります。
nav.site-nav
ul.site-nav__linklist
Block名とElement名はアンダースコア2つを続けて連結します。このElementの別バージョンが必要な際は、Modifierを使います。ModifierはBlockやElementのバリエーションを増やしたり、状態を表す要素です。元になる要素にハイフン2つを使って連結します。たとえばModifier名を bgblack とする場合、.site-nav__linklist と連結させると .site-nav__linklist--bgblack となります。
nav.site-nav
ul.site-nav__linklist.site-nav__linklist--bgblack
クラス名が2つ使われています。Modifierのクラスは単独で使うものではなく、元になる要素とセットで使います。
※ここで説明している命名規則は、BEMを発展させたMindBEMding(マインドベムディング)という拡張規則です。MindBEMdingがBEMと呼ばれることも多いので、これ以降も引き続き表記をBEMと表記します。
BEMは基本的にはシングルクラスを想定したアーキテクチャです。「Block__Element--Modifier」の命名規則があるので、Block名がかぶらない限りは意図しない名前の衝突は起きません。このBlock名も、Block毎にファイルを切り分けることで衝突を避けられます(ファイル名をBlock名にすることで、かぶること自体ができなくなる)。
参考資料
CSSアーキテクチャの中でも最古参のため、参考サイトも多く、ドキュメントが豊富です。
- 公式ドキュメント
https://en.bem.info/methodology/key-concepts/ - 公式ドキュメント(和訳)
https://github.com/juno/bem-methodology-ja/blob/master/definitions.md - BEMという命名規則とSass 3.3の新しい記法http://blog.ruedap.com/2013/10/29/block-element-modifier
- BEMによるフロントエンドの設計(Code Grid)https://app.codegrid.net/entry/bem-basic-1
- MindBEMding(和訳)
https://gist.github.com/juno/6182957
OOCSS
OOCSSの概要
OOCSS(Object Oriented CSS)はオブジェクト指向に基づいて考案されたCSSアーキテクチャです。Twitter、Github、Youtubeなどにも採用されています。特に、Twitter用に開発されたBootstrapがこのOOCSSを採用しており、子のフレームワークを多くのユーザが利用していることから、非常に影響度の高いアーキテクチャといえます。
OOCSSは構造に関係するスタイルと、装飾に関係するスタイルを分けて定義し、それらを組み合わせてスタイルを定義します。
構造:width,height,border,padding,margin等
装飾:color,border-color,background-color等
OOCSSで黒いボタンを定義する場合、構造がボタン、黒色が装飾です。
button.btn.btn-black ボタン
OOCSSは他のアーキテクチャと比べても再利用性が高く、クラス名もシンプルです。その反面、スタイルの変更がサイト全体に影響するため、メンテナンスに難があります。
Bootstrapに馴染みがあり、使いやすいと感じるのでしたらこのアーキテクチャが合うかもしれません。
参考資料
OOCSSスライダ解説(和訳)
https://www.slideshare.net/tshinobu/whats-objectoriented-css-japaneseSMACSS
SMACSSの概要
SMACSS(Scalable and Modular Architecture for CSS)は、BEM、OOCSSを参考に設計されたスタイルガイドです。Sassの利用が前提となっているので、Sassとの相性は保証付きです。
SMACSSでは、CSS設定を下記の5つに分類して記述を行います。
- Base ベースルール
CSSリセットを含む、要素のデフォルトスタイルを定義します。ここで定義するのはBODYやDIVといった要素に限定され、クラスやIDは設定しません。
- Layout レイアウトルール
ヘッダやフッタなど、ページのレイアウトを定義します。
プレフィックスに l- をつけます(l-header、l-footer)。
- Module モジュールルール
ボタンやテキストなど、レイアウトの構成要素で、再利用可能なパーツを定義します。
親モジュールの名前をプレフィックスに付与します(例: 親: .list、子: .list-item)。
- State 状態ルール
.is-activeなど状態によって見た目が変化する場合のスタイルを定義します。
プレフィックスに is- をつけます(.is-active、.is-error)。
- Theme テーマルール
サイト全体の視覚的なスタイルを定義します。たとえば、セクション毎や、言語毎に異なる色を使いたい際に、それぞれのテーマを定義します。プレフィックスに theme- をつけます(.theme-color)。
参考資料
SMACSSはドキュメントがしっかりしており、オフィシャルサイトの解説が和訳されてPDFやEPUBで無償公開されています。
- Scalable and Modular Architecture for CSS
http://smacss.com/ - Scalable and Modular Architecture for CSS(和訳)
http://smacss.com/ja
FLOCSS
FLOCSSの概要
FLOCSS(フロックス) は、OOCSSやSMACSS、BEM、SuitCSSのコンセプトを取り入れたCSSアーキテクチャです。FLOCSSでは、命名規則はBEMを使い、下記のレイヤーでCSS設定を分類します。
- Foundation
CSSリセットを含む、要素のデフォルトスタイルや、プロジェクトの基本的なスタイルを定義します。
- Layout
ヘッダやフッタなど、ページのレイアウトを定義します。 - Object
Objectは下記の3つのレイヤーで構成されます。 - Component
再利用可能なコンポーネントを定義します。
プレフィックスに c- をつけます(.c-button) - Project
記事一覧や、ユーザープロフィールなど、Componentに該当しないパターンを定義します。
プレフィックスに p- をつけます(.p-article) - Utility
ComponentとProjectレイヤーで解決しにくいものや、スタイル調整用のクラスなどを定義します。
プレフィックスに u- をつけます(.mb)
Sassを使う場合は次のようなディレクトリ構成が推奨されています。
├── foundation
│ ├── _base.scss
│ └── _reset.scss
├── layout
│ ├── _footer.scss
│ ├── _header.scss
│ ├── _main.scss
│ └── _sidebar.scss
└── object
├── component
│ ├── _button.scss
│ ├── _dialog.scss
│ ├── _grid.scss
│ └── _media.scss
├── project
│ ├── _articles.scss
│ ├── _comments.scss
│ ├── _gallery.scss
│ └── _profile.scss
└── utility
├── _align.scss
├── _clearfix.scss
├── _margin.scss
├── _position.scss
├── _size.scss
└── _text.scss
RSCSS(Reasonable System for CSS)
RSCSS(Reasonable System for CSS)はコンポーネント思考のCSSアーキテクチャです。RSCSSの特徴は他のCSSアーキテクチャと比べて規則が少なく、比較的学習コストが低いといえます。BEMのコンポーネントを参考にしつつ、クラス名が長くなるのを避け、マルチクラス、CSSのネスト、子セレクタ(>)を推奨しています。
Components
再利用可能なコンポーネントを定義します。クラス名は最低2単語で、単語はハイフンで連結します(.like-button、.search-form)。
Elements
Componentsを構成する要素を定義します。クラス名は1単語限定で、単語を複数使いたい場合は区切り文字を使わずに連結します(.firstname)。
セレクタには可能な限り > をつけます。
.search-form {
> .field {}
}
Variant
変化した状態を設定します。
プレフィックスにダッシュをつけます(.-active)。
.like-button {
>.-disabled {}
}
Layout
Componentsの配置を設定します。
Helpers
値を上書きするときに使います。
プレフィックスにアンダースコアをつけます(._center)。
公式ドキュメントにてアイデアセットと自己紹介しているだけあって、規則はミニマムです。覚えやすい反面、規定されていない部分を補う必要があります。また、公式以外の参考サイトがまだ少ないようです(2020年5月時点)。
- 公式ドキュメント
https://rscss.io/
英語ですが、Google翻訳で十分読めます。 - 日本語訳
その他のアーキテクチャ
- ECSS(Enduring CSS)公式ドキュメント
https://ecss.io/ - ECSSの扱い方
https://qiita.com/manabuyasuda/items/37523e9d0bfbad34211f
https://github.com/manabuyasuda/coding-guidelines/blob/master/css/how-to-ecss.md
OOCSS、SMACSS、BEMで解決できなかった問題のために開発されました。OOCSSの再利用性などを犠牲にしつつ、使い勝手やシンプルさを重視しています。同じような見栄えであっても別物として扱い、重複も許されます。命名規則はBEMベースです。
各アーキテクチャの比較
Googleにて、CSS + CSSアーキテクチャ名で検索し、その結果を調べてみました。誤マッチを減らすために「CSS」と組み合わせて検索しています。
BEM | 19,800,000 |
OOCSS | 90,800 |
FLOCSS | 204,000 |
RSCSS | 15,500 |
ECSS | 50,700 |
次にGithubでも検索してみました。
BEM | 8,373 |
OOCSS | 262 |
FLOCSS | 45 |
RSCSS | 45 |
ECSS | 247 |
古くから使われているBEMが圧倒的1位という結果になりました。
次はリリース時期を調べてみました。リリース時期がはっきりしないところがあり、若干正確性に欠けるかもしれません。
BEM | 2009年にLEGO2.0としてリリース |
OOCSS | 2009年 |
SMACSS | 2012年 |
FLOCSS | 2014年 |
RSCSS | 2015年 |
ECSS | 2015年 |
ちなみにSassのリリースは2006年です。
最後にクラス名の命名規則の特徴を下記に記載します。
BEM | BEM命名規則のオリジナル。クラス名は「Block__Element--Modifier」の組み合わせで、明確だが長い。 |
OOCSS | 機能や性質で名前をつけるのでクラス名は短い。 |
SMACSS | 各レイヤーごとにプレフィックスを用意。 |
FLOCSS | BEMベース。 |
RSCSS | > セレクタを積極的に使い、クラス名が短い。 |
ECSS | BEMベースで、さらにネームスペースを追加するため、さらに長い。 |