SMACSSとSUIT CSS naming conventionsをベースに個人的なプロジェクトのみで使用するクラス名の命名規則について考えてみた。
IDはスタイリングに使わずクラスのみを使用する。
カテゴリ表すためにプレフィックスを使用する。
- Layout Module
.l-<layout_element_name>
- Component Module
.c-<component_element_name>
- Theme
.t-<theme_name>
- State
.is-<state_name>
- State
- Mofifier
.mod-<modify_name>
- Theme
- Utility
.u-<element_name>
- JavaScript
.js-<element_name>
クラス名には先頭にカテゴライズを行うためのプレフィックスを使い、どんなところに使うべきクラスかを表すようにする。 プレフィックスを指定したクラスは一意な名前とし、マルチクラスで子孫セレクタを前提とした構造にすることができる。子孫は必ず親セレクタの名前をプレフィックスとして継承することでセレクタの子孫構造を表し、クラス名が長くなることを避ける。
// Syntax: <prefix>-<element_name>
.c-box {
/* ... */
}
// Syntax .<prefix>-<element_name>.<element_name>-<child_element_name>
.c-box.box-header {
/* ... */
}
CSSでは少し冗長であるがSCSSであれば許容できる範囲のシンプルさを保てる。
.c-box {
/* ... */
&.box-header {
/* ... */
}
}
セレクタの子孫が複数の階層構造となってしまう場合、パフォーマンス低下の原因となるので、親のセレクタ<prefix>-<ElementName>
を必須とした子孫セレクタにすることを前提として、間のセレクタを省略してセレクタ指定を行える。
.c-box {
/* ... */
// Syntax: <element_name>-<child_element_name>
.box-header {
/* ... */
}
// インデントでレベルを表現
// Syntax: <child_element_name>-<grand_child_element_name>
.header-title {
/* ... */
}
// Syntax: .<grand_child_element_name>-<great_grand_child_element_name>
.title-badge {
/* ... */
}
}
HeaderやFooter、Container等の再利用をしないレイアウトモジュールのためのクラス。
// Syntax: .l-<layout_element_name>
.l-header {
background: #aaa;
}
リストやボタンなどの再利用可能なモジュールとして定義するクラス。コンポーネントはスタンドアロンで利用できるよう設計し再利用性を高める。
// Syntax: .c-[<namespace>-]<component_element_name>
.c-box {
background: #eee;
}
<section class="c-box">
<header class="box-header">
<h1 class="header-title">{{text}}</h1>
<p class="header-sub_title">{{text}}</p>
</header>
<div class="box-container">{{text}}</div>
</section>
レイアウトモジュールやコンポーネントに対してカラーテーマを指定するためのクラス。Component側ではデフォルトのスタイルを持ちStateやModifyよりもローレイヤーなスタイルとなる。テーマではサイズやポジションに関するスタイリングを指定しない。
// Syntax: .t-<theme_name>
.t-inverse {
background: #000;
}
<div class="c-box t-inverse">{{text}}</div>
Themeは下記モジュールにのみ定義できる。
- Layout Module
- Component Module
コンポーネント等のある状態(current等)を表すために利用するクラス。デフォルトテーマ以外のテーマが定義されている場合、テーマモジュールの子孫セレクタとなる。
// Syntax: .is-<state_name>
.is-current {
background: #cc0000;
}
.t-inverse {
.is-current {
background: #00ccc00;
}
}
<div class="c-box is-current">{{text}}</div>
<div class="c-box t-inverse is-current">{{text}}</div>
Stateは下記モジュールにのみ定義できる。
- Layout Module
- Component Module
Stateの変更とまではならない限定的なスタイルの変更に利用するクラス。Stateに影響を与えないような変更のにみ利用する。Modifierは必ずしもテーマの子孫セレクタになる必要はない。
// Syntax: .mod-<modify_name>
.mod-half_width {
width: 50%;
}
<div class="c-box mod-half_width">{{text}}</div>
Modifyは下記モジュールにのみ定義できる。
- Layout Module
- Component Module
レイアウトやコンポーネントに属さないポジションなどを制御するためのクラス。
// Syntax: .u-<element_name>
.u-clear {
/* ... */
}
JavaScriptでDOMを制御する場合、カスタムデータ属性を使用する。
<div class="c-box" data-js="insertText">{{text}}</div>