CSS (Sass) のコーディングルール #CSS #Sass version 6
#HTML #SCSS / #SASS の #コーディングルール
2016/3月現在の個人的(あるいはテンマド社の)CSS/SCSSコーディングについてのルール
# 目指すこと
* 開発時に「迷う」「考える」部分を極力減らしつつ、できるだけ一貫したCSSを書けるようにする
* 覚えるべきことを必要最小限にする
# 前提
### ◎ SASSではなく、SCSSの記法を使う
SASSの記法(HAMLっぽいやつ)は使わず、SCSS(より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{
color:red;
}
```
タグ名でスタイル指定はせず、面倒でも全部クラスを割り振ります。
タグの構造は制作していく途中や、JSとの兼ね合いで変えることがよくあるので、その際に書き換える手間を減らし、HTML構造とCSSによるスタイリングを極力分離しておくためです。
例外として、たとえばMarkdownパーサが出力するHTMLなど、クラスの割り当てられない部分で、かつタグにスタイルを指定するのが妥当な部分は除きます。
## ◎ クラス名はハイフン区切りで全て小文字
```scss:BAD
.snakecase_class{
color:red;
}
.camelCaseClass{
color:red;
}
.Capital-CLASS{
color:red;
}
```
```scss:GOOD
.good-class-definition{
color:red;
}
```
大文字小文字を両方使って書く前提にすると、必ず大文字小文字のタイプミスでスタイルが当たらなくてうんうん悩む時間が発生するので、基本的に大文字は一切使いません。
例外として、Angularのアプリを書いていてdirective名とCSSの接頭辞を合わせたい、などの理由で接頭辞のみcamelCaseを使ったりするのはアリです。
例外として、Angularアプリを書いていてdirective名とCSSの接頭辞を合わせたい、などの理由で接頭辞のみcamelCaseを使ったりするのはアリです。
## ◎ グローバルなクラスは`.g-`で始める
## ◎ クラスのネストは2段階まで、を基本とする
* `.g-`で始まる「グローバルなクラス」
* 同一ファイル内にある、同じ接頭辞のクラス
のみネストして上書きできます。
それ以外のネストは基本的に禁止です。
こうすることで
* `.g-`のクラスは、変更するとサイト全体のいろんなところに影響が出るので慎重に変更が必要だとわかりやすくなります
* それ以外のクラスは、同一ファイル内にあるものだけ考えればよいので、確認の必要な範囲が最小限で済みます
# ファイル分け
## ◎ 基本的なディレクトリ構造
## ◎ クラス名の接頭辞と、そのクラスの書かれたファイル名を一致させる
どのクラスがどのファイルに書かれているか、が瞬時にわかるようになります。
sourcemapなどに頼る必要が発生したら負けです。
なお、
* `_x.scss`(あるいは_x-hoge.scss)
* `_mode.scss`(あるいは_mode-hoge.scss)
は後述のJavascriptとの連携に関わる予約語的なものなので、作成禁止です。
## ◎ ファイルが大きくなった場合は、接頭辞の前の部分をベースにディレクトリ化する
# Javascriptとの連携
## ◎ JSから使うクラスは「.x-」で始め、CSS側でそのクラスは絶対に使わない
JSで使っているクラスなので変更に注意が必要、ということを明示するために特別なクラスを指定します。
また、JSでのDOM操作と、CSSでのスタイル指定はできるかぎり切り離しておいたほうがよいので、「.x-」のついたクラスに対してスタイルを当てることは絶対にしないようにします。
後述の「.mode-」のついたクラスでコントロールします。
## ◎ JSで使うIDは「x」で始めたcamelCaseとし、CSS側でそのIDは絶対に使わない
jsでのDOM操作のためにIDを割り当てる場合は`id="xSomeElement"`というようにxから始まるcamelCaseで指定します。
CSS側ではこのIDに対してスタイルを当てるようなことはしてはいけません。
## ◎ JSとCSSで連携する場合は`.mode-`というクラスを通して行う
要素のアニメーションなどはできる限りCSSのtransitionやanimationで行います。
その際、JS側では`.mode-`と頭についたクラスの追加と削除のみを行い、CSS側ではその`.mode-`と頭についたクラスを使ってアニメーション
# SASS
## ◎ SASSの変数名はスネークケースで書く
SASSだと「-」が演算子としても機能するので、それとの区別をつけるため、ハイフンは使いません。
## ◎ SASSの変数名も、ファイル名と一致させる
唯一の例外として、下記のとおり「$g_」で始まるものだけルールが違います
## ◎ SASSのグローバル変数は「_vars.scss」に書き、「$g_」で始める
## ◎ レスポンシブ対応をmixinで行う
今のところ以下のようなコードでやる方向です。
今のところ以下のようなコードでやってます。
```scss:_mixins.scss
```
※もっとスマートにわかりやすく書ける方法があれば知りたい
## ◎ `@extend`は出来る限り避ける
`@extend`は、extend元のスタイルを変更した時に影響する範囲が見えず、意図しない不具合が発生しがちなのでできる限り避けます。
`@extend`は、extend元のスタイルを変更した時に影響する範囲が見えず、意図しない部分に影響が出たりするのでできる限り避けます。
代わりに、
* 同じスタイルならできるだけ同じクラス名を割り振る
* 似たスタイルならクラスを複数振って上書きして調整する
* extendsしたいようなクラスは`.g-`のクラスとして定義して、ネストさせる
のを推奨です。
`@extend`を活用したSASSライブラリなどを使う場合は除きます。
# その他
## BEMなどを使わない理由
BEMは、画面設計がしっかりできていて、CSSの設計に時間がかけられる場合はよいですが、だいたい自分の作るようなものは日々変化の多いものなので、
* ルールとしてやや複雑すぎる
* っていうかどれがBlockでどれがElementでどれがModifierだとかあれこれ余計な事を考えたくない
* 一つのモジュールのつもりで書いていたものの中のパーツをモジュールとして切り出したくなるとかいった変更をしたくなった時にストレス
といった理由で採用していません。
2016/3月現在の個人的(あるいはテンマド社の)CSS/SCSSコーディングについてのルール
目指すこと
- 開発時に「迷う」「考える」部分を極力減らしつつ、できるだけ一貫したCSSを書けるようにする
- 覚えるべきことを必要最小限にする
前提
◎ SASSではなく、SCSSの記法を使う
SASSの記法(HAMLっぽいやつ)は使わず、SCSS(よりCSSっぽい記法)のほうを使います。
単純に学習コストが低いことと、
JSライブラリ付属のCSSやネットで公開されているコードなどを取り込む時もコピペでとり込んだりしやすいからです。
命名規則
◎ IDを使用しない
#main {
color:red;
}
#main ul{
color:green;
}
BAD.main{
color:red;
}
.main-list{
color:green;
}
GOODID指定でスタイルを書くことはしません。
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;
}
.Capital-CLASS{
color:red;
}
BAD.good-class-definition{
color:red;
}
GOOD大文字小文字を両方使って書く前提にすると、必ず大文字小文字のタイプミスでスタイルが当たらなくてうんうん悩む時間が発生するので、基本的に大文字は一切使いません。
例外として、Angularアプリを書いていてdirective名とCSSの接頭辞を合わせたい、などの理由で接頭辞のみcamelCaseを使ったりするのはアリです。
◎ グローバルなクラスは.g-
で始める
◎ クラスのネストは2段階まで、を基本とする
.g-
で始まる「グローバルなクラス」- 同一ファイル内にある、同じ接頭辞のクラス
のみネストして上書きできます。
それ以外のネストは基本的に禁止です。
こうすることで
.g-
のクラスは、変更するとサイト全体のいろんなところに影響が出るので慎重に変更が必要だとわかりやすくなります- それ以外のクラスは、同一ファイル内にあるものだけ考えればよいので、確認の必要な範囲が最小限で済みます
ファイル分け
◎ 基本的なディレクトリ構造
◎ クラス名の接頭辞と、そのクラスの書かれたファイル名を一致させる
どのクラスがどのファイルに書かれているか、が瞬時にわかるようになります。
sourcemapなどに頼る必要が発生したら負けです。
なお、
_x.scss
(あるいは_x-hoge.scss)_mode.scss
(あるいは_mode-hoge.scss)
は後述のJavascriptとの連携に関わる予約語的なものなので、作成禁止です。
◎ ファイルが大きくなった場合は、接頭辞の前の部分をベースにディレクトリ化する
Javascriptとの連携
◎ JSから使うクラスは「.x-」で始め、CSS側でそのクラスは絶対に使わない
JSで使っているクラスなので変更に注意が必要、ということを明示するために特別なクラスを指定します。
また、JSでのDOM操作と、CSSでのスタイル指定はできるかぎり切り離しておいたほうがよいので、「.x-」のついたクラスに対してスタイルを当てることは絶対にしないようにします。
後述の「.mode-」のついたクラスでコントロールします。
◎ JSで使うIDは「x」で始めたcamelCaseとし、CSS側でそのIDは絶対に使わない
jsでのDOM操作のためにIDを割り当てる場合はid="xSomeElement"
というようにxから始まるcamelCaseで指定します。
CSS側ではこのIDに対してスタイルを当てるようなことはしてはいけません。
◎ JSとCSSで連携する場合は.mode-
というクラスを通して行う
要素のアニメーションなどはできる限りCSSのtransitionやanimationで行います。
その際、JS側では.mode-
と頭についたクラスの追加と削除のみを行い、CSS側ではその.mode-
と頭についたクラスを使ってアニメーション
SASS
◎ SASSの変数名はスネークケースで書く
SASSだと「-」が演算子としても機能するので、それとの区別をつけるため、ハイフンは使いません。
◎ SASSの変数名も、ファイル名と一致させる
唯一の例外として、下記のとおり「$g_」で始まるものだけルールが違います
◎ SASSのグローバル変数は「vars.scss」に書き、「$g」で始める
◎ レスポンシブ対応をmixinで行う
今のところ以下のようなコードでやってます。
_mixins.scss※もっとスマートにわかりやすく書ける方法があれば知りたい
◎ @extend
は出来る限り避ける
@extend
は、extend元のスタイルを変更した時に影響する範囲が見えず、意図しない部分に影響が出たりするのでできる限り避けます。
代わりに、
- 同じスタイルならできるだけ同じクラス名を割り振る
- 似たスタイルならクラスを複数振って上書きして調整する
- extendsしたいようなクラスは
.g-
のクラスとして定義して、ネストさせる
のを推奨です。
@extend
を活用したSASSライブラリなどを使う場合は除きます。
その他
BEMなどを使わない理由
BEMは、画面設計がしっかりできていて、CSSの設計に時間がかけられる場合はよいですが、だいたい自分の作るようなものは日々変化の多いものなので、
- ルールとしてやや複雑すぎる
- っていうかどれがBlockでどれがElementでどれがModifierだとかあれこれ余計な事を考えたくない
- 一つのモジュールのつもりで書いていたものの中のパーツをモジュールとして切り出したくなるとかいった変更をしたくなった時にストレス
といった理由で採用していません。