シンプル is ベストなCSS記法「RSCSS」
コンポーネント指向プログラミングのために生まれたCSS記法「RSCSS」のドキュメントを要約しました。
はじめに
このブログでも採用しているCSS記法のひとつである「RSCSS」。
- RSCSS自体にコンポーネントの概念があり、コンポーネント指向と非常に相性が良い
- クラス名が短い
この2点がとても魅力的で、非常にシンプルで簡潔にコーディング出来ます。
とは言え、そのルールはドキュメントの一読が必要になってくるので、今回は読みやすいようにドキュメントの内容をまとめています。
命名規則について
コンポーネント
コンポーネントの命名には以下のルールを適用します。
- 2単語以上を
-
で連結
.search-form { /* ... */ }
.rico-custom-header { /* ... */ }
コンポーネントの要素
コンポーネントの要素の命名には以下のルールを適用します。
- 1単語で命名
- 2単語以上が必要な場合、記号は使わずに連結
.search-form {
> .field { /* ... */ }
> .action { /* ... */ }
> .anotheritem { /* ... */ }
}
コンポーネントのバリエーション
ひとつのコンポーネントに複数のバリエーションがある場合、バリアントを使います。
コンポーネントの要素もバリアントを持つことが出来ます。
バリアントの命名には以下のルールを適用します。
- プレフィックスに
-
を付ける
.like-button {
&.-wide { /* ... */ }
&.-disabled { /* ... */ }
}
.shopping-card {
> .title {
&.-small { /* ... */ }
}
}
ヘルパー
!important
を付けて値を上書きするクラスになります。
ヘルパーの命名には以下のルールを適用します。
- プレフィックスに
_
を付ける
._unmargin { margin: 0 !important; }
._center { text-align: center !important; }
._pull-left { float: left !important; }
._pull-right { float: right !important; }
また、ヘルパーはすべて1つのファイルに定義します。
書き方について
セレクタ
- 可能な限り
>
を使用 - タグセレクターは避ける
.article-card {
.title { /* これでも良いけど */ }
> .author { /* ✓ 可能な限りこう */ }
}
.article-card {
> h3 { /* ✗ これは避けて */ }
> .name { /* ✓ こうする */ }
}
ネストされたコンポーネント
<div class='article-link'>
<div class='vote-box'>
<p class="up"></p>
</div>
</div>
例えば.vote-box
が.article-link
を親に持つ場合に限り、バリエーションを持つような場合であっても、そのスタイル定義に.article-link
を含ませるのは避けるべきです。
.article-link {
> .vote-box > .up { /* ✗ これは避けるべき */ }
}
上のような場合は、.vote-box
に新たにバリアントを追加してバリエーションを定義します。ここでは例として.-highlight
を追加しています。
<div class='article-link'>
<div class='vote-box -highlight'>
<p class="up"></p>
</div>
</div>
.vote-box {
&.-highlight > .up { /* こうすべき */ }
}
また、コンポーネントのネストはマークアップが汚れる場合があります。
<div class='search-form'>
<input class='input' type='text'>
<button class='search-button -red -large'></button>
</div>
その場合は@extend
を使用して、これを簡素化できます。
<div class='search-form'>
<input class='input' type='text'>
<button class='submit'></button>
</div>
.search-form {
> .submit {
@extend .search-button;
@extend .search-button.-red;
@extend .search-button.-large;
}
}
レイアウトに関するプロパティ
再利用性を高めるため、コンポーネント内で宣言を避けるべきプロパティがあります。
- ポジショニング(
position
、top
、left
、right
、bottom
) - フロート(
float
、clear
) - マージン(
margin
) - 寸法(
width
、height
)
※これらの例外は、アバターやロゴなど、幅/高さが固定されている要素です。
避けるべきプロパティを定義する場合、そのコンポーネントを内包している親コンポーネントの子要素として定義します。
.article-list {
> .article-card {
width: 33.3%;
float: left;
}
}
.article-card {
> .image { /* ... */ }
> .title { /* ... */ }
> .category { /* ... */ }
}
このように、.article-card
単体にはwidth
やfloat
は定義せず、.article-list
の子要素としてwidth
やfloat
を定義します。
CSSのネスト
3階層以上のネストは避けるべきです。
/* ✗ 3階層以上は避けるべき */
.image-frame {
> .description {
/* ... */
> .icon {
/* ... */
}
}
}
/* ✓ 2階層以下ならOK */
.image-frame {
> .description { /* ... */ }
> .description > .icon { /* ... */ }
}
注意すべき点
ネストされたコンポーネント
同じクラス名を要素に持つコンポーネントが親子関係にあるときに注意が必要です。
<article class='article-link'>
<div class='vote-box'>
<span class='count'>4</span>
</div>
<p class='count'>3 votes</p>
</article>
.article-link {
> .count { /* ... */ }
}
.vote-box {
> .count { /* ... */ }
}
>
を使っている限り問題はありませんが、>
を使っていない場合に同じクラス名の要素にまでスタイルが適用されてしまいます。これが>
を使用すべき理由のひとつです。
RSCSSではクラス名が短い分、名前の重複がよく起こるので注意が必要です。
命名規則に従いたくない・従えない
-
なんて使いたくない
クラスの命名に-
を使いたくないという意見があります。無理して使わなくても良いのですが、「コンポーネント」、「要素」、「バリアント」の概念だけは忘れないでください。
2語なんて思いつかない
例えばalert
。このコンポーネントを2語で表現するのは非常に難しく思えます。
その場合は接尾辞を使用すると、ブロックレベルの要素であることが明確になります。
.alert-box
.alert-card
.alert-block
またはインラインの場合:
.link-button
.link-span
さいごに
今回はドキュメントをまとめた内容になりますので、いずれ実際にRSCSSを使用してみて感じたことも記事にしたいと思います。
今までBEMやSMACSSをどこか違和感を覚えながら使っていましたが、RSCSSはここ1年ほど使ってみても特にシコリもなく気持ちよく使えています。
最近のフロントエンドではコンポーネント指向でのプログラミングがスタンダードになっていますので、今の時代に非常にマッチしたCSS記法だと感じています。