##設計思想的な話 後編 ~MCSS/FLOCSS/ECSS/(Atomic Design)~
今日覚えていってほしいこと
- MCSSってなんぞ
- FLOCSSってなんぞ
- ECSSってなんぞ
- Atomic Designってなんぞ
MCSS
MCSS (Multilayer CSS)
- BEMとOOCSSの原理を元にするCSS構成システム
- CSSを
Base(ファーストレイヤー)
Project (セカンドレイヤー)
Cosmetic (サードレイヤー)
の主に3つの階層に分離し管理する - 読込み順を厳格に定めることにより、レイヤー間の正しいカスケーディングを保持する。
引用:MCSS
⓪ Foundadion(ゼロレイヤー)
- リセットとちょっとした変更を加えるだけのメインレイアウトのベースを持つレイヤー(reset.css,normalize.css)
- 全ページに適用されるスタイルが含まれる
- 読込みは何よりも最初
引用:MCSS
SMACSSのBaseカテゴリと同じようなもんやね
① Base(ファーストレイヤー)
- UIの核となるレイヤー
- 最も再利用可能で抽象的な構造を持つ
- Baseレイヤーのモジュールは全てのページで再利用されることが期待されている
- Baseモジュールはデフォルトスタイルを持つが、Projectモジュールによって簡単に変更できる必要もある
- Baseレイヤーから他のBaseレイヤーや、Projectレイヤーからカスケードで変更される可能性がある
- しかしBaseレイヤーからProjectレイヤーを変更することは禁止されている
- 読込みはFoundadionの後
か〜なり抽象度を上げて書かれるのがBaseレイヤーですね。
② Project(セカンドレイヤー)
- ページを構成するProjectモジュールを含むレイヤー
- 可能な限りユニークなCSSクラスの使用が推奨される
- Projectレイヤーに書かれたスタイルは、他のProjectレイヤーモジュールからのみカスケードによる変更が行われる可能性がある
- 読込みはBaseの後
<!--
umenu - Baseレイヤーのモジュール
toolBar - Projectレイヤーのモジュール
-->
<header class="toolbar">
<a href="/" class="toolbar_logo"></a>
<menu class="toolbar_dropdown_ul umenu">
<li class="umenu_li"></li>
<li class="umenu_li"></li>
</menu>
</header>
/* Toolbar
-------------------------------------------------- */
.toolbar { }
.toolbar_dropdown_ul { }
.toolbar_dropdown_ul .umenu_li { } /* Baseモジュールをカスケードする */
/* /Toolbar */
Baseモジュールはデフォルトスタイルを持っているけど、Projectによって書き換えられることも想定しておかなきゃいけないんだね〜。
③ Cosmetic(サードレイヤー)
- シンプルで、わずかに影響するスタイルからなるレイヤー
- 非Projectモジュールのために、シンプルなOOCSSクラスをブロックで最大3つまで使用できる
- 読込みは最後
<div class="font-size_XL margin-t_L color_red"></div>
なんかこう、困った時にちょいってする感じ?再利用性を考えたモジュール作るほどのもんでもねぇな、とか。
④ Contextレイヤー(例外)
- 特定のブラウザやデバイス向け、あるいはメディアクエリによる特定な条件下など、様々な状況のために標準スタイルを変更するのに使用される例外的なスタイルを定義するレイヤー
- Contextレイヤーとしてまとめて記載する場所はもたない。各モジュールの中で記載する
- ContextレイヤーはCosmeticsレイヤーを上書きすることが可能
/*Button module*/
.button {...}
.touch .button {
line-height: 44px;
}
@media screen and (max-width: 320px;){
.button {...}
.button {
padding: 0;
width: 100%;
}
}
MCSSまとめ
- CSSの管理に、レイヤー構造という概念をもたせた
- CSSの読込み順(記載順)とレイヤー間の上書きルールを守ることにより、各レイヤーの正しい関係を維持する
CSSの最大の特徴である「カスケーディング」をうまく利用してますね。
FLOCSS
FLOCSS
- OOCSSやSMACSS、BEM、SuitCSSのコンセプト、MCSSのレイヤー構成を取り入れた、モジュラーなアプローチのためのCSS構成案
- 大きな3つのレイヤー(
foundation
layout
object
)と、object
レイヤーの3つの子レイヤー(component``project``utility
)からなる - 命名規則はMindBEMding
|---foundation (reset/normalize/base...)
|---layout (header/main/sidebar/footer...)
└---object
|---component (grid/button/form/media...)
|---project (articles/ranking/promo...)
└---utility (clearfix/display/margin...)
形)モジュラー = モジュールになった・モジュール化された
名)モジュール = 組み立てユニット・装置・機能的にまとまった部分
① Foundation
- Reset.cssやNormalize.cssなどを用いたブラウザのデフォルトスタイルの初期化や、プロジェクトにおける基本的なスタイルを定義する
SMACSSのBaseカテゴリ、MCSSのFoundataionレイヤーと同じようなもんやね
② Layout
- ページを構成するヘッダーやメインのコンテンツエリア、サイドバーやフッターといったプロジェクト共通のコンテナーブロックのスタイルを定義するレイヤー
- 基本的にページ内に唯一の存在なので、 IDセレクタを使っても良い
SMACSSのLayoutカテゴリでは、グリッドレイアウトのためのモジュールも含めたけど、FLOCSSでは、グリッドフレームワークとしての定義はFoundationレイヤーで扱うべき、とのこと。
なぜならCSSプリプロセッサによるmixinやfunctionは各所でincludeされることが考えられるから、とのことだが、
適用のしやすさを考えてObjectレイヤーに持たせても良いらしい。運用に合わせて変えていいらしい。
③ Object - Component
- 再利用できるパターンとして、小さな単位のモジュールを定義するレイヤー
- 出来る限り、最低限の機能を持ったものとして定義されるべきレイヤー
- それ自体が固有の幅や色などの特色を持つことは避けるのが望ましい
MCSSのBaseレイヤーと同じようなもんやね
④ Object - Project
- プロジェクト固有のパターンであり、いくつかのComponentと、それに該当しない要素によって構成されるものを定義する
- 記事一覧や、ユーザープロフィール、画像ギャラリーなど、コンテンツを構成する要素など
ページを構成する要素のほとんどがProjectレイヤーになる
⑤ Object - Utility
- ComponentとProjectレイヤーのObjectのモディファイアで解決することが難しい・適切では無い、わずかなスタイルの調整のための便利クラスなどを定義するレイヤー
- Object自体が持つべきではないmarginの代わりに
.mbs { margin-bottom: 10px; }
のようなUtility Objectを利用する - clearfixテクニックのためのルールセットもここに含まれる
MCSSのContextレイヤーと同じようなもんやね
Objectのプレフィックス
- Component -
.c-*
- Project -
.p-*
- Utility -
.u-*
必ずしもこの通りでなくて良いが、必ず 命名に一貫性を保つこと
カスケーディングと継承ルール
- レイヤー間のカスケーディング、他モジュールを親とするセレクタを用いたカスケーディングは原則として禁止する
- 例外として、ProjectレイヤーがComponentレイヤーを変更することは許容する
- モジュール内で完結するカスケーディング、複数のセレクタを用いることは許容する
- セレクタを継承するためのExtendは、原則そのモジュールで完結する継承以外では利用を禁止する
flocssを使ってるコンテンツの例
http://glab.gnavi.co.jp/dev-markup/pfr-stat-menu
http://my.gnavi.co.jp/restaurant/
FLOCSSまとめ
- MCSSをベースとし、プレフィックスをつけるなど、命名においてもより開発者に分かりやすいように設計されている印象。
あくまで個人の感想です。
ECSS
ECSS(Enduring CSS)
- Enduring = 永続する・長持ちする
- ファイルサイズ、UIの数、開発者の数などが大規模なWebアプリケーションのCSSを合理的に書くためアプローチ
- 抽象化を避け、複雑さを排除する
- 「分けて考える」がキーワード
「ストラクチャ」と「スキン」をレゴのように組み合わせていくOOCSSは、その分「小さなコンポーネントを組み合わせる複雑さ」をCSSにもたらしてはいないか?
高次に抽象化され共通化されたコンポーネントは、「コンポーネントの影響範囲が大きいので変更・削除がしにくい」という状況を引き起こしていないか?
@extendやmixinをフルに活用したスマートなSass(SASS,SCSS)は、見た人がすぐに理解できる簡潔さを持っているだろうか?
OOCSSがDRY(Don't repeat yourself:繰り返しを避けること)を目指しているのとは対照的に、ECSSでは繰り返しを許容し、適切に分離(decoupling)することを目指しているのが特徴
ECSSが目標とすること
- ブレース({ })の外側をどのように扱うのかに主眼を置き、キーセレクタをDRYにすることを目標とする
キーセレクタ:セレクタのいちばん右側にある実際にスタイルが適応されるセレクタのこと。
「同じレゴ(プロパティ)は2つもいらないよ、だって組み合わせれば何でも作れるじゃん。」というのがOOCSS。
「似たようなレゴが何個あっても良いよ、キーセレクタが1つのブレースで完結している(DRYである)ならね。」というのがECSS。
ECSSのディレクトリ構成
下記のようなテンプレート構造の場合
- トップページ
- カテゴリトップ(例: 家電、インテリア、キッチン用品……)
- 商品詳細
- ショッピングカート
/assets
/TopPage (トップページ)
/css
/imgs
/js
/CategoryTop (カテゴリトップ(例: 家電、インテリア、キッチン用品……))
/css
/imgs
/js
/ProductDetail (商品詳細)
/css
/imgs
/js
/ShoppingCart (ショッピングカート)
/css
/imgs
/js
サイト内で共通のコンポーネント、共通のスタイル、という考え方をせずに、がっつり分ける
ECSSの名前空間
バッティングさせないために、「名前空間」を用いる。
- トップページ -
tp (TopPage)
.tp-NewProductList
.tp-AdArea
.tp-RecommendedProductList
.tp-Carousel
- カテゴリトップ -
ct (CategoryTop)
- 商品詳細 -
pd (ProductDetail)
- ショッピングカート -
sc (ShoppingCart)
- サイトの構造のキーとなるようなモジュールの名前空間 -
st (Structure)
,sw(SiteWide)
サイト共通のヘッダーやフッターは
.st-Header
.st-Footer
になったりします。が、名前空間の名前自体は自由に考えてよいです。
ECSSにおけるモジュールとその中身
「a module is the widest, visually identifiable, individual section of functionality.」
モジュールは、視覚的に認識できる個別の機能領域のもっとも大きな区分である。
「components are the nested pieces of functionality that are included within a module」
コンポーネントは、モジュール内に含まれる(入れ子になっている)、機能性を持つ部品である。
「child nodes are the individual parts that go to make up a component (typically nodes in the DOM)」
子ノードは、コンポーネントを構成する、独立した部品(DOM要素のこと)である。
後述するAtomic Designでは「小さなものから組み合わせる」という考え方ですが、ECSSの場合は「いちばん大きなもの(Module)を探して、その中にはどんな要素が必要なのかを考える」よ。
ECSSの命名規則
.[namespace][-ModuleOrComponent][_ChildNode][-variant]
/* `tp`名前空間を持つComponentとChildNode */
.tp-NewProductList {...}
.tp-NewProductList_Title {...}
.tp-NewProductList_Title-bg1 {...}
- class名ではModuleなのかComponentなのか分からないが、それは許容する。
-
namespace
とvariant
はローワーキャメルケースで、それ以外はアッパーキャメルケース。 -
namespace
はModule名になることもある。
.[module][-Component][_ChildNode][-variant]
ECSSの命名規則はBEMの命名規則と似ている。
- ModuleとComponent:Block
- ChildNode:Element
- variant:Modifier
大きな違いは、ModuleとBlockの粒度の違い。
Moduleの状態変化
WAI-AREAを使用することが推奨されている
- aria-selected
- aria-disabled
- aria-hidden
- aria-expanded
- aria-busy
- aria-current
![]()
.is-active
のようなクラスを追加するよりも名前のバラつきが起こりにくいことや、標準化された支援技術によってアクセシブルになることが期待できるから。
WAI-ARIAを使わない場合は.is-のような名前空間でなく、variantを使うことを勧めているよ。
ECSSの10ヶ条
-
Thou shalt have a single source of truth for all key selectors
全てのキーセレクタは単一の真実を語る資料であれ -
Thou shalt not nest (unless thou art nesting media queries, overrides or thou really hast to)
ネストすることなかれ(media queryのため、上書きするため、あるいは本当に必要でない限り) -
Thou shalt not use ID selectors (even if thou thinkest thou hast to)
IDセレクタを使うことなかれ(たとえそうすべきだと思ったとしても) -
Thou shalt not write vendor prefixes in the authoring style sheets
オーサリングスタイルシートにベンダープレフィックスを使うことなかれ -
Thou shalt use variables for sizing, colours and z-index
サイズ、色、z-indexに変数を使いなさい -
Thou shalt always write rules mobile first (avoid max-width)
常にモバイルファーストでルールを書きなさい(max-widthを避けなさい) -
Use mixins sparingly (and avoid @extend)
mixinは控えめに使いなさい(そして@extendは避けなさい) -
Thou shalt comment all magic numbers and browser hacks
全てのマジックナンバーとブラウザハックについてはコメントしなさい -
Thou shalt not inline images
インライン画像を使うことなかれ -
Thou shalt not write complicated CSS when simple CSS will work just as well
シンプルなCSSで同じように動くのに、複雑なCSSを書くことなかれ
オーサリングスタイルシート:PostCSSやSassなどのスタイリングルールを作成するファイル。
マジックナンバー:(理由もなく)「動作するから」というだけで使われている値。
ECSSまとめ
- IDEALISM(理想主義)よりPRAGMATISM(実利主義)なCSS設計
- ページを構成するUIを「モジュール」単位に分ける
- 「モジュール」は「名前空間」でまとめる
- 「名前空間」ごとにアセットは分けて管理する
Atomic Design
Atomic Design
- CSS設計思想 ではない
- Atoms(原子)、Molecules(分子)、Organisms(有機体)、Templates(テンプレート)、Pages(ページ)の各コンポーネント同士を組み合わせて作成するデザイン手法
Atoms(原子)
- 画面を構成する要素の最少単位 ラベルやインプット項目など
Molecules(分子)
- Atomsを組み合わせて作成された要素 検索フォームなど
Organisms(有機体)
- 複数のMoleculesやAtomsを組み合わせたもの、ヘッダーやフッターなど
Templates(テンプレート)
- 複数のOrganisms等を組み合わせたデータの入っていない画面 ワイヤーフレームとなるもの
Pages(ページ)
- 実際の文言や画像などが入ったもの、ほとんど最終的な画面と同じ
Atomic Designについて個人的に思うことは、去年のフロントエンドGのLT大会でちょっとしゃべってるから、それ見てみて〜。
動画
スライド
APB CSS(Atomic Parts Base CSS)
- Atomic Designを取り入れたCSS設計手法
- OOCSSとSMACSSを取り入れたマルチクラスを採用
詳しくは公式をどうぞ
おまけ
色々あるよCSS設計思想
いろんなプロジェクトのREADMEに書かれているCSSルールを見てみよう。
先人たちの創意工夫や思想が読み取れますね。でもまぁとりあえず大事なのは、基本を理解すること、ですね!
次回予告
- Sass構文
- cssnext