SMACSSを参考にしたCSSコーディング規約

  • 114
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

SMACSSを参考にしたCSSコーディング規約

いまちょうどチームでそれなりの大きさのHTMLを書いているので、SMACSSを参考にコーディング規約を作ったりしています。せっかくなので何かの参考にと思い公開してみました。

HTMLコーディング

HTML5

HTMLのコーディングはHTML5のDOCTYPE準拠のタグを利用します。

<!DOCTYPE html>

コーディングスタイル

HTMLのインデントは半角スペース4文字とします。タブは利用しないでください。

また、シンプルなコーディングのため、XMLの記法は利用しません。

GOOD

<img alt="no xml" src="noxml.png">

BAD

<img alt="no xml" src="noxml.png" />


CSS コーディング

SCSS

柔軟性を重視し、CSSの記法はSCSSを採用します。(参考)

SCSSにすることで、libsassを用いた高速なコンパイルが可能になるというメリットもあります。

基本スタイル

リセット

基本のリセットスタイルにはnormalize.cssを利用します。

フレームワーク

フレームワークはFoundationを採用します。mixinが提供されており、SASSとの親和性が高いためです。
ドロップダウンメニューやモーダルを作成する際には、Foundationの提供する機能を利用してください。

レスポンシブデザイン

レスポンシブデザインへの対応のため、フォントサイズやグリッドにはrememといった単位を使用します。

また、ボックスモデルに関して以下のスタイルが全体に適用されていることに注意してください。

*, ::after, ::before {
  box-sizing: border-box;
}

Compassとベンダープレフィックス

今回はlibsassを利用するため、Compassは利用しません。CSS3のベンダープレフィックスについては、autoprefixerを使って解決します。

ベース、モジュールとレイアウト

モジュールとレイアウトの概念はSMACSSを参考にしています。詳しくはSMACSSのドキュメントを参照してください。

モジュールとレイアウトに構造を分けることで、CSSクラスの再利用性を高めます。

基本的に、再利用できるような部品としてモジュールにまとめた上で、ページ上の位置指定などをレイアウトを使って行います。

また、ベースでは汎用的なmixinの定義や全体のスタイル定義を行います。

セレクタ定義とモジュール化

それぞれのモジュールの平等性を高めるため、CSSのセレクタにはIDは利用せず、必ずクラスを使うことにします。同様の理由で多重の入れ子構造も利用しません。

BAD

#what-a-strong-selector {
  ...
}

BAD

.wrapper {
  .wrapper-inner {
    .module {
      .module-inner {
        ...
      }
    }
  }
}

ファイル構造

CSSのファイル構造は以下のようにします。

ベース、モジュールとレイアウトをそれぞれフォルダに分け、モジュー
ル、レイアウトそれぞれの名前でSCSSファイルを作成してください。

app.scssは各ファイルをimportするためのファイルです。それ以外のすべてのファイルは、_(アンダースコア)から始まるファイル名をつけた上でapp.scssからインポートするようにしてください。

また、変数は_settings.scssにまとめて記述します。

.
├── README.md
├── _settings.scss
├── app.scss
├── base
│   ├── _main.scss
│   └── _util.scss
├── layout
│   ├── _chat.scss
│   ├── _contacts.scss
│   ├── _footer.scss
│   ├── _navbar.scss
│   └── _signin.scss
└── module
    ├── _chat.scss
    ├── _contacts.scss
    ├── _dropdown.scss
    ├── _footer.scss
    ├── _modal.scss
    ├── _navbar.scss
    └── _signin.scss

コーディングスタイル

CSSのインデントは半角スペース2文字とします。タブは利用しないでください。

セレクタと{(ブレース)の間、プロパティの:(コロン)の後には1文字のスペースを入れます。値の末尾は必ず;(セミコロン)で終わってください。ブレースの終わりは必ず改行しましょう。

プロパティの記述順序はCSS2 Specificationの順序で書くと良いでしょう。(参考)
mixinなどは先頭にまとめると見やすくなります。

(ほかにはMoziilaのスタイルに合わせたプロパティ順序などがよく使われます。)

.layout-signin {
  @include grid-row();
  padding-top: 100px;

  h1 {
    margin: 0 auto;
    width: 200px;
    height: 108px;
  }
}

ドキュメントとコメントアウト

CSSのドキュメントはStyleDoccoを利用して作成されています。ドキュメント化しないコメントアウトは先頭に半角スペースを入れてください。

// ドキュメント化されるコメント
 // ドキュメント化されないコメント(先頭に半角スペース)

命名規則

基本ルール

CSSのクラスはモジュール化を意識した命名規則に従ってクラス名をつけます。単語間はハイフン区切りでつなぎます。

BEMのような記法や_(アンダースコア)、キャメルケースを利用することも良いのですが、ハイフンとの使い分けに悩むことが多いのですべてハイフン区切りで置いています。

モジュールの再利用性を意識するため、階層構造のコンテキストに依存しないように命名・定義をすると良いでしょう。

GOOD

HTML

<div class="message">
  <img src="user.png" alt="User Name" class="message-icon">
  <strong class="message-name">User Name</strong>
  <div class="message-content">
    <p>再利用性を意識した命名規則。</p>
  </div>
</div>

SCSS

.message {
  ...
}
.message-icon {
  ...
}
.message-name {
  ...
}
.message-content {
  ...
}

BAD

HTML

<div class="message">
  <img src="user.png" alt="User Name" class="icon">
  <strong class="name">User Name</strong>
  <div class="content">
    <p>再利用性を意識した命名規則。</p>
  </div>
</div>

SCSS

.message {
  .icon {
    ...
  }
  .name {
    ...
  }
  .content {
    ...
  }
}

この場合、.message全体で一つのモジュールである、という捉え方もできますが、.icon.nameなど、モジュール名と関連のない汎用的なクラス名が使われてしまうことが好ましくありません。

レイアウトの命名

レイアウトはモジュール名にlayout-のプレフィクスをつけたものを利用します。

HTML

<div class="signin-box layout-signin-box">
    <h2>アカウント登録</h2>
    <p>会社のメールアドレスを入力してください</p>
</div>

SCSS

.layout-signin-box {
  @include grid-column($columns:6, $center:true); // Foundation 由来の mixin
  margin-top: 20px;
}
.signin-box {
  box-shadow: #ddd 0 0 2px 0;
  padding-top: 20px;
  padding-bottom: 20px;
  background: #fff;
  text-align: center;

  h2 {
    margin: 1.5em;
    color: #1B4F6F;
    font-size: 1.8rem;
    font-weight: normal;
  }

  p {
    font-size: 1.6rem;
  }
}

状態の命名

状態(state)を表すものはis-has-のプレフィクスをつけたクラスを利用します。

<div class="layout-chat has-nav">
    <div class="chat-channel layout-chat-channel">
    ...
    </div>
</div>


また、それ自体がモジュールとできるものは、サフィックスをつけたモジュールとするのも良いでしょう。
(この考え方はBEMのModifierの考え方によく似ています。)

以下の例では、div要素に対してAngularJSが動的にクラス名(message-content-[modifier])を付与します。

<div class="message-content" ng-switch on="msg.kind" ng-class="'message-content-'+msg.kind">
    <p ng-switch-when="text">これはテキストです。</p>
    <img src="stamp.png" ng-switch-when="stamp">
    <video ng-src="video.mp4" ng-switch-when="movie">
</div>