少し前からBEMやSMCASSなどのCSS設計などを知り、なるほどこういう方法があるのかと、苦戦しながら実践していました。
そんな中@hiloki@githubさんが自前でFLOCSSというCSS設計思想をGithubで公開していたので、
自分もこういうの作ってみたい!と思いたち、
稚拙ながら設計を考えてみました。
OOCSS,SUIT,SMACSS,FLOCSSあたりを参考にしています。
CSSのカテゴライズ
- Base
- Component
- Unit
- layout
- pack
- Asset
- utility
- assist
CSSをこのように分割します。
Base
SMACSSのBaseにあたるものです。
Component
ページを構成するパーツのすべてです。
再利用しやすいよう、親に依存せず、Component単独でスタイルを維持できるように設計します。
Componentは自分自身の見た目のみを司り、位置関係に関しては、後述するUnitクラスがすべて受け持つようになります。
命名規則
- ComponentName
- ComponentName--skinName_[n]
- ComponentName-descendentName_[n]
Componentはskeletonとskinに分けて記述します。
ComponentName
がスケルトンになり、そのComponentに形作るための必要最低限のスタイルを司り、
ComponentName--skinName
が、そのComponentのskin(modifier)のスタイル司っています。
また、Componentを作るモジュール群に関しては、ComponentName-descendentName
で記述します。
Componentの子要素にはすべてクラス名でスタイル当てていきます。(構造とスタイルの分離のため)
親コンポーネントによって、子コンポーネントの形が変わる場合には親コンポーネントと同じskinNameを付与し対応します。
例を示します。
<div class="Island Island--notify">
<div class="Island-head">
<h3 class="Heading Heading--h3"></h3>
</div>
<div class="Island-body">
<ul class="LinkList LinkList--notify">
<li class="LinkList-item"></li>
</ul>
</div>
</div>
セマンティックに名前を付けられない場合、またはパターンがあるものに関しては、コンポーネント名(または、skinName,descendentName)の最後に_[value]
を追加し対応します。
<a href="#" class="TextLink TextLink_1"></a>
Unit
Unitにはページで一つだけしか使えないLayoutクラスと、汎用的に使えるPackクラスが存在します。
先述したように、
Componentは、そのComponentがどのような見た目をしているかだけを司り、
そして、その親のUnitが、そのComponent(またはComponent群)が、どのような位置関係にあるかを司ります。
これによって、Componentがどの位置にあるかについては全く関与しないで、自分自身の見た目だけを司ることができます。
Layout
ページに唯一のUnitとしてはプリフィックスとしてl-をつけます(Layout)
LayoutはSMACSSでいうThemeの役割も担っており、ページごとにオリジナルなComponentにしたい場合のフックに利用します。
.l-header {}
.l-sidebarRight {}
.l-specialPage {}
Pack
汎用的に使えるUnitとしてプリフィックスとしてp-をつけます(Pack)
.p-container {}
.p-streamCard {}
Asset
Assetはグローバルに使えるUtilityクラスと、コンポーネントを補助するAssistクラスが存在します。
Utility
marginやpadding、そしてclearfixなどグローバルに使える、単一のスタイルが付与されたクラスがここに分類されます。
プリフィックスとしてu-
をつけます。
スタイルには明示的に!important
を付与します。
.u-mb10 {}
.u-clearFix {}
Assist
Assistクラスは必ずコンComponentとセットで利用します。
必ずCSSはComponentとの結合セレクタで定義します。
.has-border {}
.has-header {}
タブがアクティブ、非アクティブやモーダルが、表示、非表示などコンポーネントの状態を示すときはis-
を使います
.is-hidden {}
.is-error {}
.is-active {}
.Tab-button.is-active {}
ボーダーがある場合、ない場合やアイコンをある場合、ない場合などコンポーネントのパーツを拡張したり、修飾する場合はhas-
を使います
.has-border {}
.has-header {}
.has-icon {}
.Panel.has-header {}
skinとほぼ同じ役割のように見えますが、クラス属性が冗長になるのを防ぐために、モジュールの追加(パネルのヘッダ)やグローバルなモジュール(枠線など)の場合はhas-
を使います。
<div class="Panel Panel--primary has-header"></div>
以上です。
不満な所
- 制約が多くて覚えにくい(致命的)
- の割に、複雑なUIを形成する際に詰まりそう
そして
心安らかに、拡張していけるようになりたい。
あとは、とにかくプロジェクトメンバーとの思想の共有と、コードレビューを徹底する。
作ってみて思ったのですが、
設計はメンバーで徹底する事が大事なので、もう少し、軽めに分かりやすくシンプルにするのが、寿命が長い設計のためには必要だなと思いました。
はじめて、こういうものを作ってみましたが、
これから、自分の成長とともにアップデートしていきたいなと思います。