CSS (Sass) のコーディングルール #CSS #Sass version 10

2016/03/17 02:54 by zk33 zk33
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
#HTMLCSS #SCSS / #SASS の #コーディングルール
2016/3月現在の私的(あるいはテンマド社の)HTMLとCSS/SCSSコーディングについてのルール
2016/3月現在の私的(あるいはテンマド社の)CSS/SCSSコーディングについてのルールです。

# 目指すこと

* 開発時に「迷う」「考える」部分を極力減らしつつ、できるだけ一貫したCSSを書けるようにする
* 覚えるべきことは必要最小限に
* 開発時に「迷う」「考える」部分を極力減らしつつ、できるだけ一貫した、メンテナンスしやすいCSSを書けるようにする
* 覚えるべきことは必要最小限にする

# 前提

### ◎ SASSではなく、SCSSの記法を使
### ◎ Sassを使って書く

素のCSSを使うような苦行は避けます。

ほとんど好みの問題ですが、Lessは記法がちょっとよくないので、Sassを使います。
処理速度やツールセットの関係で、本家RubyのSassではなく、node-sassのほうをgulpで走らせて使います。

### ◎ Autoprefixerなどを活用

vendor-prefix対策などは、Compass等のSassライブラリでやるのではなく、AutoprefixerなどPostCSS方面のものを使います。

### ◎ SASS記法ではなく、SCSSのほうを使う

SASSの記法(HAMLっぽいやつ)は使わず、SCSS(よりCSSっぽい記法)のほうを使います。

単純に学習コストが低いことと、
JSライブラリ付属のCSSやネットで公開されているコードなどを取り込む時もコピペでとり込んだりしやすいからです。
単純に学習コストが低いことと、JSライブラリ付属のCSSやネットで公開されているコードなどを取り込む時もコピペでとり込んだりしやすいからです。

# 命名規則
# コーディングルールと命名規則

## ◎ すべてクラスに対してスタイル指定し、IDで指定はしない

```scss:BAD  
#main {
  color:red;
}
#main ul{
  color:green;
}
```
```scss:GOOD 
.main{
  color:red;
}
.main-list{
  color:green;
}
```
ID指定でスタイルを書くことはしません。全てクラスで指定します。

IDは詳細度(selector's specificity)が高すぎて、他の場所でカスケードしてスタイルを上書きしようとした時`!important`を多発しなくてはいけなくなったり、あれこれと障害になるためです。


## ◎ 初期化/リセット的なことをする部分以外で、タグに対してスタイル指定せず、クラスで指定する

```scss:BAD  
.some-class ul{
  color:red;
}
ul.some-class li{
  color:red;
}
```
```scss:GOOD 
.some-class-list{
  color:red;
}
some-class-list-item{
.some-class-list-item{
  color:red;
}
```

タグ名でスタイル指定はせず、面倒でも全部クラスを割り振ります。
リセット/初期化する部分を除いて、タグ名で、あるいはタグ名を含めたスタイル指定は一切せず、面倒でも全部クラスを割り振り、クラスに対していスタイル指定をします。

タグの構造は制作していく途中JSとの兼ね合いで変えることがよくあるので、その際に書き換える手間を減らし、HTML構造とCSSによるスタイリングを極力分離しておくためです。
タグの構造は制作していく上の都合やJSとの兼ね合いで変えることがよくあるので、その際に書き換える手間を減らし、HTML構造とCSSによるスタイリングを極力分離しておくためです。

例外として、たとえばMarkdownパーサが出力するHTMLなど、クラスの割り当てられない部分で、かつタグにスタイルを指定するのが妥当な部分は除きます。

## ◎ クラス名はハイフン区切りで全て小文字

```scss:BAD  
.snakecase_class{
  color:red;
}
.camelCaseClass{
  color:red;
}
.Has-Capital-CLASS{
  color:red;
}
```
```scss:GOOD 
.good-class-definition{
  color:red;
}
```

大文字小文字を両方使っ書く前提にると必ず大文字小文字のタイプミスでスタイルが当たらなくてうんうん悩む時間が発生す、基本的に大文字は一切使いませんクラス名は小文字+ハイフン区切り基本とします。
シフトキー押さなくいいので楽で、大文字小文字のタイプミスでスタイルが当たらなくてうんうん悩む事も減から
例外として、Angularアプリを書いていてdirective名とCSSの接頭辞を合わせたい、などの理由接頭辞部分(一番先頭の部分)に限り、camelCaseを使ったりするのはアリです。
例外として、Angularアプリを書いていてdirective名とCSSの接頭辞を合わせたい、CSS増えすぎて小文字だけだとつらい、などの理由がある時に、接頭辞部分(一番先頭の部分)に限り、camelCaseを使ったりするのはアリです。

## ◎ グローバルなクラスは`.g-`で始める

## ◎ クラスのネストは2段階まで、を基本とする

* `.g-`で始まる「グローバルなクラス」
* 同一ファイル内にある、同じ接頭辞のクラス

のみネストして上書きできます。

それ以外のネストは基本的に禁止です。
こうすることで

* `.g-`のクラスは、変更するとサイト全体のいろんなところに影響が出るので慎重に変更が必要だとわかりやすくなります
* それ以外のクラスは、同一ファイル内にあるものだけ考えればよいので、確認の必要な範囲が最小限で済みます
* `.g-`のクラスは、グローバルなクラスなので、変更するとサイト全体のいろんなところに影響が出るため、慎重に変更が必要だということがわかりやすくなります
* それ以外のクラスは、同一ファイル内にあるものだけ考えればよいので、確認の必要な範囲が最小限で済み、変更が気軽にできるようになります

## ◎ `@keyframe`のアニメーション名などの接頭辞もファイル名に合わせる

とにかく名前を付ける必要のあるものは、接頭辞とファイル名を一致させます。

# ファイル分け

## ◎ 基本的なディレクトリ構造

## ◎ クラス名の接頭辞と、そのクラスの書かれたファイル名を一致させる

どのクラスがどのファイルに書かれているか、が瞬時にわかるようになります。
sourcemapなどにる必要が発生したら負けで
* どのクラスがどのファイルに書かれているか、が瞬時にわかるようになりsourcemapのようものがほとん要らなくなります。
* 他のファイル同名のクラスやアニメーション名、変数名などが存在していのではないか、という心配をする必要がなくなりま
なお、

* `_x.scss`(あるいは_x-hoge.scss)
* `_mode.scss`(あるいは_mode-hoge.scss)

は後述のJavascriptとの連携に関わる予約語的なものなので、作成禁止です。

## ◎ ファイルが大きくなった場合は、接頭辞の前の部分をベースにディレクトリ化する


# Javascriptとの連携

## ◎ JSから使うクラスは「.x-」で始め、CSS側でそのクラスは絶対に使わない
## ◎ Javascriptから使うクラスは「.x-」で始め、CSS側でそのクラスは絶対に使わない

JS使っているクラスなので変更に注意が必、ということを明示するために特別なクラスを指定します。
また、JSでのDOM操作と、CSSでスタイル指定はでかぎり切り離ておいたほうがよいで、「.x-」のついたクラスに対してスタイルをること絶対にしなようにし後述の「.mode-」のついたクラスでコントロールします。
Javascriptで要取得やDOM操作のために使うclass、全て「.x-」始めように、この「.x-」で始まるクラスに対してはCSSでスタイル指定ては**せん**
「.x-」をつけるのは、HTML上で、この要素はJavascriptで操作に使っているので変更に注意が必要、ということを明示するためです。
一方で、JavascriptでのDOM操作と、CSSでのスタイル指定はできるかぎり切り離しておいたほうがよいので、「.x-」のついたクラスに対してスタイルを当てることは絶対にしないようにします。

JavascriptとCSSの連携については、後述の「.mode-」のついたクラスでコントロールします。

## ◎ JSで使うIDは「x」で始めたcamelCaseとし、CSS側でそのIDは絶対に使わない

jsでのDOM操作のためにIDを割り当てる場合は`id="xSomeElement"`というようにxから始まるcamelCaseで指定します。
CSS側ではこのIDに対してスタイルを当てるようなことはしてはいけません(まあ、そもそもIDは使ってはいけないのですが…)

## ◎ JSとCSSで連携する場合は`.mode-`というクラスを通して行う

要素のアニメーションなどはできる限りCSSのtransitionやanimationで行います。

その際、JS側では`.mode-`と頭についたクラスの追加と削除のみを行い、CSS側ではその`.mode-`と頭についたクラスを使ってアニメーション


# SASS
# Sass

## ◎ SASSの変数名はスネークケースで書く
## ◎ Sassの変数名はスネークケースで書く

ハイフンは使わず、`$some_sass_vars`といったような、アンダースコア区切り+小文字のスネークケースで変数を定義します。

```scss:BAD 
$base-margin: 12px;
$basePadding: 12px;
```

```scss:BAD 
$base-margin: 12px;
$baseMargin: 12px;
```


クラス名と区別をつけやすくすることと、SASSだと「-」が演算子としても機能するので、それとの区別をつけて意図しない演算などを防ぐためです。

## ◎ SASSの変数名も、ファイル名と一致させる

変数名は、ファイル名と同じ接頭辞で始めます。

```scss:_header.scss
/* GOOD */
$header_color: #999;

/* BAD */
$color_of_header: #999;
```

唯一の例外として、下記のとおり「$g_」で始まるものだけルールが違います

## ◎ SASSのグローバル変数は`_vars.scss`に書き、`$g_`で始める

```scss:_vars.scss
/* _vars.scssにグローバル変数をまとめておく */

$g_color_border: #999;
$g_color_text: #333;

$g_radius: 5px;
$g_header_height: 30px;

...
```


※ まあ別に`$vars_`とかでもいいんだけどね。。

## ◎ `@extend`は出来る限り避ける

`@extend`は、extend元のスタイルを変更した時に影響する範囲が見えず、意図しない部分に影響が出たりするのでできる限り避けます。

代わりに、

* 同じスタイルならできるだけ同じクラス名を割り振る
* 似たスタイルならクラスを複数振って上書きして調整する
* extendsしたいようなクラスは`.g-`のクラスとして定義して、ネストさせる

のを推奨です。

`@extend`を活用したSASSライブラリなどを使う場合は除きます。

## ◎ レスポンシブ対応はmixinで行う

ここはまだ練ってるところです。
今のところ以下のようなコードでやってます。

```scss:_mixins.scss
```

※もっとスマートにわかりやすく書ける方法があれば知りたい

# その他

## BEMなどを使わない理由

BEMは、画面設計がしっかりできていて、CSSの設計に時間がかけられる場合はよいですが、だいたい自分の作るようなものは日々変化の多いものなので、

* ルールとしてやや複雑すぎる
* っていうかどれがBlockでどれがElementでどれがModifierだとかあれこれ余計な事を考えたくない
* 一つのモジュールのつもりで書いていたものの中のパーツをモジュールとして切り出したくなるとかいった変更をしたくなった時にストレス

といった理由で採用していません。      

2016/3月現在の私的(あるいはテンマド社の)CSS/SCSSコーディングについてのルールです。

目指すこと

  • 開発時に「迷う」「考える」部分を極力減らしつつ、できるだけ一貫した、メンテナンスしやすいCSSを書けるようにする
  • 覚えるべきことは必要最小限にする

前提

◎ Sassを使って書く

素のCSSを使うような苦行は避けます。

ほとんど好みの問題ですが、Lessは記法がちょっとよくないので、Sassを使います。
処理速度やツールセットの関係で、本家RubyのSassではなく、node-sassのほうをgulpで走らせて使います。

◎ Autoprefixerなどを活用

vendor-prefix対策などは、Compass等のSassライブラリでやるのではなく、AutoprefixerなどPostCSS方面のものを使います。

◎ SASS記法ではなく、SCSSのほうを使う

SASSの記法(HAMLっぽいやつ)は使わず、SCSS(よりCSSっぽい記法)のほうを使います。

単純に学習コストが低いことと、JSライブラリ付属のCSSやネットで公開されているコードなどを取り込む時もコピペでとり込んだりしやすいからです。

コーディングルールと命名規則

◎ すべてクラスに対してスタイル指定し、IDで指定はしない

#main {
  color:red;
}
#main ul{
  color:green;
}
BAD
.main{
  color:red;
}
.main-list{
  color:green;
}
GOOD

ID指定でスタイルを書くことはしません。全てクラスで指定します。

IDは詳細度(selector's specificity)が高すぎて、他の場所でカスケードしてスタイルを上書きしようとした時!importantを多発しなくてはいけなくなったり、あれこれと障害になるためです。

◎ 初期化/リセット的なことをする部分以外で、タグに対してスタイル指定せず、クラスで指定する

.some-class ul{
  color:red;
}
ul.some-class li{
  color:red;
}
BAD
.some-class-list{
  color:red;
}
.some-class-list-item{
  color:red;
}
GOOD

リセット/初期化する部分を除いて、タグ名で、あるいはタグ名を含めたスタイル指定は一切せず、面倒でも全部クラスを割り振り、クラスに対していスタイル指定をします。

タグの構造は、制作していく上の都合やJSとの兼ね合いで変えることがよくあるので、その際に書き換える手間を減らし、HTML構造とCSSによるスタイリングを極力分離しておくためです。

例外として、たとえばMarkdownパーサが出力するHTMLなど、クラスの割り当てられない部分で、かつタグにスタイルを指定するのが妥当な部分は除きます。

◎ クラス名はハイフン区切りで全て小文字

.snakecase_class{
  color:red;
}
.camelCaseClass{
  color:red;
}
.Has-Capital-CLASS{
  color:red;
}
BAD
.good-class-definition{
  color:red;
}
GOOD

クラス名は小文字+ハイフン区切りを基本とします。
シフトキー押さなくていいので楽ですし、大文字小文字のタイプミスでスタイルが当たらなくてうんうん悩む事も減るからです。

例外として、Angularアプリを書いていてdirective名とCSSの接頭辞を合わせたい、CSS増えすぎて小文字だけだとつらい、などの理由がある時に、接頭辞部分(一番先頭の部分)に限り、camelCaseを使ったりするのはアリです。

◎ グローバルなクラスは.g-で始める

◎ クラスのネストは2段階まで、を基本とする

  • .g-で始まる「グローバルなクラス」
  • 同一ファイル内にある、同じ接頭辞のクラス

のみネストして上書きできます。

それ以外のネストは基本的に禁止です。
こうすることで

  • .g-のクラスは、グローバルなクラスなので、変更するとサイト全体のいろんなところに影響が出るため、慎重に変更が必要だということがわかりやすくなります
  • それ以外のクラスは、同一ファイル内にあるものだけ考えればよいので、確認の必要な範囲が最小限で済み、変更が気軽にできるようになります

@keyframeのアニメーション名などの接頭辞もファイル名に合わせる

とにかく名前を付ける必要のあるものは、接頭辞とファイル名を一致させます。

ファイル分け

◎ 基本的なディレクトリ構造

◎ クラス名の接頭辞と、そのクラスの書かれたファイル名を一致させる

  • どのクラスがどのファイルに書かれているか、が瞬時にわかるようになり、sourcemapのようなものがほとんど要らなくなります。
  • 他のファイルに同名のクラスやアニメーション名、変数名などが存在しているのではないか、という心配をする必要がなくなります

なお、

  • _x.scss(あるいは_x-hoge.scss)
  • _mode.scss(あるいは_mode-hoge.scss)

は後述のJavascriptとの連携に関わる予約語的なものなので、作成禁止です。

◎ ファイルが大きくなった場合は、接頭辞の前の部分をベースにディレクトリ化する

Javascriptとの連携

◎ Javascriptから使うクラスは「.x-」で始め、CSS側でそのクラスは絶対に使わない

Javascriptで要素の取得やDOM操作のために使うclassは、全て「.x-」で始めるようにし、この「.x-」で始まるクラスに対してはCSSでスタイル指定をしてはいけません

「.x-」をつけるのは、HTML上で、この要素はJavascriptで操作に使っているので変更に注意が必要、ということを明示するためです。
一方で、JavascriptでのDOM操作と、CSSでのスタイル指定はできるかぎり切り離しておいたほうがよいので、「.x-」のついたクラスに対してスタイルを当てることは絶対にしないようにします。

JavascriptとCSSの連携については、後述の「.mode-」のついたクラスでコントロールします。

◎ JSで使うIDは「x」で始めたcamelCaseとし、CSS側でそのIDは絶対に使わない

jsでのDOM操作のためにIDを割り当てる場合はid="xSomeElement"というようにxから始まるcamelCaseで指定します。
CSS側ではこのIDに対してスタイルを当てるようなことはしてはいけません(まあ、そもそもIDは使ってはいけないのですが…)

◎ JSとCSSで連携する場合は.mode-というクラスを通して行う

要素のアニメーションなどはできる限りCSSのtransitionやanimationで行います。

その際、JS側では.mode-と頭についたクラスの追加と削除のみを行い、CSS側ではその.mode-と頭についたクラスを使ってアニメーション

Sass

◎ Sassの変数名はスネークケースで書く

ハイフンは使わず、$some_sass_varsといったような、アンダースコア区切り+小文字のスネークケースで変数を定義します。

$base-margin: 12px;
$basePadding: 12px;
BAD
$base-margin: 12px;
$baseMargin: 12px;
BAD

クラス名と区別をつけやすくすることと、SASSだと「-」が演算子としても機能するので、それとの区別をつけて意図しない演算などを防ぐためです。

◎ SASSの変数名も、ファイル名と一致させる

変数名は、ファイル名と同じ接頭辞で始めます。

/* GOOD */
$header_color: #999;

/* BAD */
$color_of_header: #999;
_header.scss

唯一の例外として、下記のとおり「$g_」で始まるものだけルールが違います

◎ SASSのグローバル変数は_vars.scssに書き、$g_で始める

/* _vars.scssにグローバル変数をまとめておく */

$g_color_border: #999;
$g_color_text: #333;

$g_radius: 5px;
$g_header_height: 30px;

...
_vars.scss

※ まあ別に$vars_とかでもいいんだけどね。。

@extendは出来る限り避ける

@extendは、extend元のスタイルを変更した時に影響する範囲が見えず、意図しない部分に影響が出たりするのでできる限り避けます。

代わりに、

  • 同じスタイルならできるだけ同じクラス名を割り振る
  • 似たスタイルならクラスを複数振って上書きして調整する
  • extendsしたいようなクラスは.g-のクラスとして定義して、ネストさせる

のを推奨です。

@extendを活用したSASSライブラリなどを使う場合は除きます。

◎ レスポンシブ対応はmixinで行う

ここはまだ練ってるところです。
今のところ以下のようなコードでやってます。

_mixins.scss

※もっとスマートにわかりやすく書ける方法があれば知りたい

その他

BEMなどを使わない理由

BEMは、画面設計がしっかりできていて、CSSの設計に時間がかけられる場合はよいですが、だいたい自分の作るようなものは日々変化の多いものなので、

  • ルールとしてやや複雑すぎる
  • っていうかどれがBlockでどれがElementでどれがModifierだとかあれこれ余計な事を考えたくない
  • 一つのモジュールのつもりで書いていたものの中のパーツをモジュールとして切り出したくなるとかいった変更をしたくなった時にストレス

といった理由で採用していません。