Coding 2019.10.22

シンプル is ベストなCSS記法「RSCSS」

記事のアイキャッチ画像

コンポーネント指向プログラミングのために生まれたCSS記法「RSCSS」のドキュメントを要約しました。

はじめに

このブログでも採用しているCSS記法のひとつである「RSCSS」。

  • RSCSS自体にコンポーネントの概念があり、コンポーネント指向と非常に相性が良い
  • クラス名が短い

この2点がとても魅力的で、非常にシンプルで簡潔にコーディング出来ます。
とは言え、そのルールはドキュメントの一読が必要になってくるので、今回は読みやすいようにドキュメントの内容をまとめています。

命名規則について

コンポーネント

20191013 01

コンポーネントの命名には以下のルールを適用します。

  • 2単語以上を-で連結
.search-form { /* ... */ }
.rico-custom-header { /* ... */ }

コンポーネントの要素

20191013 02

コンポーネントの要素の命名には以下のルールを適用します。

  • 1単語で命名
  • 2単語以上が必要な場合、記号は使わずに連結
.search-form {
  > .field { /* ... */ }
  > .action { /* ... */ }
  > .anotheritem { /* ... */ }
}

コンポーネントのバリエーション

20191013 03

ひとつのコンポーネントに複数のバリエーションがある場合、バリアントを使います。
コンポーネントの要素もバリアントを持つことが出来ます。

バリアントの命名には以下のルールを適用します。

  • プレフィックスに-を付ける
.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 { /* ✓ こうする */ }
}

ネストされたコンポーネント

20191014 01

<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;
  }
}

レイアウトに関するプロパティ

20191014 02

再利用性を高めるため、コンポーネント内で宣言を避けるべきプロパティがあります。

  • ポジショニング(positiontopleftrightbottom
  • フロート(floatclear
  • マージン(margin
  • 寸法(widthheight

※これらの例外は、アバターやロゴなど、幅/高さが固定されている要素です。

避けるべきプロパティを定義する場合、そのコンポーネントを内包している親コンポーネントの子要素として定義します。

.article-list {
  > .article-card {
    width: 33.3%;
    float: left;
  }
}

.article-card {
  > .image { /* ... */ }
  > .title { /* ... */ }
  > .category { /* ... */ }
}

このように、.article-card単体にはwidthfloatは定義せず、.article-listの子要素としてwidthfloatを定義します。

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記法だと感じています。


Category List カテゴリー

Tag List タグ