Full Code of manabuyasuda/styleguide for AI

master bd4acfd0d091 cached
10 files
110.1 KB
54.8k tokens
1 requests
Download .txt
Showing preview only (206K chars total). Download the full file or copy to clipboard to get everything.
Repository: manabuyasuda/styleguide
Branch: master
Commit: bd4acfd0d091
Files: 10
Total size: 110.1 KB

Directory structure:
gitextract_j70as5z8/

├── .gitignore
├── LICENSE
├── README.md
├── css-class-name-list.md
├── css-coding-rule.md
├── css-styleguide.md
├── how-to-bem.md
├── how-to-ecss.md
├── image-naming-rule.md
└── svg-operating-rules.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.git

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015 Manabu Yasuda

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README.md
================================================
# styleguide
リポジトリを変更してガイドラインを整理しました。
[coding-guidelines](https://github.com/manabuyasuda/coding-guidelines)


================================================
FILE: css-class-name-list.md
================================================
# CSS クラス名リスト
名前をつけることは難しいですが、とても重要なことです。

CSSには設計思想が必要ですが、実践するにあたり、名前と機能の意味がとおり、名前のつけ方にブレがないようにするべきです。

このドキュメントでは、CSSでよく使われる単語を分類し、意味や機能を短くまとめています。  
ただし、見た目やUIの機能をクラス名にするのではなく、デザインの意図やそのコンポーネントの役割をクラス名にすることを推奨します。

## 場所

- `section` - 区分・区画。
- `content` - 文書の内容。
- `article` - 記事。
- `post` - 投稿。
- `top` - 頂上・上部。
- `home`- トップページ。
- `sidebar` - 補足記事。

## 比較

- `main` - 主要な。
- `primary` - 主要な。
- `secondary` - 補助的な・第二の。
- `tertiary` - 第三の。
- `quaternary` - 第四の。
- `common` - 共通の。
- `global` - 全体的な。
- `local` - 局所的な。
- `general` - 一般的な。

## 補足

- `wrapper` - 内包する。
  - `wrap` - `wrapper`の略語。
  - `container` - `wrapper`の類語。容器・入れ物。
- `group` - 集まり。
- `area` - 特定の場所・範囲。
- `brand` - ブランドの。
- `site` - サイトの。
- `emphasis` - 強調・重視。
- `catch` - 興味を惹く・関心をつかむ。
- `note` - 注釈。
- `description` - 概要。
  - `desc` - `description`の略語。
- `introduction` - 前置き・導入。
  - `intro` - `introduction`の略語。
- `announce` - お知らせ。
- `information` - 情報。
  - `info` - `information`の略語。
- `action` - Call To Action。重要度の高い。
- `success` - 成功。
- `alert` - 注意・警戒。
- `attention` - 配慮・気配り。
- `error` - 間違い・失敗。
- `caution` - 用心・警告。
- `warning` - 警告・予告。
- `danger` - 危険・驚異。
- `more` - もっと多くの。
- `feature` - 主要なもの。
- `detail` - 詳細・細部。
- `summary` - 概要・要約。

## コンテンツ

- `about` - 〜について。
- `work` - 仕事・任務。
- `product` - 製品。
- `service` - サービス。
- `news` - お知らせ・近況。
- `event` - 行事・出来事。
- `history` - 歴史・沿革。
- `archive` - 保存・保管・記録。
- `concept` - 構想・概念・考え。
- `recommend` - おすすめ・推奨。
- `table of contents` - 目次。
  - `toc` - `Table of contents`の略語。
- `index` - 索引・指標。
- `contact` - 問い合わせ・連絡。
- `inquiry` - 問い合わせ・質問・調査。
- `access` - 交通手段。
- `shop` - 店舗。
- `related` - 関連のある。
- `privacy` - 個人情報の利用・保護の方針。
- `qanda` - Question and answer(質問と回答)の略。
  - `faq` - `qanda`の類語、Frequently asked questions(よくある質問)の略。

## レイアウトパターン

- `wrapper` - 複数の要素を内包する。
- `grid` - グリッドレイアウト。
- `block` - 縦に積まれる。
- `inline` - 横一列に並ぶ。
- `media` - テキストと画像の横並び。
- `flag` - テキストと画像の横並び(垂直方向の指定可能)。
- `box` - 箱状の。
- `card` - (主に)画像を目立たせるカード型。
- `tile` - 繰り返しによって構成されるパターン。

## UI

### Text

- `link` - アンカーテキスト。
- `label` - 分類する・項目名。
- `tag` - 符号・識別子。
- `badge` - 残数を示す数値。
- `copyright` - 著作権表示。
- `dialog` - (主に)注意や警告を知らせるために使用されるメッセージで、ユーザーに操作を要求するのが特徴。
  - `toast` - `dialog`の類語で、`dialog`との違いは時間が経つと自動的に消えること。
- `tooltip` - マウスオーバー時に補足情報を表示するインターフェイス。
- `button` - オン・オフの選択に使うインターフェイス。
  - `btn` - `button`の略語。

### Image

- `image` - 画像。
  - `img` - `image`の略語。
- `icon` - 対象の内容や機能などを小さな絵柄で表したもの。
- `loading` - 読み込み中であることを示すインターフェイス。
- `logo`  - 社名や製品名などを図案化・装飾化した文字・文字列。
- `map` - 地図。
- `chart` - 理解しやすいような方法で情報を示すリストやグラフのこと。
  - `graph` - `chart`の類語で視覚表現のための手段のこと。
- `hero` - キービジュアルになる大型の画像。
- `banner` - (主に宣伝用の)画像をともなうリンク。
- `carousel` - 画像などのコンテンツを上下左右にスライドさせて切り替えるインターフェイス。
  - `slider` - `carousel`の類語。
  - `ticker` - `carousel`の類語で自動でアイテムを左右に流しながら表示する。ユーザーは基本的にコントロールできない。

### Navigation

- `navigation` - 情報へ誘導するリンク。
  - `nav` - `navigation`の略語。
- `breadcrumb` - パンくずリスト。トップページから現在ページまでの階層構造を示したリンク。
  - `topicpath` - `breadcrumb`の類語。
- `springboard` - 同じサイズのリンクを2×2や3×3のように配置した同じ重要度を持つ並列なナビゲーション。
- `cards` - トランプのような積み重なったカードのメタファーをもつインターフェイス。
- `list-menu` - 縦に並んだリスト型のリンクで、階層構造をもったナビゲーション。
- `dashboard` - グラフやステータスなどを一つの画面にまとめたインターフェイス。
- `pagination` - 昇順にしたページ番号付きのナビゲーション。
- `back-to-top` - ページトップに戻るためのページ内リンク。
- `tabbar` - 書類などのインデックスタブを模した、別のドキュメントに切り替えるインターフェイス。
  - `segmented-control` - モバイルアプリケーションでは`tabbar`を画面全体の切り替えに使い、`segmented-control`は画面内の特定の表示領域の表示切り替えに使う。
- `toolbar` - ユーザーが利用できるツールやアクションをまとめたインターフェイス。
- `off-canvas` - 表示領域外から画面の大半を覆い隠したり(オーバーレイ)、ずらすようにスライドしながら表示するナビゲーション。
  - `side-drawer` - `off-canvas`の類語。drawerは「引き出し」の意味。
- `toggle-menu` - 同一の操作で二つの状態を交互に切り換えるインターフェイスで、操作対象になるボタンを基準にナビゲーションを表示することが多い。
- `scroll-tab` - 表示領域よりも横に長いナビゲーションで、左右にスクロールすることで非表示部分を見ることができるインターフェイス。
- `sitemap` - サイト内のすべてのページへのリンクをリスト化したもの。
- `sns` - ソーシャルネットワーキングサービス。

### Form

- `form` - 送信フォーム。
- `login` - ユーザー認証をするためのフォーム。
  - `signin` - `login`の類語。
- `registration` - ユーザー登録をするためのフォーム。
- `step-navigation` - 複数画面にわたるフォームの順序や、現在地を示したナビゲーション。
- `cart` - 購入するアイテムを一時的に保存する画面。
- `checkout` - 保存していたアイテムを購入する画面。
- `search-box` - キーワード検索するためのフォームエリア。
- `search-result` - 検索結果画面。

### etc.

- `dropdown` - 複数の項目を表示して、1つの項目を選択するインターフェイス。
  - `pulldown` - `dropdown`の類語。
- `accordion` - 折りたたまれたコンテンツを選択することで表示させるインターフェイス。
- `comment` - 記事に対する反応。
- `table` - テーブル・図表。
- `timeline` - チャットや年表のように時系列に並べたリスト。

## Element

- `inner` - 内側の。
- `outer` - 外側の。
- `body` - 主要部分。
- `head` - 上部。
- `foot` - 下部。
- `heading` - 見出し・表題。
- `title` - 表題・題名。
- `lead` - 見出しの補足・記事の要約。
- `list` - 一覧・表。
- `menu` - 一覧・表。
- `item` - (表やデータなどの)項目。
- `unit` - 1つの単位・1セット。
- `column` - 縦列。
  - `col` - `column`の略語。
- `text` - 本文。
- `caption` - 画像・図表の補足文。
- `thumbnail` - 縮小した画像。
  - `thumb` - `thumbnail`の略語。
- `avatar` - 人の顔を示す画像。
- `feature` - 特徴を補足する画像。
- `tel` - 電話番号。
- `address` - 住所。
- `date` - 日付。
- `time` - 日時。
- `category` - 分類・部類。
  - `cat` - `category`の略語。
- `tag` - 識別子。
- `next` - 次の。
- `previous` - 前の。
  - `prev` - `previous`の略語。
- `mask` - 覆い隠す。
- `overlay` - かぶせる・上書きする。
- `delimiter` - アイテムの範囲や境界線を示すインターフェイス。
  - `separator` - `delimiter`の類語で混ぜないように分離する目的で使います。
  - `divider` - `delimiter`の類語でグルーピングするように分割する目的で使います。

## Modifier

- `tiny` - とても小さい。
  - `xs` - `tiny`の類語でExtra small(smallよりさらに小さい)こと。
- `small` - 小さい。
- `medium` - 中間。
- `large` - 大きい。
- `huge` - とても大きい。
  - `xl` - `huge`の類語でExtra large(特大・超大型)のこと。
- `reverse` - 反転する。
- `push` - 前方に押す。
- `pull` - 自分の方に引く。
- `offset` - 相殺する・埋めあわせる。
- `left`- 左側の。
- `center`  - 真ん中。
- `right` - 右側の。
- `top` - 上部。
- `middle` - 真ん中。
- `bottom` - 下部。
- `round` - 角丸。
- `circle` - 円形。

## 状態

- `show` - 見せる。
- `hide` - 隠す。
- `open` - 開く。
- `close` - 閉じる。
- `current` - 現在の。
- `active` - 活動中・有効な。
- `disabled` - 無効になっている。


================================================
FILE: css-coding-rule.md
================================================
# CSSコーディングルール
## ファイル・ディレクトリ構成
ファイルの構成は[FLOCSS](https://github.com/hiloki/flocss)をベースにします。

```
root
└── assets/
    └── css/
        ├── common.scss
        ├── foundation/
        │   ├── base/
        │   ├── function/
        │   ├── mixin/
        │   └── variable/
        ├── layout/
        └── object/
            ├── component/
            ├── project/
            ├── scope/
            └── utility/
```

スタイルは基本的に`/assets/css/common.scss`で出力しますが、ページ特有のスタイルが多く出る場合は`css/pagename.scss`のようにページ専用のスタイルシートを作ることもできます。

```
root
├── assets/
│   └── css/
│       ├── common.scss
│       ├── foundation/
│       │   ├── base/
│       │   ├── function/
│       │   ├── mixin/
│       │   └── variable/
│       ├── layout/
│       └── object/
│           ├── component/
│           ├── project/
│           ├── scope/
│           └── utility/
├── css/
│   └── index.scss
├── index.html
└── page/
    ├── css/
    │   └── index.scss
    └── index.html
```

無理に1つのCSSとして管理するより、以下のようにHTMLから優先度が把握できるほうがスタイルの追加が容易になり、`common.css`の肥大化・複雑化を防ぐことができます。

```html
<link rel="stylesheet" href="/assets/css/common.css">
<link rel="stylesheet" href="/css/index.css">
```

### FLOCSSの基本
FLOCSSはFoundation、Layout、Objectの3つのレイヤーとComponent、Project、Utilityの3つの子レイヤーから構成されます。

#### 1. Foundation
Foundationレイヤーでは`html`や`body`のような広範囲にわたるベーススタイル、`h2`や`ul`のような基本的なタイプセレクタのデフォルトスタイルを定義します。装飾的なスタイルは避けて、できる限り低詳細度に保ちます。idセレクタやclassセレクタは使用しません。

Foundationレイヤーにはレイヤーを追加するため、normalize.cssやベーススタイルは`foundation/base`レイヤーに指定します。

```scss
@import "foundation/base/_normalize";
@import "foundation/base/_base";
```

#### 2. Layout
Layoutレイヤーはヘッダーやフッターのような、ページを構成するコンテナブロックのスタイルを定義します。目安としてはワイヤーフレームに書かれるような大きな単位のブロックです。汎用性のあるグリッドシステムは次のObject/Componentレイヤーで定義します。

例えば、ヘッダーにあるロゴやグローバルナビゲーションのレイアウトの役割を持つといったことができます。グローバルナビゲーションやコピーライトのようなコンポーネントは、Object/Projectレイヤーで定義します。基本的にはclass属性を使用しますが、id属性を使用することもできます。

プレフィックス(接頭辞)として`l-`をつけます。

```scss
@import "layout/_header";
@import "layout/_footer";
@import "layout/_main";
```

#### 3. Object
Objectレイヤーはプロジェクトにおけるビジュアルパターンです。抽象度や詳細度、拡張性などによって、3つのレイヤーにわけられます。

1. Component(`c-`)
2. Project(`p-`)
3. Utility(`u-`)

#### 3.1 Component
Componentレイヤーは多くのプロジェクトで横断的に再利用のできるような、小さな単位のモジュール(機能)です。

OOCSSの構造(structure)の機能を担うため、装飾的なスタイルをできるだけ含めないようにします。また、`width`や`margin`といったレイアウトに影響を与えるプロパティもできるだけ含めないようにします。

プレフィックス(接頭辞)として`c-`をつけます。

```scss
@import "object/component/_list-ordered";
@import "object/component/_media";
@import "object/component/_layout";
@import "object/component/_wrapper";
```

#### 3.2 Project
Projectレイヤーはプロジェクト固有のパターンで、複数のページで使い回せるようなコンポーネントです。具体的なスタイルを持つUI(ユーザーフェイス)で、追加されるコンポーネントのほとんどはこのレイヤーに置かれます。

構造的なパターンでも、(ボタンのように)装飾的に拡張されるのであればProjectレイヤーに置きます。

もし、このレイヤーで同じパターンが3箇所で使われていたら、別のコンポーネント(構造部分だけのパターンならComponentレイヤー、それ以外ならProjectレイヤー)としてまとめられないか検討しましょう。

プレフィックス(接頭辞)として`p-`をつけます。

```scss
@import "object/project/_icon";
@import "object/project/_icon-extend";
@import "object/project/_label";
@import "object/project/_button";
@import "object/project/_heading-h2";
@import "object/project/_heading-h3";
```

#### 3.4 Utility
Utilityレイヤーはいわゆる汎用クラスで、ほとんどの場合は単一のスタイルをもっています。コンポーネント間の間隔を調整したり、BEMのModifierが増えすぎるのを防ぎます。

共通の構造を持っていないセクションごとの余白などは、BEMのBlockとModifierで拡張することが適切でない場合があります。
そのようなモジュールは無理にBEMにせず、`.u-section`のようプレフィックスつけた汎用クラスを作ります。

`.mb10`のような具体的な名前より`.mb-small`のような相対的な名前にしたり、pxよりもemや%で指定することを推奨します。確実にスタイルを適応させるために`!important`を使用します。

プレフィックス(接頭辞)として`u-`をつけます。

```scss
@import "object/utility/_text";
@import "object/utility/_align";
@import "object/utility/_display";
@import "object/utility/_sr-only";
@import "object/utility/_width";
@import "object/utility/_margin";
@import "object/utility/_section";
```

### 追加するレイヤー
FLOCSSのファイル構成に5つのレイヤーを標準で追加します。

#### 1.1 Variable
プロジェクト全体で使われる変数を定義します。例えば以下のように、基本的な変数を定義する`global.scss`とブレイクポイント、色、font-familyを定義するファイルを分割すると見通しがよくなります。

```scss
@import "foundation/variable/_global";
@import "foundation/variable/_breakpoint";
@import "foundation/variable/_font-family";
@import "foundation/variable/_color";
```

Sass(scss記法)で変数を定義する場合は以下のことに気をつけます。

- `!default`フラグを指定することで、先に読み込んだ変数が適応されるルールに統一します。
- `$pn-`(Project name)のようにプレフィックスを付けることで名前の衝突を防ぎます。
- ハイフン(`-`)とアンダースコア(`_`)は同一と見なされるので、注意して扱います。
- 3箇所以上で使われる共通の値やプロジェクトに関わらず利用できる値だけを定義します。

#### 1.2 Function
Sassで使用できるfunctionを機能ごとに定義します。例えばpxをremに変換したり、PhotoShopのトラッキングをemに変換するfunctionなどです。
`$pn-`(Project name)のようにプレフィックスを付けることで名前の衝突を防ぎます。

```scss
@import "foundation/function/_em";
@import "foundation/function/_rem";
@import "foundation/function/_tracking";
```

#### 1.3 Mixin
Sassで使用できるmixinを機能ごとに定義します。例えばメディアクエリやclearfix、再利用できるオブジェクトのベーススタイルなどです。
`$pn-`(Project name)のようにプレフィックスを付けることで名前の衝突を防ぎます。

```scss
@import "foundation/mixin/_mq-up";
@import "foundation/mixin/_mq-down";
@import "foundation/mixin/_clearfix";
@import "foundation/mixin/_media";
```

#### 1.4 Base
normalize.cssや要素セレクタ・属性セレクタのデフォルトスタイルを指定します。

```scss
@import "foundation/base/_normalize";
@import "foundation/base/_base";
```

#### 3.3 Scope
ComponentレイヤーやProjectレイヤーのようなコンポーネント単位ではなく、ページ内の小さな範囲(スコープ)でのスタイルを定義します。繰り返し使用しないページ特有のスタイルはPageレイヤーやHTMLファイルのある各ディレクトリに定義します。

例えばブログページのスタイルとして_blog.scssを作成します。このレイヤーでは`.s-blog p`のような要素セレクタとの結合子も使うこともできます。
もし、このレイヤーで同じパターンが3箇所で使われていたら、ProjectレイヤーやUtilityレイヤーでまとめられないか検討しましょう。

直下の要素に一律の余白を指定するといった使い方をしてもいいでしょう。

```scss
.s-block {
  > {
    section, address,
    // h1, h2, h3, h4, h5, h6,
    p, ul, ol, dl,
    pre, div,
    blockquote, figure,
    table,
    form,
    a {
      &:not(:last-child) {
        margin-bottom: 1.7rem;
      }
    }
  }
}
```

プレフィックス(接頭辞)として`s-`をつけます。

```scss
@import "object/scope/_element";
@import "object/scope/_block";
@import "object/scope/_blog";
```

#### その他のレイヤー
その他にもレイヤーを追加することもできます。

- Page - ページ特有のスタイルやページ単位でObjectレイヤー内のスタイルを上書きする場合など
- Theme - SMACSSのThemeモジュールに該当するテーマによる色の切り替えなど
- QA/Test - Quality Assurance(品質保証)、もしくはテストのための一次的なスタイル

レイヤーの追加は以下のリンクを参考にします。

* [More Transparent UI Code with Namespaces](http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/)
* [Managing CSS Projects with ITCSS](http://csswizardry.net/talks/2014/11/itcss-dafed.pdf)

#### モジュール化
Layoutレイヤー以下のモジュールは機能ごとにファイルに分割します。モジュールは後述するBEMをベースに名前をつけ、モジュール名とファイル名は一致するようにします。

- `.grid` => `_grid.scss`
- `.button` => `_button.scss`

#### モジュールの粒度
モジュールを適切な粒度(受け持つ機能の大きさ)にするために、以下の3つの粒度でモジュールを分類し、小さなモジュールから読み込みます。

1. Content
1. Medium Container
1. Large Container

##### 1. Content
見出しやリスト、ボタンやアイコンなどのページの内容を表現する小さなオブジェクトです。

##### 2. Medium Container
Contentを内包するオブジェクトで、Contentのスタイルを上書きすることができます。例えば、`.media`や`.button-group`のようなオブジェクトです。

##### 3. Large Container
ContentやMedium Containerを内包するオブジェクトで、内包するオブジェクトに干渉することはできません。例えば、`.grid`や`.wrapper`のようなオブジェクトです。

Large BlockはSmall BlockとMedium Blockを内包することができますが、スタイルを上書きすることはできません。

#### レイヤーの順序
カスケーディングを管理するため、レイヤーを読み込ませる順序は

- 低詳細度から高詳細度
- 抽象的なスタイルから具体的なスタイル
- カスケーディングを許容するモジュールからカスケーディングを許容しないモジュール

のようにする必要があります。例えば以下のような順番で読み込ませます。

```scss
@import "foundation/";
@import "layout/";
@import "object/component/";
@import "object/project/";
@import "object/scope/";
@import "object/utility/";
@import "page/";
@import "theme/";
@import "qa/";
```

#### 外部ライブラリのレイヤー
JQueryのプラグイン、CSSフレームワークやライブラリを読み込ませる順序は「レイヤーの順序」で示した基準を使います。外部ライブラリであっても、役割や機能が変わることはないからです。
例えば、normalize.cssは`foundation/base/`、スライダーのようなJQueryプラグインは`object/project/`のMedium Containerが適切な位置になるでしょう。

外部ライブラリは基本的にファイルを直接上書きせず、`libraryname-extend.scss`のようなファイルを作成し、上書きをします。

## 命名規則
命名規則はBEM(MindBEMding)をベースとし、レイヤーごとにプレフィックスをつけることで名前空間とし、ブレイクポイントをもつモジュールにはサフィックス(接尾辞)をつけることで名前のブレを防ぎます。

### BEM(MindBEMding)
[BEM](https://github.com/juno/bem-methodology-ja/blob/master/definitions.md)をベースにした[MindBEMding](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)を使用します。BEMには役割や関係性を明確にできるメリットがあります。

BEMはBlock、Element、Modifierの3つの概念から構成され、以下のようなクラス名になります。

```scss
.block-name {}
.block-name__element {}
.block-name--modifier-name {}
.block-name__element--modifier-name {}
```

* 小文字の英単語とハイフン1つ(`-`)とハイフン2つ(`--`)、アンダースコア2つ(`__`)で構成されます
* BlockとElementとModifierの単語はハイフン(`-`)でつなぎます
* BlockとModifierはできるだけ2つ以上の単語を合わせてユニークな名前にします
* ElementとModifierは1つの単語だけを使ってもかまいません
* ElementとModifierはBlockの名前を受け継ぎます
* BlockとElementはアンダースコア2つ(`__`)でつなぎます
* BlockとModiferもしくはElementとModiferはハイフン2つ(`--`)でつなぎます

基本的にクラスセレクタ1つだけにスタイルを指定しますが、`.block--modifier`の指定でElementにもスタイルを指定したい場合にはクラスセレクタを2つ使って指定することもできます。ただし、直近の子要素に限定するなど、影響範囲をできるだけ狭くしておきます。

```scss
// Good
.block--modifier > .block__element {}

// Bad
.block--modifier .block__element {}
```

#### BEMの注意点
Elementを入れ子にするときに`.block__element__element`のような名前にできるだけならないようにします。HTMLの構造を示すのではなく、Blockに対するElementとModifierの関係性を示します。

```scss
// Good
.block__element {}
.block__child-element {}

// Bad
.block__element {}
.block__element__element {}
```

OOCSSのようにマルチクラスで指定するのを基本とします。基本的にはBlockは独立して機能するようにしますが、汎用性を考慮したり、クラス名が長くなりすぎる場合には、Modifierだけでなく汎用クラスを組み合わせることもあります。

```html
<!-- 汎用クラスで`width`を指定している。 -->
<div class="c-grid">
  <div class="c-grid__item u-8of12-md"></div>
  <div class="c-grid__item u-4of12-md"></div>
</div>
```

Blockを親セレクタにしてElementとModifierを指定しません。スコープは命名規則によって擬似的に作ります。スタイルは柔軟に上書きができるように、詳細度をできるだけ弱くしておきます。

```scss
// Good
.block {}
.block__element {}
.block--modifier {}

// Bad
.block {}
.block .block__element {}
.block .block--modifier {}
```

Blockのスタイルを上書きするときに詳細度を変えないようにします。例えば、`.block1`のスタイルを変更するために`.block2`を親セレクタにして`.block1`を上書きするような指定はできるだけ避けます。同じ詳細度のセレクタであとから読み込ませることで上書きするようにします。

```scss
// Good
.block1 {}
.block__element {}

.block2 {}

// Bad
.block1 {}
.block__element {}

.block2 .block1 {}
```

FLOCSSにカスケーディングに関するルールを2つ追加しています。

1. 同じProjectレイヤーでもMedium BlockはSmall Blockのスタイルを一部上書きすることができます。
1. Scopeレイヤー、Themeレイヤー、QAレイヤーはそれまでのレイヤーを上書きすることができます。

Sassの入れ子とアンパサンド(`&`)でBEMの記述を短縮することができますが、基本的に使わないようにします。1つ目の理由は入れ子のElementが増えると、今のアンパサンドがどこまでのElementとModifierを含んでいるのかを把握しにくくなるからです。

```scss
// Bad
.foo {
  color: white;
  &--bar {
    color: red;
  }
  & .bar {
    color: red;
  }
}
```

2つ目の理由は実際に指定しているセレクタ名で検索できなくなるからです。CSSにコンパイルされてはじめて`.block__element`のように生成されるので、Sass編集時に検索することができません。

入れ子を使うのは擬似要素やステートクラス、ブレイクポイントの挿入などに制限します。

```scss
// Good
.block {
  &:hover {
    color: blue;
  }
  &.is-active {
    color: blue;
  }
  @include _mq-up(md) {
    color: green;
  }
}
```

早く書けることも必要ですが、修正や運用がしやすいことのほうがずっと重要です。

その他のBEMに関する注意点などは[BEM(MindBEMding)によるCSS設計](https://github.com/manabuyasuda/styleguide/blob/master/how-to-bem.md)を参照してください。

### プレフィックス(Prefix)
レイヤーごとの役割を示したり、名前の重複をさせないために名前空間としてプレフィックスをつけます。FLOCSSで推奨されているプレフィックスといくつかのプレフィックスを使用します。

- `l-` Layoutレイヤー
- `c-` Componentレイヤー
- `p-` Projectレイヤー
- `u-` Utilityレイヤー
- `t-` Themeレイアー
- `s-` Scopeレイヤー
- `qa-`, `te-` QA/Testレイヤー
- `is-` クリックやマウスオーバーなどのイベントが発生している要素に付与する
- `js-` JavaScriptから参照される要素
- `cp-` あるHTML専用のCSSファイル(current pageの略称。名前を変更することもできます。)

### サフィックス(Suffix)
ブレイクポイントを指定しているクラス名は`-sm`や`-md`のようなブレイクポイントのキーワードをクラス名の末尾につけます。
ブレイクポイントはグローバル変数として定義しておき、そのキーをクラス名にも使うようにします。

```scss
$_breakpoint-up: (
  'sm': 'screen and (min-width: 400px)',
  'md': 'screen and (min-width: 768px)',
  'lg': 'screen and (min-width: 1000px)',
  'xl': 'screen and (min-width: 1200px)',
) !default;
```

```scss
@media (min-width: 400px) {
  .u-dn-sm { display: none; }
}

@media (min-width: 768px) {
  .u-dn-md { display: none; }
}

@media (min-width: 1000px) {
  .u-dn-lg { display: none; }
}

@media (min-width: 1200px) {
  .u-dn-xl { display: none; }
}
```

メディアクエリは`min-width`を優先的に使い`-sm`などとします。`max-width`のパターンも作る場合は`-sm-down`などとします。

## コメント
コメントにはコードだけでは理解できない(しにくい)情報を残します。例えば以下のようなものです。

- 全体を見渡せるような目次
- レイヤーやモジュールの区切りをわかりやすくするための見出し
- なぜその実装方法を選んだのかという理由
- コードの整理をしたい、バグを修正したいといった、コードからはわからない情報
- コード自体の補足

### 目次(Table of Contents)
スタイルシートのボリュームが一定以上になると全体の把握は難しくなります。CSSでもSassでも利用できる目次をスタイルシートのはじめに用意しておくことを推奨します。

```scss
/**
 * VARIABLE
 * global...サイト全体に使用するサイズや数値に関する変数です。
 * breakpoint...メディアクエリで使用するブレイクポイントです。
 * font-family...font-family指定をまとめています。
 * color...グローバルに使用する色指定です。
 *
 * FUNCTION
 * em...pxをemに変換します。
 * rem...pxをremに変換します。
 * tracking...Photoshopのカーニングをemに変換します。
 *
 * MIXIN
 * mq-up...メディアクエリを`min-width`で挿入します。
 * mq-down...メディアクエリを`max-width`で挿入します。
 * responsive...レスポンシブ対応クラスを生成します。
 * on-event...:hover, :active, :focusをまとめて指定します。
 * clearfix...floatの解除をします。
 * sr-only...非表示にしてスクリーンリーダーにだけ読み上げさせます。
 * list-unstyled...list-unstyledオブジェクトのベーススタイルです。
 * list-mark...list-markオブジェクトのベーススタイルです。
 * media...mediaオブジェクトのベーススタイルです。
 * flag...flagオブジェクトのベーススタイルです。
 * ratio...ratioオブジェクトのベーススタイルです。
 * layout...layoutオブジェクトのベーススタイルです。
 *
 * BASE
 * normalize...Normalize.cssをインポートしています。
 * base...タイプセレクタと属性セレクタのデフォルトスタイルです。
 *
 * LAYOUT
 * header...`<body>`タグ直下にある`<header>`タグのスタイルです。
 * footer...`<body>`タグ直下にある`<footer>`タグのスタイルです。
 * main...`<main>`タグのスタイルです。
 *
 * COMPONENT
 * list-ordered...番号付きリストを入れ子レベルに応じて、1, 1.1のように区切り文字を付け加えます。
 * media...画像とテキストが横並びになるオブジェクトです。テキストを画像に回り込みさせます。
 * layout...汎用的なレイアウトオブジェクトです。グリッドレイアウトなどに使用できます。
 * wrapper...最大幅を指定します。
 *
 * PROJECT
 * icon...アイコンフォントです。テンプレートから自動で生成されます。
 * icon-extend...アイコンフォントを拡張するModifierです。
 * label...インラインのラベルコンポーネントです。
 * button...ボタンコンポーネントです。
 * heading-h2...`<h2>`で使うような見出しです。
 * heading-h3...`<h3>`で使うような見出しです。
 *
 * SCOPE
 * element...BEMにおけるElementの余白を一括で指定します。
 * block...BEMにおけるBloclの余白を一括で指定します。
 * blog...ブログページのスタイルです。
 *
 * UTILITY
 * text...テキストのスタイルに関する汎用クラスです。
 * heading...見出しの汎用スタイルです。
 * align...画像などを中央や右側に配置します。
 * display...要素の表示や改行をコントロールする場合に使用します。
 * sr-only...要素を非表示にさせますが、スクリーンリーダーには読み上げられます。
 * width...おもにグリッドで使用する`width`を指定する汎用クラスです。
 * margin...マージンで余白の管理をします。常に下方向にだけ余白をとります。
 * section...`<section>`要素を使うようなセクションの余白を管理します。
 */
```

### レイヤータイトル
どこのレイヤーにいるのか、どういった特徴のあるレイヤーなのかなどを残しておくとコードを理解しやすくなります。ContentやMedium Containerのような粒度の分類もコメントで残しておきます。

```scss
/* -----------------------------------------------------------------------------
   #Component
   -------------------------------------------------------------------------- */
/**
 * Componentレイヤーは多くのプロジェクトで横断的に再利用のできるような、小さな単位のモジュール(機能)です。
 * OOCSSの構造(structure)の機能を担うため、装飾的なスタイルをできるだけ含めないようにします。
 * また、`width`や`margin`といったレイアウトに影響を与えるプロパティもできるだけ含めないようにします。
 * プレフィックス(接頭辞)として`c-`をつけます。
 */
// Content
@import "object/component/_list-unstyled";
@import "object/component/_list-addstyle";
@import "object/component/_list-ordered";
@import "object/component/_list-note";
@import "object/component/_embed";
// Medium Container
@import "object/component/_block";
@import "object/component/_list-inline";
@import "object/component/_media";
@import "object/component/_flag";
@import "object/component/_table";
@import "object/component/_ratio";
// Large Container
@import "object/component/_layout";
@import "object/component/_wrapper";
```

### モジュールタイトル
モジュール化したファイルにはモジュールの名前や機能、マークアップの例などを残します。下記はスタイルガイドジェネレーター「[Aigis](https://pxgrid.github.io/aigis/)」のコメントも併記した例です(シンタックスハイライトを効かせるために一部全角を使用しています)。

```scss
 /* #Label
   -------------------------------------------------------------------------- */
/*
ーーー
name: label
category: project
ーーー

インラインでメッセージを表示するコンポーネントです。

```jade
p: span.p-label タグ名
```
*/
.p-label {
  display: inline-block;
  padding: 0.5em;
  color: $_color-ui-bg;
  font-size: $_font-size--small;
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  text-decoration: none;
  background-color: $_color-link;
  @include _on-event() {
    color: #fff;
    text-decoration: none;
  }
}
```

### 注意事項とTODO
あとで処理をしたいことや、把握しておいてほしい注意事項はコメントに残していつでも検索できるようにします。

- `NOTE:` コード上で確認できない制限などの共有
- `TBD:` 今後どうしていくか検討したいこと
- `TODO:` 動作はするけれど改修したい箇所

### コードの説明と参照リンク
そのコードが一部のひとにしか正しく理解されないと感じたらコメントを残します。詳しくコメントで説明できない場合は参照となるリンクも貼っておきます。

```scss
/**
 * ボックスモデルを`border-box`にリセットします。
 * https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
 */
html {
    box-sizing: border-box;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}
```

### Sassのコメント
SassはCSSをプログラム的に拡張できるプリプロセッサーです。複雑になりがちな機能や使い方を伝えるためにコメントで補足をしておきます。

```scss
// @desc - メディアクエリを`min-width`で挿入します。
// @param {String} $breakpoint [$_default-breakpoint] - 引数に変数のキーワードを渡します。
// @see - $_breakpoint-up
// @example scss - Usage
// .foo {
//   color: red;
//   @include _mq-up {
//     color: blue;
//   }
// }
// @example css - CSS output
// .foo {
//   color: red;
// }
// @media screen and (min-width: 768px) {
//   .foo {
//     color: blue;
//   }
// }
@mixin _mq-up($breakpoint: $_default-breakpoint) {
  @if map-has-key($_breakpoint-up, $breakpoint) {
    @media #{inspect(map-get($_breakpoint-up, $breakpoint))} {
      @content;
    }
  } @else {
    @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
    + "Please make sure it is defined in `$_breakpoint-up` map.";
  }
}
```

## フォーマットとプロパティの宣言順
CSSの構文はセレクタとブレース、プロパティと値で構成されます。このルールセットに読みやすさを確保したフォーマット(書式)をルール化します。

### ルールセットのフォーマット
ルールセットの基本的なフォーマットは以下の通りです。

* 複数のセレクタは別の行に(関連性があって1行が長くなり過ぎなければ同じ行に指定してもいい)
* 最後のセレクタとオープニングブレースの間にスペースを1つ
* それぞれの宣言は別々の行に
* ルールセット内に空行は入れない
* プロパティの前にスペースを2つ
* コロン(`:`)と値の間にスペースを1つ
* クロージングブレースは独立した行に
* 各ルールセットの間に空行を1つ
* 関数はカンマ(`,`)と引数の間にスペースを1つ
* ローカル変数は最初に定義
* extendはローカル変数の次に指定
* mixinはextendの次に指定
* contentを使用しているmixinは最後に指定
* 演算は常に括弧(`()`)で囲む
* 括弧内のカンマ(`,`)と値の間にスペースを1つ

```scss
/* Good */
.foo, .foo--bar,
.baz {
  $_padding: 1em;
  @extend %base-unit;
  @include _clearfix;
  display: block;
  margin-right: auto;
  margin-left: auto;
  padding-right: $_padding;
  padding-left: $_padding;
  backgrouond-color: rgba(0, 0, 0, 0.7);
  @include _mq-up(md) {
    padding-right: ($_padding * 2);
    padding-left: ($_padding * 2);
  }
}

/* Bad */
.foo,
.foo--bar, .baz{
    @include _mq-up_(md) {
        padding-right: $_padding * 2;
        padding-left: $_padding * 2;
    }
    display: block;margin-right: auto;
    backgrouond-color: rgba(0,0,0,0.7);
    margin-left:auto;
    @extend %base-unit;
    @include _clearfix;
    $_padding: 1em;}
```

### 単一行ルールセットのフォーマット
原則的には複数行でルールセットを記述しますが、汎用クラスなどの単一のスタイルの場合は1行で記述することもできます。

単一行のフォーマットは以下の通りです。

* 最後のセレクタとオープニングブレースの間にスペースを1つ
* オープニングブレースとプロパティの間にスペースを1つ
* コロン(`:`)と値の間にスペースを1つ
* セミコロン(`;`)とクロージングブレースの間にスペースを1つ
* 各ルールセットの間には空行を入れない

```scss
// Good
.u-text-right { text-align: right !important; }
.u-text-center { text-align: center !important; }
.u-text-left { text-align: left !important; }
```

### プロパティの宣言順
ルールセット内の宣言は重要なプロパティから書き始め、その機能ごとに固めて記述することで意図を素早く理解できるようにします。プロパティの宣言順は以下のようなルールで記述します。

* ボックスモデルの種類や表示方法を示すプロパティ(`box-sizing`, `display`, `visibility`, `float`など)
* 位置情報に関するプロパティ(`position`, `z-index`など)
* ボックスモデルのサイズに関するプロパティ(`width`, `height`, `margin`, `padding`, `border`など)
* フォント関連のプロパティ(`font-size`, `line-height`など)
* 色に関するプロパティ(`color`, `background-color`など)
* それ以外

アルファベット順には記述しません。プロパティをアルファベット順で書いていくのは難しいと思いますし、読み難いとも思います。例えば`position`プロパティ
で位置の指定をする場合に`top`と`left`が離れてしまうのは読みやすいでしょうか?

```scss
// Good
.foo {
  display: block;
  position: absolute; // 親要素に対して、
  top: 0;
  left: 0; // 左上を基準にする。
  width: 100%;
  margin: 0;
  padding: 0;
  font-size: 0.75em;
  color: #000;
  background-color: #fff;
}

// Bad
.foo {
  background-color: #fff;
  color: #000;
  display: block;
  font-size: 0.75em;
  left: 0; // どこかにpositionがある?
  margin: 0;
  padding: 0;
  position: absolute; // positionがあった、親要素を基準にするのか
  top: 0; // 上にあわせて、他の値はなんだっただろう?
  width: 100%;
}
```

### 個別指定プロパティの宣言順

`margin`や`position`のように上下左右に個別に指定できるプロパティは時計回りで記述をすることで規則性をもたせます。

```scss
// Good
.foo {
  margin-top: auto;
  margin-right: auto;
  margin-bottom: auto;
  margin-left: auto;
}

// Bad
.foo {
  margin-left: auto;
  margin-right: auto;
  margin-top: auto;
  margin-bottom: auto;
}
```

## CSSベタープラクティス

### セレクタ
#### インライン記述を使用しない
HTMLのstyle属性にスタイルを記述することは禁止します。HTMLには見た目に関する情報を極力書かないようにします。クラスを振ったほうが柔軟にスタイルを変更することができます。JavaScriptを使う場合もstyle属性を使いません。

```html
<!-- Bad -->
<div style="color:red; background-color: black;"></div>
```

#### HTMLの構造に依存させない
要素セレクタに対してスタイルを指定すると、構造が変更されたときにスタイルが崩れてしまう恐れがあります。

```scss
// Bad
article h2 {}
```

クラスセレクタであれば、指定している要素に関係なくスタイルが適応されるので、使い回しがしやすくなります。ただし、要素によってデフォルトのスタイルがちがうこともあるので、スタイルが崩れないようにリセットしておく必要がある場合があります。

```scss
// `article`要素の見出しに指定するクラス
.article__title {}

// 汎用的な見出しのクラスを用意
.u-h2 {}
```

クラスセレクタに対して要素セレクタを連結させるのも意味がありません。

```scss
// Good
.foo {}

// Bad
h2.foo {}
```

特定の要素で指定してほしいのであれば、コメントやクラス名でそれを示します。

```scss
/* Good */
/* ulタグかolタグに指定してください。 */
.foo {}

/* ul, ol */.foo-list {}
```

#### IDセレクタを多用しない
IDセレクタはスタイルの上書きが難しくなるので、複雑なセレクタを指定しなければいけなくなったり、詳細度を強くしてしまう原因になります。IDセレクタは使わないほうがベターです。

ただし、ページ内リンクやJavaScriptのフックとして使うのは問題ありません。

#### メディアクエリをまとめて管理しない
メディアクエリをまとめて指定しません。そのセレクタがどのように変化していくのかを把握しにくくしてしまいます。

```scss
// Good
.foo {}

@media (min-width: 768px) {
  .foo {}
}

// Bad
@media (min-width: 768px) {
  .foo {}
  .bar {}
  .baz {}
}
```

#### セレクタを短くする
セレクタは必ずしもHTML構造に沿う必要はありません。場合によってはセレクタを短くすることで詳細度を低く抑えることができます。

```scss
// Good
ul a {}
th {}

// Bad
ul li a {}
table th {}
```

#### divやspanをセレクタに使用しない
`div`や`span`は使用頻度が高いので、セレクタに指定すると意図しないところにスタイルが当たってしまう恐れがあります。直接スタイルを指定せずに、クラスを振って指定します。

```scss
// Bad
div {}
span {}
.foo div {}
.foo span {}
```

#### 擬似クラスを活用する
CSS3の擬似クラスを使うとセレクタを柔軟に指定することができます。

* x番目の要素 - `:nth-of-type(x)`
* x番目以降の要素 - `nth-of-type(n+x)`
* 奇数の要素 - `:nth-of-type(odd)` `nth-of-type(2n+1)`
* 偶数の要素 - `:nth-of-type(even)` `:nth-of-type(2n)`
* 最初の要素 - `:first-of-type`
* 最初の要素以外の要素 - `:not(:first-of-type)` `:nth-of-type(n+2)`
* 最初から数えてx番目までの要素 - `:nth-of-type(-n+x)`
* 最後の要素 - `:last-of-type`
* 最後の要素以外 - `:not(:last-of-type)`
* 最後から数えてx番目の要素 - `:nth-last-of-type(x)`
* 最後の要素でなおかつ奇数の要素 - `:nth-of-type(odd):last-of-type`
* 最初の子要素 - `> :first-child`
* 最後の子要素 - `> :last-child`
* あるクラス名がfooで始まる要素のx番目 - `> [class^="foo"]:nth-child(x)`

CSS3の擬似クラスを使う場合は`nth-child`のような`-child`ではなく、`nth-of-type`のような`of-type`を使います。`-child`は親要素から見た子要素を要素のタイプに関係なく数えるので、HTMLの構造によっては期待どおりにならないことがあります。

#### セレクタの詳細度を管理する
セレクタの詳細度は基本的にスタイルシートの序盤は詳細度を弱く、それから徐々に詳細度を高くしていくほうが管理がしやすくなります。

セレクタの工夫で詳細度を変える方法もあります。

* `.foo`(0,0,1,0)の詳細度を強くする場合は`.foo.foo`(0,0,2,0)
* `#bar`(0,1,0,0)の詳細度を弱くする場合は`[id="bar"]`(0,0,1,0)
* `html`(0,0,0,1)の詳細度を強くする場合は`:root`(0,0,1,0)
* `a`(0,0,0,1)の詳細度を強くする場合は`a:link`(0,0,1,1)

`.foo`と`[class="foo"]`は同じ詳細度(0, 0, 1, 0)になりますが、属性セレクタは「`.foo`で始まるクラス名」のような柔軟な指定ができます。

* `[class^="foo"]` class属性の値がfooで始まる(前方一致)要素
* `[class$="foo"]` class属性の値がfooで終わる(後方一致)要素
* `[class*="foo"]` class属性の値がfooを含む(部分一致)要素

[Specificity Calculator](http://specificity.keegan.st/)

#### ステートクラス単体にスタイルを指定しない
SMACSSというCSSの設計手法にState(ステート)という状態をあらわすルールがあります。例えばクリックやマウスオーバーのようなイベントが発生している要素に指定することでスタイルを変更します。

このステートクラスは単体でスタイルを持たせず、コンポーネントと一緒に指定することでスコープを作ります。

```scss
// Good
.foo.is-active {}

// Bad
.is-active {}
```

#### 構造とスキン(見た目)を分離する
いくつかのバリエーションを含んでいるコンポーネントはOOCSSの構造とスキン(見た目)の分離ができるようにします。構造とはボックスモデルやレイアウトなどで、スキンとは色や線などの見た目を整えることです。

以下のように構造を担う`.box`と、スキンを担う`.box--success`と分けて指定することで、共通のスタイルを多く持つコンポーネントにすることができます。余白を変更する場合でも構造を持つ`.box`を変更するだけで他のバリエーションにも適応されます。

```html
<!-- Good -->
<p class="box"></p>
<p class="box box--success"></p>
<p class="box box--error"></p>
```

```scss
// Good
.box {
  margin-bottom: 1rem;
  padding: 1em;
  border: 1px solid #e7edf0;
  color: #47525d;
  background-color: #f7f9fa;
}

.box--success {
  border-color: #d9f4e1;
  color: #2c683f;
  background-color: #edfaf1;
}

.box--error {
  border-color: #ffcaca;
  color: #921515;
  background-color: #ffe3e3;
}

// Bad
.box {
  margin-bottom: 1rem;
  padding: 1em;
  border: 1px solid #e7edf0;
  color: #47525d;
  background-color: #f7f9fa;
}

.box--success {
  margin-bottom: 1rem;
  padding: 1em;
  border-color: #d9f4e1;
  color: #2c683f;
  background-color: #edfaf1;
}

.box--error {
  margin-bottom: 1rem;
  padding: 1em;
  border-color: #ffcaca;
  color: #921515;
  background-color: #ffe3e3;
}
```

### プロパティ
#### !importantを多用しない
`!important`の使用は禁止しませんが、多用するべきではありません。例えばシングルクラスのヘルパークラスを確実に適応されるために指定したり、外部ライブラリがJavaScriptでstyle属性を指定してしまうのを上書きするためといった場合に限って使用します。

#### スタイルをリセットしている
スタイルのリセットとは、`0`や`none`などで値を上書きすることです。スタイルのリセットが多いときは、要素にスタイルを持たせすぎていたり、早く指定しすぎている恐れがあります。

```scss
// Bad
.foo {
  border: 1px solid #ddd;
}

// ある要素内ではボーダーが邪魔になるためリセット
.bar .foo {
  border: none;
}
```

Modiferで必要なときにだけ指定するとリセットが起きにくくなります。

```scss
// Good
.foo {}
.foo--bordered {
  border: 1px solid #ddd;
}
```

#### 要素セレクタに装飾的なスタイルを指定しない
`h1`や`p`といったセマンティックな要素セレクタには多くのスタイル(特に装飾的なスタイル)を指定しません。必ずあとでスタイルをリセットすることになります。

```scss
// Bad
h2 {
  padding-bottom: 0.5em;
  border-bottom: 1px solid #888;
}
```

要素セレクタにはブラウザのデフォルトスタイルシートやリセットCSSで指定されるような最低限のスタイルにとどめておきます。

```scss
// Good
h2 {
  font-size: 2rem;
  line-height: 1.2;
  margin-top: 0;
  margin-bottom: 24px;
}
```

#### 高さを指定しない
レスポンシブでは横幅も高さも変化します。高さを指定していると余分な余白ができてしまったり、逆にコンテンツが隠れてしまう恐れがあります。

```scss
// Bad
.foo {
  height: 1000px;
}
```

#### 固定の幅を持たせない
コンテンツは基本的に親要素に対して横幅100%の表示になるようにします。横幅を固定すると、横幅が足りなかったり、はみ出してしまう恐れがあります。

幅を変更するときは、コンテナブロックにmax-widthを指定する、widthのヘルパークラスを指定する、Modifierでサイズを指定するなどの方法があります。

```scss
// Good
.button {}

.wrapper {
  max-width: 1200px;
}

.c-button--size-full {
  width: 100%;
}

// Bad
.button {
  width: 300px;
}
```

#### カラーコードは短縮する
colorプロパティなどで色を指定する時は可読性をあげるために、可能な場合は短縮します。

```scss
// Good
.foo { color: #ddd; }

// Bad
.foo { color: #dddddd; }
```

#### 文字列には引用符(ダブルクォート)をつける
contentプロパティやURLの指定、属性セレクタの指定をする時にはダブルクウォートを使用します。

```scss
// Good
.foo {
  content: "this is content";
  background: url("logo.png");
}
input[type="submit"] {}

// Bad
.foo {
  content: 'this is content';
  background: url(logo.png);
}
input[type=submit] {}
input[type='submit'] {}
```

#### 0に単位をつけない
値が0の場合はpxや%といった単位は必要がないため指定しません。

```scss
// Good
.foo { margin: 0; }

// Bad
.foo { margin: 0px; }
```

ただし、角度(`deg`,`grad`,`rad`,`turn`)や時間(`s`,`ms`)では単位の省略をすることができないので注意します。

#### 小数点のあたまの0を省略しない
0.5emなどの小数点の前の0は省略しません。ファイルサイズの削減は考えずに、明示的に指定します。

```scss
// Good
.foo { font-size: 0.5em; }

// Bad
.foo { font-size: .5em; }
```

#### すべて小文字で記述する
プロパティとプロパティ値は大文字でも小文字でも同様に扱われますが、小文字に統一します。

```scss
// Good
.foo { color: #fff; }

// Bad
.foo { COLOR: #FFF; }
```

#### ショートハンドはなるべく避ける
font-sizeやmarginなどのショートハンドプロパティの使用は必要がなければ避けます。ショートハンドプロパティに渡さなかったプロパティに初期値が指定されてしまい、思わぬスタイルが当たってしまう恐れがあります。

必要なプロパティにだけ指定するほうがコードの目的も分かりやすくなります。

```scss
// Good
.foo {
  // 中央配置にする。
  margin-right: auto;
  margin-left: auto;
}

// Bad
// 上下を0に指定する必要がない。
.foo { margin: 0 auto; }
```

#### ベンダープレフィックスは手動で書かない
-webkit-や-moz-などのベンダープレフィックスは手動で書かず、[Autoprefixer](https://github.com/postcss/autoprefixer)を使います。自動化したほうが確実で、管理する必要がなくなります。

### Sass
#### 変数を作りすぎない
CSSフレームワークではコンポーネントごとに大量の変数が定義されています。これはコードを変更せずに、変数で見た目を変更するというCSSフレームワーク特有の使い方です。通常の案件では必要ない場合が多いです。

変数を定義する条件は以下の2つです。

1. 同じ値を繰り返し使う
1. 四則演算などで値を変える必要がある

```scss
// Good
$unit-base: 1em !dafault;
.foo {
  margin-left: (-$unit-base);
}
.foo__bar {
  padding-left: $unit-base;
}
```

#### 変数にはdefaultフラグを指定する
変数を定義するときには`!default`フラグも指定します。同じ変数名の場合、先に定義した変数が適応されるというシンプルなルールになるので管理がしやすくなります。

```scss
// Good
$unit-base: 1em !default;

// Bad
$unit-base: 1em;
```

#### 変数名と関数名のつけかた
`$color-red`のような直接的な名前の変数は`$color-error`のような変数に代入してから指定します。`$color-red`を直接指定すると、変数の値を変えたときに変数名と値の意味が合わなくなってしまう恐れがあります。指定した変数を付け替えるのではなく、定義した変数の値で一括管理できるようにします。

```scss
// Good
$color-red: red;
$color-error: $color-red;
.foo { color: $color-error; }

// Bad
$color-red: red;
.foo { color: $color-red; }
```

変数や関数には接頭辞をつけます。CSSフレームワークやライブラリを併用する場合に名前が重複する可能性があるからです。プロジェクト名から2文字をとって`.pj-`のようにするといいでしょう。

```scss
// Good
$my-variable: "variable";
@funciton my-function() {}
@mixin my-mixin() {}

// Bad
$variable: "variable";
@funciton function() {}
@mixin mixin() {}
```

Sassの変数と関数ではハイフン(`-`)とアンダースコア(`_`)は同じものとして扱われるので注意します。例えば以下の変数名は同一視されるので、`$foo--base`は常に上書きされて適応されません。

```scss
$foo--base: black; // 上書きされる
$foo__base: red;
```

!defaultフラグを指定すると逆に`$foo__base`が上書きされて適応されません。

```scss
$foo--base: black !default;
$foo__base: red !default; // 上書きされる
```

#### extendはできるだけ使わない
extendはCSSに継承の機能を持ち込むことができますが、継承元のセレクタがある場所に継承先のセレクタも指定されるのでカスケーディングを複雑にしてしまう恐れがあります。CSSにコンパイルされたときに、ルールセットに大量のセレクタが指定されてしまい、コードを理解しにくくなってしまう恐れもあります。

extendを使う場合は以下の点に気をつけます。

* 同じモジュール内で完結させる
* コメントによって補足する


================================================
FILE: css-styleguide.md
================================================
# CSS Styleguide
## はじめに
このスタイルガイドはCSSを扱う上でベターだと思われる方法をまとめたものです。必ずしも正しいものかは分かりません。このスタイルガイドの目的は共通の認識や知識を得ることにあります。

このスタイルガイドは以下の3つのドキュメントに大きく影響を受けています。

* [CSS Guidelines (2.2.4) – High-level advice and guidelines for writing sane, manageable, scalable CSS](http://cssguidelin.es/)
* [Sass Guidelines](http://sass-guidelin.es/)
* [hiloki/flocss](https://github.com/hiloki/flocss)

### 基本的な考え方
CSSという言語の特性について考える前に基本となる考え方を定義します。ベストな方法があったとしても、そのプロジェクトの規模やチームメンバーの能力によっては実現が困難であったり、より適した方法があると考えられるからです。大切なことは実現可能な方法で結果を出し続けることです。

* 一貫性を保つこと。
* いつ読んでも、誰が読んでも理解できるようにコードを書くこと。
* 共通のルールを決めて周知し、遵守すること。
* 知識の差をなるべく埋め、認識のズレを少なくすること。
* 不必要な複雑さを避け、簡潔に単純にすること(「KISSの原則」)。
* 繰り返しや重複を避けること(「DRYの原則」)。

### CSSアーキテクチャのゴール
[Philip Walton](https://github.com/philipwalton)は[CSS Architecture](http://philipwalton.com/articles/css-architecture/)([日本語訳](http://article.enja.io/articles/css-architecture.html))のなかで、まずゴールを定めることが大切だと語っています。そして、そのゴールは予測、再利用、保守、拡張しやすいものであるべきだとしています。

> 予測しやすいCSSとはルールが期待通りに振る舞うことを意味する。ルールを追加・更新したとき、そのルールが意図せずサイトの一部に影響を与えるべきではない。滅多に変更されない小規模なサイトであれば、このことはあまり重要ではないが、数十、数百ページの大規模なサイトであれば、予測しやすいCSSは必須といえる。
> 
> CSSのルールは抽象的で、十分に分離されているべきである。それはパターンとすでに解決した問題を書きなおす必要なく、既存のパーツから新しいコンポーネントを速くつくることができるということだ。
> 
> サイトに新しいコンポーネントと機能が追加・更新されるか、再編される必要があるとき、既存のCSSのリファクタリングを必要とすべきではない。ページにコンポーネントXを追加するときに、そのわずかな存在によってコンポーネントYを壊すべきではない。
> 
> サイトが大きく、複雑に成長していくにつれて、通常はたくさんのデベロッパがメンテナンスのために必要となる。 拡張しやすいCSSとはひとりのデベロッパか、大きなエンジニアチームかを問わず、容易に管理できることを意味する。またそのサイトのCSSアーキテクチャに、巨大な学習曲線を必要することなく容易に近づけるという意味でもある。あなたが今日CSSを触る唯一のデベロッパだからといって、先々にも常にあなただけであるというわけではない。

これらのゴールを達成するために、より適切な方法を選択しましょう。できる限り、技術的なハードルが低く、学習コストの低い方法が望ましいです。

## ファイル構成
CSSには詳細度という仕組みがあります。詳細度が同じであれば、あとで記述したスタイルが適応されますが、詳細度の強さが違う場合は必ずしも適応されるわけではありません。

理想的にいえば詳細度はほとんど一定であることが望ましいです。そうでない場合は、スタイルシートの序盤は詳細度が弱く抽象的で一般的なスタイルを持ち、終盤になるにしたがって詳細度が強く具体的なスタイルが指定されるべきです。

詳細度は[Specificity Calculator](http://specificity.keegan.st/)というサービスで確認することができます。

### FLOCSS
ファイルの構成は[FLOCSS](https://github.com/hiloki/flocss)(フロックス)をベースにするのを推奨します。FLOCSSはFoundation、Layout、Objectの3つのレイヤーから構成されます。ObjectレイヤーはさらにComponent、Project、Utilityの3つの子レイヤーに分けられます。レイヤーごとに詳細度に関するルールを定義することで、カスケーディングを管理します。以下はそれぞれの特徴を示したものです。

1. Foundation - Normalize.cssやタイポグラフィーなどプロジェクトのベースになるスタイルが該当します。詳細度は極力抑えるべきで、要素セレクタや属性セレクタなどに最低限のスタイルを指定します。
1. Layout - ワイヤーフレームに定義されるような大きなコンテナブロックが該当します。このレイヤーでのみIDセレクタを指定することが許容されます。
1. Object - OOCSSのコンセプトを元にしたビジュアルパターンが主に該当します。classセレクタのみで構成されます。
1. Component - 多くのプロジェクトで横断的に再利用できるような、小さな単位のモジュールが該当します。OOCSSでの構造を担うため、固有の幅や装飾的なスタイルは極力指定しないようにします。
1. Project - プロジェクト固有のビジュアルパターンでいわゆるUI(ユーザーインターフェイス)が該当します。ほとんどのスタイルの追加はこのレイヤーになります。
1. Utility - いわゆる汎用クラスのことで、主に単一のスタイルを持っています。ComponentレイヤーとProjectレイヤーで指定するのが適切でない例外的なスタイルや汎用的に使えるスタイルが定義されています。オプションとして`!important`を許容しています。

#### レイヤーを追加する
FLOCSSにないレイヤーを追加することもできます。ただし、詳細度の管理に支障が出ないように追加する場所には注意しましょう。例えば以下のようなレイヤーが考えられます。

* Variable - プロジェクトでグローバルに使用される変数を定義します。
* Function - プロジェクトでグローバルに使用される@functionを定義します。
* Mixin - プロジェクトでグローバルに使用される@mixinを定義します。
* Vendors - Normalize.cssやBootstrapのような外部のライブラリやCSSフレームワークです。
* Vendors-extension - Vendorsレイヤーを上書きするためのレイヤーです。
* Theme - SMACSSのThemeモジュールに該当します。defaultテーマやdarkテーマのようにページ全体のカラーを変更する場合に使用します。多言語化対応のためのスタイル変更なども該当するでしょう。
* Scope - 例えばブログの投稿用のスタイルを要素セレクタに指定したい場合などに使用します。classセレクタと要素セレクタの子孫セレクタでスタイルを指定するため、classセレクタを要素ごとに指定する必要がなくなります。
* QA/Test - Quality Assurance(品質保証)、もしくはテストのための一時的なスタイルを定義するレイヤーです。

追加するレイヤーについては以下の記事を参考にします。

* [More Transparent UI Code with Namespaces – CSS Wizardry](http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/)
* [Managing CSS Projects with ITCSS](http://csswizardry.net/talks/2014/11/itcss-dafed.pdf)

レイヤーは以下のような構成にします。(Vendorsなど)レイヤーによっては子レイヤーではなく、親レイヤーとしてもいいでしょう。また、CSSフレームワークやJQueryプラグインなどの装飾的な要素を多く含むモジュールは追加する場所を変更しなければいけないかもしれません。

* Foundation
 * Variable
 * Function
 * Mixin
 * Vendors
 * Vendors-extension
 * Base
* Layout
* Object
 * Component
 * Project
 * Theme
 * Scope
 * QA/Test
 * Utility

FLOCSS以外では[ITCSS](https://speakerdeck.com/dafed/managing-css-projects-with-itcss)が候補としてあげられます。ITCSSはFLOCSSとほとんど同じ考えをもっています。ただし、英語のドキュメントであり、詳細な説明があまりないためFLOCSSのほうが導入がしやすいと考えています。

### Sassのパーシャル機能で@importする
Sassのパーシャルを使用するとファイルを機能ごとに分割して管理をして、CSSにコンパイルするときに指定した順序でアウトプットすることができます。

```scss
/* ==========================================================================
   Layout
   ========================================================================== */

@import "layout/_footer";
@import "layout/_header";
@import "layout/_main";
@import "layout/_sidebar";

/* ==========================================================================
   Object
   ========================================================================== */

/* Component
   ----------------------------------------------------------------- */

@import "object/component/_wrapper";
@import "object/component/_grid";
```

## シンタックスとフォーマッティング
CSSの構文はセレクタとブレース、プロパティと値からなっています。このルールセットに読みやすさを確保したフォーマット(書式)を定義します。

### ルールセットのフォーマット
ルールセットの基本的なフォーマットは以下の通りです。

* 複数のセレクタは別の行に(関連性があれば同じ行に指定してもいい)
* 最後のセレクタとオープニングブレースの間にスペースを1つ
* それぞれの宣言は別々の行に
* ルールセット内に空行は入れない
* プロパティの前にスペースを4つ(2つにしてもいい)
* コロン(`:`)と値の間にスペースを1つ
* クロージングブレースは独立した行に
* 各ルールセットの間に空行を1つ
* 関数はカンマ(`,`)と引数の間にスペースを1つ

```css
/* Good */
.foo, .foo--bar,
.baz {
    display: block;
    margin-right: auto;
    margin-left: auto;
    background-color: rgba(0, 0, 100, 0.8);
}

/* Bad */
.foo,
.foo--bar, .baz{
  display: block;margin-right: auto;
  margin-left:auto;
  background-color: rgba(0,0,100,0.8);}
```

### Sass使用時の追加ルール
Sassを使用している場合は以下のルールを追加します。

* ローカル変数を最初に定義します
* @extendをローカル変数の次に指定します
* @mixinを@extendの次に指定します
* @contentを使用している@mixinは最後に指定します

```scss
/* Good */
.foo, .foo--bar,
.baz {
    $padding: 1em;
    @extend %base-unit;
    @include clearfix;
    display: block;
    margin-right: auto;
    margin-left: auto;
    padding-right: $padding;
    padding-left: $padding;
    @include media-query(md) {
        padding-right: ($padding * 2);
        padding-left: ($padding * 2);
    }
}

/* Bad */
.foo,
.foo--bar, .baz{
  @include media-query(md) {
    padding-right: ($padding * 2);
    padding-left: ($padding * 2);
  }
  display: block;margin-right: auto;
  margin-left:auto;
  @extend %base-unit;
  @include clearfix;
  $padding: 1em;}
```

### 単一行ルールセットのフォーマット
原則的には複数行でルールセットを記述しますが、ユーティリティクラスなどの単一のスタイルの場合は1行で記述することを許容します。この場合は複数行よりも可読性に優れていると考えられるからです。

単一行のフォーマットは以下の通りです。

* 最後のセレクタとオープニングブレースの間にスペースを1つ
* オープニングブレースとプロパティの間にスペースを1つ
* コロン(`:`)と値の間にスペースを1つ
* セミコロン(`;`)とクロージングブレースの間にスペースを1つ
* 各ルールセットの間には空行を入れない

```css
/* Good */
.u-pos { position: static !important; }
.u-por { position: relative !important; }
.u-poa { position: absolute !important; }
.u-pof { position: fixed !important; }
```

### プロパティの宣言順
ルールセット内の宣言は重要なプロパティから書き始め、その機能ごとに固めて記述することで意図を素早く理解できるようにしましょう。プロパティの宣言順は以下のようなルールで記述するのを推奨します。

1. ボックスモデルの種類や表示方法を示すプロパティ(`box-sizing`, `display`, `visibility`, `float`など)
1. 位置情報に関するプロパティ(`position`, `z-index`など)
1. ボックスモデルのサイズに関するプロパティ(`width`, `height`, `margin`, `padding`, `border`など)
1. フォント関連のプロパティ(`font-size`, `line-height`など)
1. 色に関するプロパティ(`color`, `background-color`など)
1. それ以外

アルファベット順で記述することは禁止します。整列ではなく、理解しやすいように分類することが目的だからです。

```css
/* Good */
.foo {
    display: block;
    position: absolute;
    right: 0;
    bottom: 0;
    width: 100%;
    margin: 0;
    padding: 0;
    font-size: 0.75em;
    color: #000;
    background-color: #fff;
}

/* Bad */
.foo {
    background-color: #fff;
    bottom: 0;
    color: #000;
    display: block;
    font-size: 0.75em;
    margin: 0;
    padding: 0;
    position: absolute;
    right: 0;
    width: 100%;
}
```

### 個別指定プロパティの宣言順
例えば`margin`プロパティは`margin-top`や`margin-left`のように個別に方向を指定することもできます。このようなプロパティは規則性を持たせるため、時計回りに指定するのを推奨します(`position`プロパティの`top`や`left`も同様です)。

```css
/* Good */
.foo {
    margin-top: auto;
    margin-right: auto;
    margin-bottom: auto;
    margin-left: auto;
}

/* Bad */
.foo {
    margin-left: auto;
    margin-right: auto;
    margin-top: auto;
    margin-bottom: auto;
}
```

## コメント
コードの機能やルールの意図、目次やTODOを示すために積極的にコメントを使用しましょう。誰もが同じ知識を持っているわけではありませんし、必要なコードを誤って削除してしまう可能性を下げることができます。

### 目次(Table of Contents)
コードを書く前に目次を書きましょう。そしてコードを書いたら目次に追加しましょう。スタイルシートの全体像を把握するのを助けてくれますし、目次から目的のコードを検索することもできるようになります。レイヤーとその中のセクション(モジュール)を簡単な説明も加えて書いていきましょう。

```css
/**
 * VARIABLE
 * Global...............プロジェクト全体を通して使用される変数です。
 *
 * MIXIN
 * Media-query..........メディアクエリ用のmixinです。
 * Clearfix.............`float`を解除する`clearfix`のmixinです。
 *
 * BASE
 * Base.................要素セレクタと属性セレクタのデフォルトスタイルです。
 *
 * LAYOUT
 * Header...............ヘッダーエリアのコンテナブロックのスタイルを指定します。
 * Footer...............フッターエリアのコンテナブロックのスタイルを指定します。
 * Main.................メインコンテンツエリアのコンテナブロックのスタイルを指定します。
 * Sidebar..............サイドバーエリアのコンテナブロックのスタイルを指定します。
 *
 * COMPONENT
 * Wrapper..............コンポーネントをラップするオブジェクトです。`max-width`が指定されています。
 * Grid.................グリッドレイアウトのベーススタイルです。
 *
 * PROJECT
 * Tag-cloud............タグクラウドのコンポーネントです。
 *
 * UTILITY
 * Width................レスポンシブに対応した`width`を指定するためのヘルパークラスです。
 */
```

### セクションタイトル
目次とセクションタイトルは対(つい)になります。セクションタイトルに`#`を接頭辞として付けることで素早く検索することができるようになります。

```css
/**
 * #Grid
 */
```

### レイヤータイトル
FLOCSSでは3つのレイヤーと3つの子レイヤーで構成されます。Sassを使用していない場合は以下のようにコメントをします。

```css
/* ==========================================================================
   Layout
   ========================================================================== */
/**
 * #Footer
 */
 #footer {}
 
/**
 * #Header
 */
#header {}

/* ==========================================================================
   Object
   ========================================================================== */

/* Component
   ----------------------------------------------------------------- */

/**
 * #Wrapper
 */
 .c-wrapper {}
```

Sassを使用する場合は以下のようにコメントをしてインポートします。

```scss
/* ==========================================================================
   Layout
   ========================================================================== */

@import "layout/_footer";
@import "layout/_header";
@import "layout/_main";
// @import "layout/_sidebar";

/* ==========================================================================
   Object
   ========================================================================== */

/* Component
   ----------------------------------------------------------------- */

@import "object/component/_wrapper";
@import "object/component/_grid";
```

編集をしやすくするために、以下のようなルールで`@import`を使用します。

* 1つのファイルごとに@importを使用します
* @importごとに改行します
* 同じフォルダからのインポートの間には改行をしません
* 同じフォルダからの最後のインポートの後には改行をします
* ファイルの拡張子(.scss)を省略します

### コードの説明と参照リンク
そのコードが一部のひとにしか正しく理解されないと感じたらコメントを書きましょう。そして、詳しくコメントで説明できない場合は参照となるリンクを書きましょう。

```css
/**
 * ボックスモデルを`border-box`にリセットします。
 * https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
 */
html {
    box-sizing: border-box;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}
```

### マークアップ例
コンポーネントなど、頻繁に使用されるコードには簡単な説明とマークアップの例を書きましょう。

```css
/**
 * グリッドレイアウトオブジェクトです。
 * `width`はデフォルトで100%が指定されています。
 * ガターは左側にだけ指定されています。
 * `width`の変更は`Utility/_width.scss`のクラスを使用します。
 *
 * <div class="c-wrapper">
 *   <div class="c-grid c-grid--gutter-medium">
 *     <div class="c-grid__item u-8/12@md"></div>
 *     <div class="c-grid__item u-4/12@md"></div>
 *   </div>
 * </div>
 */
.c-grid {
    display: block;
    margin: 0;
    padding: 0;
    /* カラム間の余白を除去する */
    font-size: 0;
    list-style-type: none;
}

.c-grid__item {
    display: inline-block;
    width: 100%;
    /* フォントサイズを戻す */
    font-size: 1rem;
    vertical-align: top;
}
```

### Sassのコメント
Sassでは@functionや@mixinなど通常のCSSにはない機能があります。Sassを熟知していないひとのためにもコメントを書いて正しく理解してもらえるようにしましょう。以下は@mixinのコメント例です。

```scss
//
// #Media-query
//

// @desc - ブレイクポイントを挿入します。
// @type Mixin
// @param {String} $breakpoint - `$breakpoints`のkeyを渡します。
// @requires {Map} $breakpoints - ブレイクポイントを管理するためのmapです。
//
// @example scss - Usage
// .foo {
//     color: red;
//     @include media-query(sm) {
//         color: blue;
//     }
// }
//
// @example css - CSS output
// .foo {
//   color: red;
// }
// @media screen and (min-width: 400px) {
//   .foo {
//     color: blue;
//   }
// }
//
@mixin media-query($breakpoint) {
    @media #{map-get($breakpoints, $breakpoint)} {
        @content;
    }
}
```



## 命名規則
命名規則はBEMをベースにした[MindBEMding](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)の使用を推奨します。理由は名前から役割や関係性を明確にできるからです。これはコードを書く時でも読む時でも同様です。短く単純な名前より、長くても明快な名前の方が機能的で、誰にとっても使いやすいものになるはずです。

BEMはルールが厳格で導入が難しいと一般的には言われますが、ルールがあるからこそ理解しやすく、共通の認識を持つことができると考えています。

BEMについては以下のリンクを参考にしてください。

* <a href="https://github.com/juno/bem-methodology-ja/blob/master/definitions.md" target="_blank">bem-methodology-ja/definitions.md at master · juno/bem-methodology-ja</a>
* <a href="http://blog.ruedap.com/2013/10/29/block-element-modifier" target="_blank">BEMという命名規則とSass 3.3の新しい記法 - アインシュタインの電話番号</a>
* <a href="https://app.codegrid.net/entry/bem-basic-1" target="_blank">BEMによるフロントエンドの設計 - 基本概念とルール | CodeGrid</a>

### MindBEMding
BEMはBlock、Element、Modifierの3つの概念から構成され、以下のようなclass名になります。

```css
.block-name {}
.block-name__element-name {}
.block-name--modifierkey-value {}
.block-name__element-name--modifierkey-value {}
```

以下のようなルールがあります。

* 小文字の英単語とハイフン1つ(`-`)とハイフン2つ(`--`)、アンダースコア2つ(`__`)で構成されます
* BlockとElementとModifierの単語はハイフン1つ(`-`)でつなぎます
* Blockはできるだけ2つ以上の単語を合わせてユニークな名前にします
* ElementとModifierは1つの単語だけを使ってもかまいません
* ElementとModifierはBlockの名前を受け継ぎます
* BlockとElementはアンダースコア2つ(`__`)でつなぎます
* BlockとModiferもしくはElementとModiferはハイフン2つ(`--`)でつなぎます

よって以下のように短く書くこともできます。

```css
/* Good */
.block-name {}
.block-name__element {}
.block-name--modifier {}
.block-name__element--modifier {}
```

### BEMの注意点

#### Elementの連結をさせない
Elementの入れ子であることを示すためにElementの名前を連結させてはいけません。HTMLの構造を示すのではなく、Blockに対するElementとModifierの関係性を示すようにしましょう。例えば`sub`や`child`といった名前によって関係性を表しましょう。

```css
/* Good */
.block__element {}
.block__sub-element {}

/* Bad */
.block__element {}
.block__element__element {}
```

もしくは、入れ子のElementを別のBlockとして定義できないか考えましょう。Elementとして拡張するよりは、Blockを組み合わせたほうが拡張性が高くできることがあります。

#### マルチクラスを禁止にしない
「OOCSSはマルチクラスでBEMはシングルクラスだ」などと言われることがありますが、そういったことはありません。[Yandex](https://www.yandex.com/)のソースコードを見てもマルチクラスで指定されています。例えば同じHTML要素に異なるBlockやElementを指定したとしても妥当な指定方法です(OOCSSの構造と見た目を別々に指定したい時など)。

```html
<!-- Good -->
<div class="block1 block2">
  <div class="block1__element block2__element">
</div>
```

#### Blockを親セレクタにしない

詳細度を強くしたり、スコープを作るためにBlockを親セレクタにしてElementとModifierを指定しないようにしましょう。Blockの名前を継承することで擬似的にスコープを作るようにしましょう。詳細度はなるべくフラットに保ってカスケーディングのコントロールをしやすいようにします。

```css
/* Good */
.block {}
.block__element {}
.block--modifier {}

/* Bad */
.block {}
.block .block__element {}
.block .block--modifier {}
```

#### 他のBlockに依存させない
Blockは他のBlockに依存せず、単独で機能するようにしましょう。例えば、`Block1`のスタイルを変更するために`Block2`を親セレクタにして`Block1`を上書きするようなことはできるだけ避けましょう。同じ詳細度であれば、セレクタを加えなくても後から記述するだけで適応されます。

```css
/* Good */
.block1 {}
.block__element {}

.block2 {}

/* Bad */
.block1 {}
.block__element {}

.block2 .block1 {}
```

また、例えば`Block1`と`Block2`を左右に配置したい場合は、グリッドのようにレイアウトをするための`Block3`を定義するようにしましょう。Blockの機能を拡張しすぎたり、依存関係を作ってしまうよりも、Blockを組み合わせることでページを構築するようにします。

#### Sassのネストを制限する
Sassを使用している場合、ネストによってBEMの記述が楽になりますが、なるべく使用しないようにしましょう。理由はBlockに関連するルールセットが際限なくつながり、長くなることで可読性やメンテナンス性を損なう可能性が高いからです。

```scss
// Bad
.block {
    &__element {
        ...
    }
    &__element {
        ...
    }
    &__element {
        ...
    }
    &--modifier {
        ...
    }
    &__element {
        ...
    }
    &__element {
        &--modifier {
            ...
        }
    }
}
```

また、ネストを深くしすぎると、HTMLのclass属性から該当するスタイルを検索するときに支障をきたす可能性が増します。速く書くよりも、読みやすくメンテナンスしやすくなるようにしましょう。

### 接頭辞(Prefix)
接頭辞(Prefix)をclassセレクタとIDセレクタに使用することで、名前が重複する可能性を下げたり、その役割を簡潔に示すことができます。FLOCSSで定義されている接頭辞に以下のような接頭辞を加えて使用するのを推奨します。

* `c-` Componentレイヤーのコンポーネントあることを示します
* `p-` Projectレイヤーのコンポーネントであることを示します
* `u-` Utilityレイヤーのコンポーネントであることを示します
* `js-` JavaScriptのフックとして使用されるclassやIDであることを示します(CSSでスタイルは指定しない)
* `is-`, `has-` 要素の表示の切り替えなどの状態の変化があることを示します
* `t-` Themeレイヤーのコンポーネントであることを示します。
* `s-` Scopeレイヤーのコンポーネントであることを示します。
* `qa-`, `t-` QA/Testレイヤーのコンポーネントであることを示します。

役割ではなく、プロジェクトの名前やバージョンを示すために接頭辞をつけるのも有効です。例えば`.pj-`(project)のようにプロジェクト名を短縮させたり、`.pj02-`のようなバージョンをつけると重複を避けることができます。

接頭辞をつけることはスタイルの追加をより安全にしたり、他のCSSフレームワークやライブラリと共存するベターな方法です。

### 接尾辞(Suffix)
classに`-sm`や`-md`などを付与してブレイクポイントを指定していることを示すことがあります。規則性をもたせるためにクラス名の最後に接尾辞を付けることを推奨します。より明示的に名前をつけるために`@`を接尾辞として使用してもいいでしょう。

```css
/* Good */
@media (min-width: 768px) {
    .u-col1of3\@md { width: width: 33.33333% !important; }
    .u-col2of3\@md { width: width: 66.66667% !important; }
    .u-col3of3\@md { width: width: 100% !important; }
}
```

`@`をスタイルシートで指定する際にはバックスラッシュ(`\`)でのエスケープが必要ですが、HTMLで指定する際にはエスケープは必要ありません。詳しくは以下の記事を参照してください。

[BEMIT: Taking the BEM Naming Convention a Step Further | CSS Wizardry](http://csswizardry.com/2015/08/bemit-taking-the-bem-naming-convention-a-step-further/)

### 単語の省略を制限する
意味が汲み取れない単語の省略は禁止します。例えば`navigation`を`nav`と省略することは許容しますが、`title`を`ttl`と省略するのは意味が読み取れませんし、ほとんど短くなってもいません。基本的には省略をせずに名前をつけましょう。

```css
/* Good */
.navigation {}
.title {}
.text {}
.icon {}

/* allow */
.nav {}

/* Bad */
.ttl {}
.txt {}
.ico {}
```

省略する場合にはドキュメントに残すことを推奨します。認識を共有することもできますし、`nav`と`navi`が混在してしまうようなことを防ぐこともできます。

### 絶対値を表すクラス名を避ける
`.mb10`のような値を固定した名前をつけることを禁止します。理解はしやすい名前ですが、値を変更したい場合にHTMLに記述したclass属性も変更する必要が出てきます。こうした変更に柔軟に対応するために`.mbs`(margin-bottom smallの意味)のような相対的な名前をつけましょう。

```css
/* Good */
.mbs { margin-bottom: 10px; }

/* Bad */
.mb10 { margin-bottom: 10px; }
```

また、`small`, `medium`, `large`のようなパターンに制限するルールを設けることで、際限なくサイズ違いが増えてしまうことを防ぐこともできます。

カラーネーム(`.red`や`.blue`)のようなクラス名も禁止します。ある要素の色を変更したい場合にクラス名と値の意味が合わなくなってしまい、class属性を変更しなくてはいけなくなることが考えられるからです。`.success`や`.brand`のような値を変更しても意図が変わらない名前にしましょう。

```css
/* Good */
.brand {}
.success {}

/* Bad */
.red {}
.blue {}
```

## セレクタ
### インライン記述を使用しない
HTMLの`style`属性に直接スタイルを記述するインライン記述は使用を禁止します。理由はスタイルシートで一括管理できないこと、詳細度が高いこと、HTMLのファイルサイズを無闇に増やしてしまうこと、単一のスタイルごとしか指定できない(レスポンシブに対応できない)からです。

```html
<!-- Bad -->
<div style="color:red; background-color: black;"></div>
```

JavaScriptによるインラインでのスタイル追加もできるだけ避けて、classを追加するようにします。

### HTML(DOM)構造に依存させない
マークアップは変更される可能性があります。例えば`article`を`section`にしたり`h2`を`h3`に変更するかもしれません。特定のHTML要素に依存したセレクタを指定している場合はその都度変更しなくてはいけません。

```css
/* Bad */
article h2 {}
```

classを使ったセレクタを定義していればHTML構造が変更されたとしても、CSSを変更する必要がなくなり、可搬性が高まります。

```css
/* `article`要素の見出しに指定するクラス */
.article__title {}

/* 汎用的な見出しのクラスを用意 */
.u-h2 {}
```

### 不要な要素セレクタを連結させない
classやIDセレクタで指定する時に要素セレクタを連結させるのは詳細度を高めるだけで意味がありません。

```css
/* Good */
.foo {}

/* Bad */
h2.foo {}
```

もし、特定の要素に指定してほしいのであれば、コメントによってそれを示しましょう。

```css
/* Good */
/* h2要素に指定してください。 */
.foo {}

/* h2 */.foo {}
```

### セレクタを短くする
セレクタは必ずしもHTML構造に沿う必要はありません。場合によってはセレクタを短くすることで詳細度を低く抑えることができます。

```css
/* Good */
ul a {}
th {}

/* Bad */
ul li a {}
table th {}
```

### セマンティックでないセレクタの指定を制限する
特定の意味を持たないセレクタ(`div`, `span`)は使用される範囲も広いため、セレクタに対する影響範囲も広くなります。使用する場合はできるだけ範囲を狭くして指定してください(classセレクタで指定するのが望ましいです)。また、単体でのセレクタは禁止とします。

```css
/* Good */
.foo > div {}
.foo > span {}

/* Bad */
div {}
span {}
.foo div {}
.foo span {}
```

### 拡張できるようにオブジェクトを定義する
保守性や拡張性を高めるために構造を含んだベースになるclassを定義し、装飾的なclassで拡張するようにしましょう。ベースになるスタイルを変更したい場合でも1箇所変更するだけでよくなりますし、拡張するclassにも最低限のスタイルを追加するだけになります。

1つのclassでまとめて指定してしまうと、バリエーションが増えるごとに同じスタイルを何回も指定することになってしまいます。ベースになるスタイルを変更したい場合に何箇所も変更する必要も出てきます。

下記の例ではベースになるclassの`.p-alert`に装飾的なスタイルが指定されていますが、オブジェクトの特性上、問題はごくわずかだと判断しています。

```html
<!-- Good -->
<p class="p-alert"></p>
<p class="p-alert p-alert--success"></p>
<p class="p-alert p-alert--error"></p>
```

```css
/* Good */
.p-alert {
    padding: 1em;
    border: 1px solid #e7edf0;
    border-radius: 3px;
    color: #47525d;
    background-color: #f7f9fa;
}

.p-alert--success {
    border-color: #d9f4e1;
    color: #2c683f;
    background-color: #edfaf1;
}

.p-alert--error {
    border-color: #ffcaca;
    color: #921515;
    background-color: #ffe3e3;
}

/* Bad */
.p-alert-default {
    padding: 1em;
    border: 1px solid #e7edf0;
    border-radius: 3px;
    color: #47525d;
    background-color: #f7f9fa;
}

.p-alert-success {
    padding: 1em;
    border: 1px solid #d9f4e1;
    border-radius: 3px;
    color: #2c683f;
    background-color: #edfaf1;
}

.p-alert-error {
    padding: 1em;
    border: 1px solid #ffcaca;
    border-radius: 3px;
    color: #921515;
    background-color: #ffe3e3;
}
```

### State単体にスタイルを指定しない
[SMACSS](http://shop.smacss.com/)というCSSの設計手法にState(ステート)という状態をあらわすルールがあります。例えば`.is-open`というclassはある要素を開いた状態にするために使用されます。

このStateに単体でスタイルをもたせないようにしましょう。Stateはコンポーネントに対して指定するようにして、影響範囲を制限しましょう。

```css
/* Good */
.foo.is-open {}

/* Bad */
.is-open {}
```

### IDセレクタを多用しない
CSSはカスケーディングをコントロールしなければ、すぐに破綻してしまいます。IDセレクタは詳細度が圧倒的に高いことや、ページ内に1度しか使用できないため再利用性にも欠けます。classではなくIDで指定する理由が明確に説明できる場合にのみ使用しましょう。

CSSのIDセレクタとHTMLのid属性とは区別して考えます。id属性はページ内リンクやJavaScriptでのフックとして利用される場合があるためです。

### メディアクエリをまとめて管理しない
ファイル容量の削減のためにメディアクエリをブレイクポイントごとにまとめて記述することを禁止します。

```css
/* Good */
.foo {}

@media screen and (min-width: 768px) {
    .foo {}
}

/* Bad */
@media screen and (min-width: 768px) {
    .foo {}
    .bar {}
    .baz {}
}
```

同じ目的のオブジェクトは同じ場所(Sassの場合は同じファイル)に記述するようにしましょう。全体像の把握を難しくさせたり、モジュール(ある機能のひとまとまり)として管理するのを難しくさせます。短期的なパフォーマンスよりも見通しの良さやメンテナンス性を重視しましょう。

## プロパティ
### !importantを多用している
`!important`は基本的に使用を禁止しますが、意図的に使用する場合は許容されます。例えばヘルパークラスは確実に適応させるために使用することがあります。

```css
/* Good */
.u-col1of12 { width: 8.33333% !important; }
.u-col2of12 { width: 16.66667% !important; }
.u-col3of12 { width: 25% !important; }
```

その場合もスタイルシートの終盤に記述をして、影響範囲を抑えましょう。

### スタイルを取り消している
スタイルの取り消しとは、あるスタイルを`0`や`none`などで値をリセットすることです。スタイルの取り消しがあった場合は多くのスタイルを持ちすぎている、スタイルを早く指定してしまっていることが考えられます(リセットCSSは除く)。

```css
/* Bad */
.foo {
    border: 1px solid #ddd;
}

/* ある要素内ではボーダーが邪魔になるためリセット */
.bar .foo {
    border: none;
}
```

Modifierで定義しておくと必要な時にだけ指定することができます。

```css
/* Good */
.foo {}
.foo--bordered {
    border: 1px solid #ddd;
}
```

### 要素セレクタに装飾的なスタイルを指定しない
`h1`や`p`といったセマンティックな要素セレクタには装飾的なスタイルを指定してはいけません。必ずあとでスタイルを取り消すことになります。

```css
/* Bad */
h2 {
    padding-bottom: 0.5em;
    border-bottom: 1px solid #888;
}
```

要素セレクタにはブラウザのデフォルトスタイルシートやリセットCSSで指定されるような最低限のスタイルにとどめておきましょう。

```css
/* Good */
h2 {
    font-size: 2rem;
    line-height: 1.2;
    margin-top: 0;
    margin-bottom: 24px;
}
```


### 高さを指定しない
閲覧されるデバイスによって同じコンテンツであっても横幅が変わるため高さも可変します。高さを指定しているとコンテンツが隠れてしまったり、余分な余白ができてしまいます。

```css
/* Bad */
.foo {
    height: 1000px;
}
```

高さは指定せず、コンテンツによって決まるものと考えましょう。ロゴなどの特定のサイズを持ったものはこれに当たりません。

### 固定の幅を持たせない
コンテンツブロックは基本的に固有の幅を持つことを禁止します。`width`を固定していると、ある場所では幅が足りず、ある場所でははみ出てしまうなどの弊害が出ます。横幅は可変するようにしておいて、コンテナブロックによってサイズが決まるようにしておきます。

幅を指定したい時は、コンテナブロックに`max-width`を指定する、`width`のヘルパークラスを使用する、Modifierでサイズを指定するなどの方法があります。

```css
/* Good */
.c-button {}

.c-wrapper {
    max-width: 1200px;
}
.c-button--size-full {
    width: 100%;
}

/* Bad */
.c-button {
    width: 300px;
}
```

### カラーコードは短縮させる
`color`プロパティなどで色を指定する時は可読性をあげるために、可能な場合は短縮しましょう。

```css
/* Good */
.foo { color: #ddd; }

/* Bad */
.foo { color: #dddddd; }
```

### 文字列には引用符(ダブルクォート)をつける
`content`プロパティやURLの指定、属性セレクタの指定をする時にはダブルクウォートを使用しましょう。

```css
/* Good */
.foo {
    content: "this is content";
    background: url("logo.png");
}
input[type="submit"] {}

/* Bad */
.foo {
    content: 'this is content';
    background: url(logo.png);
}
input[type=submit] {}
input[type='submit'] {}
```

### 0に単位をつけない
値が0の場合はpxや%といった単位は必要がないため使用しません。

```css
/* Good */
.foo { margin: 0; }

/* Bad */
.foo { margin: 0px; }
```

### 小数点のあたまの0を省略しない
`0.5em`などの小数点の前の0は省略しません。ファイルサイズの削減は考えずに、明示的に指定しましょう。

```css
/* Good */
.foo { font-size: 0.5em; }

/* Bad */
.foo { font-size: .5em; }
```

### すべて小文字で記述する
プロパティとプロパティ値は大文字でも小文字でも同様に扱われますが、小文字に統一しましょう。

```css
/* Good */
.foo { color: #fff; }

/* Bad */
.foo { COLOR: #FFF; }
```

### ショートハンドはなるべく避ける
`font-size`や`margin`などショートハンドが用意されているプロパティがありますが、ショートハンドに指定しなかったプロパティに初期値が渡されてしまうことから意図せずプロパティがリセットされてしまったり、指定する必要がないところにまで指定する必要が出てきます。明示的に何が目的なのかを示すという意味でも使用をなるべく避けましょう。

```css
/* Good */
.foo { 
    /* 中央配置にする。 */
    margin-right: auto;
    margin-left: auto;
}

/* Bad */
/* 上下を0に指定する必要がない。 */
.foo { margin: 0 auto; }
```

### ベンダープレフィックスは手動で書かない
`-webkit-`や`-moz-`などのベンダープレフィックスは手動で書かず、[Autoprefixer](https://github.com/postcss/autoprefixer)を使用しましょう。Sassの@mixinを使用する方法もありますが、@mixinを管理する手間が発生します。Gulpなどの環境が使えない場合は[Prepros](https://prepros.io/)を推奨します。


## Sass
BootstrapやFoundaitonなどのCSSフレームワークでも使われているようにSassを利用してCSSを書くことがデファクトスタンダードになっています。Sass特有の機能にいくつかのルールを設けます。

### SCSS記法を使う
Sassには拡張子が.sassのSASS記法と拡張子が.scssのSCSS記法があります。どちらも一長一短がありますが、SCSS記法を使うことを推奨します。SCSS記法であればCSSの構文とほとんど変わらないので、誰にとっても読みやすいからです。また、SCSS記法の方がよく使われている(CSSフレームワークはほとんどがSCSS記法で書かれている)ので、ソースコードの流用がしやすいこともメリットです。

また、jQueryプラグインなどを使う時もデフォルトのCSSファイルの拡張子を.scssに変更するだけでインポートできるようになります。

### 機能ごとにコードを分割する
SassにはCSSとしてアウトプットさせないファイルを定義するパーシャルという機能があります。コードをファイルごとに分割してモジュール化して管理しましょう。scssファイルをアンダースコア(`_`)から始めることでパーシャルファイルとして認識されます。

```scss
// パーシャルファイルをインポートする
@import "_grid";

// インポートしない場合
// @import "_grid";
```

スタイルシートのアウトプットする場所を指定することでカスケーディングを管理しやすくなったり、使うファイルだけインポートすることができます。

### 変数は繰り返しや演算する場合にだけ使用する
Sassの変数は特定の値を一括で管理できる便利な機能ですが、使いすぎると可読性を損なったり変数名がバッティングする危険性が増します。同じ値を繰り返し指定する場合や四則演算などで値を変更・再計算する場合にだけ定義しましょう。

```scss
// Good
$unit-base: 1em !dafault;
.foo {
    margin-left: (-$unit-base);
}
.foo__bar {
    padding-left: $unit-base;
}

// Bad
$foo-unit: 1em !dafault;;
.foo {
    padding: $foo-unit;
}
```

CSSフレームワークでは大量の変数が定義されています。これは、コードを変更・追加せずに変数でスタイルを変更するためです。通常のスタイルシートではこういった機能はいらない場合がほとんどでしょう。

### モジュール内でだけ使用する変数は個別に定義する
モジュール内で、ある変数や値が繰り返し使用されている場合はモジュール専用の変数を定義しましょう。プロジェクト全体で使用される変数に変更があった場合でも各モジュールで対応できるようにしておきます。

```scss
// Good
$unit-base: 1em !default;

/**
 * #Media
 */
$media-gutter: $unit-base !default;
```

### 変数だけでなくキーワードや相対値を利用する
数値やカラーは必ずしも変数で固定値を指定する必要はありません。例えば親要素の計算値を継承する[inherit](https://developer.mozilla.org/ja/docs/Web/CSS/inherit)キーワードやプロパティの初期値を指定する[initial](https://developer.mozilla.org/ja/docs/Web/CSS/initial)キーワード、同じ要素の`color`プロパティを取り込む[currentColor](http://www.hcn.zaq.ne.jp/___/WEB/css-color-ja.html#currentcolor-color)キーワードなどがあります。

数値([length](https://developer.mozilla.org/ja/docs/Web/CSS/Length))を指定するときも`px`のような絶対値で指定するよりも、当該要素のフォントサイズを基準にする`em`やルート要素(通常は`html`要素)のフォントサイズを基準にする`rem`のような相対値で指定したほうが柔軟に対応することができます。

### 変数には!defaultフラグを必ず指定する
変数を定義する際には`!default`フラグを必ず指定するようにしましょう。その変数が定義されているファイルより先に同じ変数を定義し直すことで変数の値を確実に上書きすることができます。これによって変数をまとめて管理することが可能になります(必ずしもまとめて変更する必要はなく、あくまでオプションです)。

```scss
// Good
$unit-base: 1em !default;

// Bad
$unit-base: 1em;
```

### 直接的な変数名は用途をあらわす変数名に格納する
カラーパレットとして`$color-red`のような変数名をつける場合は(例えば`$color-error`のような)用途をあらわす変数名にいったん格納してから指定するようにしましょう。値を変更したい場合にも一箇所を書き換えるだけで済むようになりますし、変数名と値が矛盾することを避けることができます。ハードコード(特定の状況に固定してしまうこと)は避けて、常に変更がしやすいようにしておきましょう。

```scss
// Good
$color-red: red;
$color-error: $color-red;
.foo { color: $color-error; }

// Bad
$color-red: red;
.foo { color: $color-red; }
```

### 変数や関数に名前空間をつける
BootstrapやBourbonといったフレームワークやライブラリを併用した時に変数や関数の名前の衝突が起きないように、名前空間(namespace)をつけましょう。冗長にはなってしまいますが、確実に指定することができるようになります。

```scss
// Good
$my-variable: "variable";
@funciton my-function() {}
@mixin my-mixin() {}

// Bad
$variable: "variable";
@funciton function() {}
@mixin mixin() {}
```

### ネストは擬似要素やメディアクエリだけに制限する
兄弟セレクタやBEMのElementやModifierを指定するためにSassのネストは便利です。ですが、ネストを制限なく使用すると際限なく縦に長くなってしまい、可読性を損ないます。ネストは擬似要素、擬似クラス、メディアクエリの使用にとどめます。

```scss
// Good
.foo {
    &:hover,
    &:focus {
        ...
    }
    @media (min-width: 768px) {
        ...
    }
}

// Bad
.foo {
    &__bar {
        ...
        ...
        ...
    }
    &__baz {
        ...
        ...
        ...
    }
}
```

ネストするセレクタが明確に関係している場合はネストの使用を許容します。別々のルールセットにして記述するよりも理解しやすいと考えられるためです。

```scss
// Good
.foo--gutter-medium {
    margin-left: - $foo-gutter;
    > .foo__item {
        padding-left: $foo-gutter;
    }
}
```

### 数値の計算には括弧()を常に使う
Sassでは四則演算を使うことができます。複数の数値を計算させるときに想定外の計算結果になってしまうことを防ぐために括弧`()`で囲いましょう。

```scss
// Good
.foo {
    width: (100% / 3);
}

// Bad
.foo {
    width: 100% / 3;
}
```

### extendはできるだけ使用しない
extendは継承を可能にするため、Sassファイル内を簡潔にできます。しかし、継承元のセレクタを記述した場所にまとめて出力されるため、カスケーディングを複雑にしてしまう可能性があります。また、CSSにコンパイルした時に膨大なセレクタのついたルールセットができてしまうことで可読性を失う可能性があります。

もし使用するのであれば、同じモジュール内で完結させるか、継承元のセレクタを1つのモジュールにまとめてカスケーディングを管理しやすいようにしましょう。

### 更新用のCSSファイルを作成する
Sassを使えないクライアントがCSSファイルを変更する可能性がある場合は、クライアントがスタイルを追加するためのCSSファイルを作成しておくと管理がしやすくなります。

また、そのような場合にはextendは極力使用しないようにして、読みやすいCSSファイルになるようにしましょう。


================================================
FILE: how-to-bem.md
================================================
# BEM(MindBEMding)によるCSS設計

## BEMとは?

[BEM](https://github.com/juno/bem-methodology-ja/blob/master/definitions.md)は[Yandex](https://www.yandex.com/)という主にロシア人で構成される、検索エンジンなどを作っている企業が使っているCSSの設計方法です。[BEM Tools](https://github.com/bem/bem-tools)という、jsonでデータを管理してBEMの規則に則ったHTMLを生成する仕組みによってサイトが管理されているようです。

<a href="http://geckotang.tumblr.com/post/68662389684/bem%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AB%E8%A7%A6%E3%82%8C%E3%81%A6%E3%81%BF%E3%82%8B">BEMツールに触れてみる - < /gecko ></a>

命名規則はBEMから派生した[MindBEMding](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)の方が広く使われているので、MindBEMdingをベースに考えていきます。

MindBEMdingは[csswizardryことHarry Roberts](https://github.com/csswizardry)が提唱したCSSの命名規則のことです。Harry RobertsはCSS界では世界的に有名で、コンサルタントやスピーカーとして世界中で活躍されています。

* [CSS-Guidelines](http://cssguidelin.es/)
* [csswizardry-grids](https://github.com/csswizardry/csswizardry-grids)
* [inuitcss](https://github.com/inuitcss/inuitcss)

---

これ以降の内容は忠実なBEMの方法論ではなく、BEMの考え方にいくつかのアイデアを加えたものになります。  
公式ドキュメントは日本語に翻訳された[bem-methodology-ja](https://github.com/juno/bem-methodology-ja/blob/master/definitions.md)が公開されています。

## BEMの概念
BEMはブロック(Block)、エレメント(Element)、モディファイア(Modifier)の頭文字をとったものです。  
Blockはあるパーツ(コンポーネント)の親要素です。BlockはElementと呼ばれる子孫要素を持つことができます。Modifierはバリエーションや状態を変化させるときに指定するもので、BlockかElementと同階層に指定します。

命名規則はハイフン2つやアンダースコア2つでつなげます。

* `.Block`
* `.Block__Element`
* `.Block--Modifier`
* `.Block__Element--Modifier`

詳しい説明は後述します。

### Block(親要素)
Blockはサイトを構成するパーツのことです。例えばボタン、グリッド、タブ、見出し、画像などで、簡単に言ってしまえばパーツの親要素です。BEMではBlockを起点として考え、サイトはBlockを組み合わせることで構成していきます。

例えばブロック要素で余白を持ったシンプルなBlockの`.box`を作りました。

```scss
.box {
  display: block;
  padding: 1em;
}
```

ボタンもBlockとして考えることができます。ここではボタンのベースになるスタイルだけを持っています。

```scss
.button {
  display: inline-block;
  margin: 0;
  padding: 0.75em;
  border: none;
  border-radius: 3px;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  background: transparent;
  cursor: pointer;
  appearance: none;
  &:hover,
  &:active,
  &:focus {
    text-decoration: none;
  }
  &:disabled,
  &.is-disabled {
    opacity: 0.5;
    pointer-events: none;
  }
}
```

2つのBlock(`.box`と`.button`)を組み合わせて1つのパーツを作ることもできます。

```html
<div class="box">
  <a href="#" class="button"></a>
</div>
```

### Element(子孫要素)
ElementはBlockを構成するパーツの1つ1つのことです。例えばグリッドを構成するカラム、タブのボタンやコンテンツ部分、見出しや画像などです。

BEMではBlock(親要素)から見て下の階層にいる要素はすべてElement(子孫要素)として扱います。なので、Blockは1つしかありませんし、Elementは0個以上から構成されます。

クラス名は`.block__element`のようにBlockの名前を引き継いでアンダースコア2つでつなぎます。

例えばグリッドレイアウトであれば、`.grid`がBlockになり、`.grid__item`がElementになります。

```scss
.grid {
  display: block;
  margin: 0;
  padding: 0;
  font-size: 0;
  list-style-type: none;
}

.grid__item {
  display: inline-block;
  width: 100%;
  font-size: medium;
  font-size: 1rem;
  vertical-align: top;
}
```

先ほどの`.box`というBlockのElementとしてボタンを定義しました。Block特有のスタイルがある場合は`Block__Element`として定義します。

```html
<!-- OK -->
<div class="box">
  <div class="box__button">
    <a href="#" class="box__button-item">button</a>
  </div>
</div>
```

ボタンのベーススタイルを持っている`.button`というBlockをマルチクラスで指定しました。`.box__button-item`は色やサイズなどの装飾的な指定をするだけでよくなりました。

```html
<!-- Good -->
<div class="box">
  <div class="box__button">
    <a href="#" class="button box__button-item">button</a>
  </div>
</div>
```

### Modifier(バリエーション)
ModifierはBlockとElementのバリエーションや状態の変化をつくるときに指定します。

クラス名は`.block__element--modifier`か`.block--modifier`のようにBlockとElementの名前を引き継ぎ、ハイフン2つでつなぎます。Modifier名は以下のようにつけるといいでしょう。

* `Block--small` - あるBlockの余白やサイズなどが小さいバージョン
* `Block--pad-small` - あるBlockの`padding`が小さいバージョン
* `Block--item-small` - Block内の`item`というElementが小さいバージョン

例えば`.box`というBlockに背景色をつけたパターンが出てきたとします。

```scss
.box {
  display: block;
  padding: 1em;
}
```

Block自体ではなく、Blockに背景色を持たせるためのModifierを作ります。

```scss
.box--highlight {
  background-color: gray;
}
```

これで、元のBlockのスタイルを変更することなく、背景色をつけたパターンを作ることができました。HTMLはこのようにマルチクラスで指定することになります。

```html
<div class="box box--heightlight">
</div>
```

基本的にリセットしていくよりも、足していくようにすると管理しやすくなります。

```scss
/* NG */
.box {
  display: block;
  padding: 1em;
  background-color: gray;
}

.box--no-highlight {
  background-color: transparent;
}
```

このパターンはOOCSSの原則のひとつである「構造と見た目の分離」と同じことをしています。つまり、BEMとOOCSSは組み合わせることもできます。

## BEMのメリット

### 採用するメリットと導入コスト
BEMの概念や命名規則の方法など、導入するためのコストは必要です。ですが、BEMのルールは基本的に案件ごとに変わることはないので、導入コストは最初の案件だけに限られると思います。

また、逆にルールがあるということは、自分で考える必要がないということです。自分で考えるはずだった時間を、他の重要なことに使えます。後述する命名規則の明確さもメリットのひとつです。

基本的なルールが決まっていること、ルールを共通言語にすることでコミュニケーションを円滑にできること。BEMを採用するメリットはこのあたりにあるのかなと思います。

### 命名規則の明確さ
BEMを使うメリットのひとつにクラス名からクラスが持っている役割が伝わりやすいことがあります。

クラス名の単語をハイフンやアンダースコアで区切ると、

```scss
.widget-list {}
.widget_list {}
```

のようになり、ウィジェットリストなのか、ウィジェットの中にあるリストなのか、人によって解釈が変わってしまう恐れがあります。

BEMであれば、ウィジェットリストなら

```scss
.widget-list {}
```

になりますし、ウィジェットの中にあるリストなら、

```scss
.widget__list {}
```

のようにクラス名だけで判断することができます。

---

BootstrapやFoundationがハイフン区切りでも問題がないのは、

* フレームワークとして完成した状態で使うことを前提としているのでブレない
* ドキュメントが充実している

ことがあげられます。実際の案件ではじめからこの条件を満たすことはまずできません。いちから組んでいってもブレにくいルールが必要になります。

#### 命名規則のアレンジ
BEMのクラス名はBlockの名前を引き継いだりハイフン2つやアンダースコア2つで区切ること、マルチクラス(複数のクラスを指定すること)を前提していることから、class属性の指定が長くなりがちです。

クラス名をなるべく短くするために、命名規則を案件ごとに微調整することがよくあります。命名規則には3つのパターンがあります。

1つ目、通常は`block-name`のように単語をハイフンで区切ります。

```scss
.block-name {}
.block-name__element {}
.block-name--modifier {}
```

2つ目、単語をローワーキャメルケースにした場合。

```scss
.blockName {}
.blockName__element {}
.blockName--modifier {}
```

3つ目、単語をローワーキャメルケースにして、区切り文字を1つにした場合。

```scss
.blockName {}
.blockName_element {}
.blockName-modifier {}
```

Elementが複数の単語からなっている場合はより短くできます。

```scss
.block-name__element-name {}
.blockName__elementName {} // 2文字少ない
.blockName_elementName {} // 3文字少ない
```

## BEMの基本ルール

### クラスセレクタ単体に指定する
BEMではIDセレクタや要素セレクタは使用せず、クラスセレクタで指定します。

```scss
/* Good */
.block-name {}
.block-name__element {}
.block-name--modifier {}
```

クラスセレクタ単体にスタイルを指定していくので、詳細度は0,0,1,0のままになります。`!important`を使うこともほとんどありません。

IDセレクタを使わないのはページ内で使い回せるようにするためです。

```scss
/* NG */
#block {} // ページ内で1つしか使えない
#block__element {} // Elementが2つ以上ある場合に使えない
#block--modifier {}
```

要素を使わないのは影響範囲を限定させるためです。HTMLタグを限定させないことで使い回しをしやすくできるメリットもあります。

```scss
/* NG */
.block > p {} // Block直下の`<p>`すべてに適応されてしまう
```	

案件によってルールを緩くした方が運用しやすいこともあります。どこまで厳密にするかは案件の規模、制作者の人数やレベル、運用をするひとのレベルなどから決めるといいでしょう。

### ElementとModiferを単体で使用しない
「ここは`.box__element`と同じデザインだから、`.box__element`だけ持ってこよう。」と考えてはいけません。ElementとModifierは親となるBlockの中でだけ指定することができます。

```html
<!-- NG -->
<div class="foo">
  <div class="box__element"></div>
  <div class="box__element"></div>
</div>
```

`.box__element`が汎用的に使えるのであれば、`.box__element`ではなく、別のBlockとして定義しましょう。今は`.box__element`は汎用的に使えるかもしれませんが、スタイルが変更される可能性もあります。

## BEMのよくある問題

### Element__Element
BEMでは必然的にElementの数が多くなります。Blockから見て孫要素ができることもあります。このときに`.block__element__element`のようなクラス名にしているケースがあります。

```html
<!-- NG -->
<div class="box">
  <div class="box__element">
    <div class="box__element__element">
    </div>
  </div>
</div>
```
BEMはHTMLの構造をElementによって表す必要はありません。`child-element`のような名前にしても伝わりますし、より具体的です。

```html
<!-- Good -->
<div class="box">
  <div class="box__element">
    <div class="box__child-element">
    </div>
  </div>
</div>
```

例えば多階層のナビゲーションを`element__element`でマークアップした場合、極端な例かもしれませんがこのように階層が深くなるごとに名前が長くなってしまいます。

```html
<!-- NG -->
<ul class="nav">
  <li class="nav__item">
    <ul class="nav__item__items">
      <li class="nav__item__items__item"><a href="#" class="nav__item__items__link"></a></li>
      <li class="nav__items__items__item"><a href="#" class="nav__item__items__link"></a></li>
    </ul>
  </li>

  <li class="nav__item">
    <ul class="nav__item__items">
      <li class="nav__item__items__item"><a href="#" class="nav__item__items__link"></a></li>
      <li class="nav__items__items__item"><a href="#" class="nav__item__items__link"></a></li>
    </ul>
  </li>

</ul>
```

僕なら以下のようにマークアップします。`.nav__items`の子要素は`.nav__child-items`のように`child`をつけています。`.nav__child-items`の子要素は`.nav__child-item`のように`s`を抜いて名前をつけています。


```html
<!-- Good -->
<ul class="nav">
  <li class="nav__items">
    <ul class="nav__child-items">
      <li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
      <li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
    </ul>
  </li>

  <li class="nav__items">
    <ul class="nav__child-items">
      <li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
      <li class="nav__child-item"><a href="#" class="nav__child-link"></a></li>
    </ul>
  </li>

</ul>
```

階層が深くなっても2つの単語で収めるようにできればコードが読みやすくなると思います。Blockという名前のスコープがあるので、意味が理解しやすい範囲でBlock内で重複しなければ十分です。

なるべく階層が深くならないようにBlockを組み合わせて使うようにすると、名前の付け方はシンプルになると思います。

例えば、上記のナビゲーションをラップする`<nav>`要素には`.g-nav`のようなレイアウトを担当するクラス、スマホでハンバーガーボタンがあるなら`.nav-toggle`のようにBlockを分けて、組み合わせることで名前やコードが複雑になるのを避けることができます。

```html
<!-- Good -->
<nav class="g-nav">
  <div class="g-nav__navigation">
    <ul class="nav">
      <li class="nav__items">
        <ul class="nav__child-items"></ul>
      </li>
    </ul>
  </div>

  <div class="g-nav__toggle">
    <div class="nav-toggle">
      <span class="nav-toggle__item"></span>
      <span class="nav-toggle__item"></span>
      <span class="nav-toggle__item"></span>
    </div>
  </div>
</nav>
```

### Block__Element--Modifier
例えばElementの`padding`を変更するModifierを作りたい場合、すべてのElementにModifierを指定するのは冗長で指定忘れが出てしまったりするかもしれません。

```html
<!-- NG -->
<div class="box">
  <div class="box__element box__element--pad-large"></div>
  <div class="box__element box__element--pad-large"></div>
</div>
```

```scss
.box__element {
  padding: 1em;
}

.box__element--pad-large {
  padding: 2em;
}
```

このパターンにはBlock--Modiferを起点にしてスタイルを指定する方が運用しやすくなります。直下の要素として指定したりして、影響範囲をできるだけ抑えるようにしておきます。

```html
<!-- Good -->
<div class="box box--pad-large">
  <div class="box__element"></div>
  <div class="box__element"></div>
</div>
```

```scss
.box__element {
  padding: 1em;
}

.box--pad-large > .box__element {
  padding: 2em;
}
```

### Blockを名前空間にする
BEMのルールではElementとModifierはBlockのなかでだけ存在することができるとあります。以下のHTMLはBlockが存在しないためルール違反になります。

```html
<!-- NG -->
<div class="box--size-large">
  <div class="box__element"></div>
  <div class="box__element"></div>
</div>
```

セレクタの結合子にBlockを常に指定することでスタイルを適応できないようにすることもできます。

```scss
.block {}
.block > .block__element {}
.block.block--modifier {}
```

```html
<!-- Blockがないので、スタイルは適応されない。 -->
<div class="box--size-large">
  <div class="box__element"></div>
  <div class="box__element"></div>
</div>
```

ただし、ここまで厳密にする必要はないと考えています。  
セレクタを複雑にして厳密さを求めるより、BEMの基本的なルールを守ってもらえるようにコミュニケーションをとる方が必要ではないかなと考えています。


### Sassの&(アンパサンド)
Sassでは入れ子と`&`(アンパサンド)を使ってBEMをショートカットで書くことができますが、BEMの命名規則の明確さを損なってしまうので、使わない方がベターだと思います。

```scss
/* Bad */
.foo {
  color: white;
  &--bar {
    color: red;
  }
  & .bar { // このセレクタは`.foo .bar`なのか?`.foo--bar .bar`?なのか?
    color: red;
  }
}
```

```scss
/* Good */
.foo {
  color: white;
}

.foo--bar {
  color: red;
}

.foo .bar {
  color: red;
}
```

検索しにくくなる(あるいはできなくなる)ことも使わない理由のひとつです。

```scss
/* Bad */
.foo {
  color: white;
  &--bar { // `.foo--bar`を検索しても引っかからない
    color: red;
  }
  & .bar { // `.foo .bar`を検索しても引っかからない
    color: red;
  }
}
```

### Blockの粒度
Blockの大きさ(粒度)をどのように考えるかは、2つの基準があると考えています。

#### コンテナとコンテンツの分離(OOCSS)

OOCSSの「コンテナとコンテンツの分離」をできるようにしておきます。

コンテナとは`.container`や`.wrapper`のような横幅を制限したり、グリッドレイアウトのような大枠のレイアウトを指定するものです。  
コンテンツとは本文やリスト、画像やテーブルなどのパーツのことです。

このデザインはどんな構造(レイアウト)が必要なのか?その中にはどんなパーツがあるのかという順番で考えていくと作りやすく、使いまわしがしやすくなると思います。

#### どこまで汎用性を持たせるか
BlockにはいくつでもModifierを足していけますが、増えるごとに複雑さが増します。自分で定義したBlockならまだしも、誰かが定義したBlockであればModifierの組み合わせを把握しきれなくなる恐れがあります。

指定が複雑になってきてしまったら、別のBlockとして定義できないか考えましょう。「このパターンではこのBlockに2つModifierを指定してください。」よりも「このパターンではこのBlockを指定してください。」の方がシンプルで伝わりやすく、運用がしやすいと思います。

### divが足りなくなってしまった
デザインの変更があり、コーディングをやり直す必要があるけどBlockを`<div>`でラップしないと難しいということもあります。そのときは、

1. できればHTMLも含めて修正する
1. Blockを組み合わせて対応できないか考える
1. `.block-wrapper`や`.block-inner`のようなクラスを作る

という順番で考えています。

```html
<div class="block-wrapper"> 
  <div class="block">
    <div class="block__item"></div>
  </div>
</div>
```

`.block-wrapper`のようなクラスはBEMにはありませんが、Blockをラップするというイレギュラーに対応するためにこのようなクラスを作ることがあります。



## BEM以外の手法との組み合わせ
BEMとBEM以外の設計手法を組み合わせることに問題はありません。例えば、

* OOCSS
* SMACSS
* 汎用クラス(ユーティリティクラス)

などです。FLOCSSがいい例ですが、BEMだけですべてを解決することは難しいです。BEM以外の設計手法を柔軟に取り入れていくのがベターだと思います。

### 汎用クラス
BEMで汎用クラスを適切に書くことはできないと思います。もし書けたとしても冗長になるでしょう。

汎用クラスはBEMとは別のルールとして適応させます。例えば`.display-none`や`.dn`のようなシングルクラスで適応できるようにします。

### SMACSS
BEMにはバリエーションや状態の変化としてModifierがありますが、状態の変化はSMACSSのStateに任せてしまうのもありです。

```scss
.tab {}
.tab__trigger {}
.tab__content {}
.tab__trigger.is-active {}
.tab__content.is-open {}
```

Modifierはパターン違い、Stateは一時的な状態変化と分けて考えると把握しやすくなります。

## リンク集
公式ドキュメント

* <a href="https://github.com/juno/bem-methodology-ja/blob/master/definitions.md">bem-methodology-ja/definitions.md at master · juno/bem-methodology-ja</a>

BEM

* <a href="https://app.codegrid.net/entry/bem-basic-1">基本概念とルール | CodeGrid</a>
* <a href="http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/">MindBEMding – getting your head ’round BEM syntax – CSS Wizardry – CSS, OOCSS, front-end architecture, performance and more, by Harry Roberts</a>
* <a href="https://github.com/inuitcss/inuitcss">inuitcss/inuitcss: Extensible, scalable, Sass-based, OOCSS framework for large and long-lasting UI projects.</a>
* <a href="http://blog.kubosho.com/entry/extend-base-ruleset-vs-define-base-class-and-modifier-class-in-html">MindBEMding の Modifier は元のクラス名と一緒に指定するべきか否か - I'm kubosho_</a>

OOCSS

* <a href="https://app.codegrid.net/entry/oocss-1">OOCSSの基本 | CodeGrid</a>

EDJO

* <a href="https://hail2u.net/blog/webdesign/every-declaration-just-once-example.html">Every Declaration Just Onceの例 - Weblog - Hail2u.net</a>
* <a href="https://hail2u.net/blog/webdesign/oocss-drawbacks-and-gifts-of-every-declaration-just-once.html">OOCSSの欠点とEvery Declaration Just Onceのもたらすもの - Weblog - Hail2u.net</a>
* <a href="http://morishitter.hatenablog.com/entry/2015/01/16/005343">OOCSSとEDJO、もしくはHTMLとCSSにおける命名 - morishitter blog</a>
* <a href="http://terkel.github.io/cargo-cult-css/">カーゴ・カルト CSS</a>

アイデア

* <a href="http://cssguidelin.es/#naming-conventions">CSS Guidelines (2.2.5) – High-level advice and guidelines for writing sane, manageable, scalable CSS</a>
* <a href="http://sass-guidelin.es/#architecture">Sass Guidelines</a>
* <a href="https://github.com/hiloki/flocss">hiloki/flocss: CSS organization methodology.</a>
* <a href="https://smacss.com/ja">Ja - Scalable and Modular Architecture for CSS</a>
* <a href="http://pepabo.github.io/docs/frontend/standard/css-framework/">CSS フレームワークとの付き合い方 - ペパボのフロントエンドスタンダード</a>
* <a href="http://pepabo.github.io/docs/frontend/standard/css-architecture/">CSS 設計の長い夢 - ペパボのフロントエンドスタンダード</a>
* <a href="http://melty.koume.in/css-architecture-for-large-scale-web-site/">不特定多数の人が更新する大規模サイトに必要な CSS 設計の思想</a>
* <a href="http://blog.kubosho.com/entry/2014/12/09/valhalla-gate-css-architecture">神獄のヴァルハラゲートのCSS設計 - I'm kubosho_</a>
* <a href="http://geckotang.tumblr.com/post/104065014321/%E4%BB%8A%E5%B9%B4%E3%81%AE%E3%83%8D%E3%83%BC%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%AB-css%E8%A8%AD%E8%A8%88">今年のネーミングルール #CSS設計 - < /gecko ></a>
* <a href="http://geckotang.tumblr.com/post/69554882865/bem-words">BEMで命名する時に役に立ちそうな単語 - < /gecko ></a>
* <a href="http://qiita.com/hiloki@github/items/4fa99b8755a22878449e">少し細かいBEMい話 - Qiita</a>
* <a href="http://liginc.co.jp/web/html-css/html/173153">【CSS設計】拡張や修正に強いコンポーネントをマークアップする6つのテクニック | 株式会社LIG</a>

================================================
FILE: how-to-ecss.md
================================================
# ECSS
[Enduring CSS](http://ecss.io/)

「Enduring CSS」(以降ECSSと表記)は(ファイルサイズ、UIの数、開発者の数などが)大規模なWebアプリケーションのCSSを合理的に書くためアプローチです。すべてのケースで最適な方法ではないので、[OOCSS](https://github.com/stubbornella/oocss)や[SMACSS](https://smacss.com/ja)、[BEM](https://en.bem.info/)のようなCSS設計の手法や、[Atomic Design](http://atomicdesign.bradfrost.com/)のようなデザインシステム、[CSS Modules](https://github.com/css-modules/css-modules)のようにCSSのスコープを管理できるツールなどのアプローチも検討してください。

このドキュメントはECSSの考え方やアプローチをまとめたものです。意訳や独自に追加した箇所もあります。Webサイトでの使用を想定しています。正確な情報は[公式サイト](http://ecss.io/)を確認してください。

Enduringは、「長続きする、永続的な、不朽の、我慢強い、辛抱強い」という意味を持っています。  
OOCSSのようなオブジェクト指向のCSSアプローチは再利用性やファイルサイズの削減というメリットはありますが、「小さなコンポーネントを組み合わせる複雑さ」「コンポーネントの影響範囲が大きいので変更・削除がしにくい」というデメリットもあります。

ECSSでは複雑で抽象度の高いオブジェクト指向ではなく、複雑さを避けて、管理をしやすく、CSSの寿命を長くすることを目指したアプローチをとります。100を70にするのではなく100は100のままで管理をしたり、大きな塔ではなく中規模のビル群を作っていくイメージです。  
OOCSSが[DRY](https://www.google.co.jp/search?q=Don%27t+repeat+yourself&gws_rd=cr&ei=BkiRWOqJF8uh8QXZzrOAAg)(Don't repeat yourself:繰り返しを避けること)を目指しているのとは対照的に、ECSSでは繰り返しを許容し、適切に分離(decoupling)することを目指しているのが特徴です。

## ECSSで使用される用語の定義
同じ言葉でも違った意味で解釈されてしまうことがあります。これを避けるためにECSSで使用される言葉とその意味を定義します。

- コンテキスト:前後の文脈や状況。
- スコープ:有効になる範囲。
- キーセレクタ:セレクタのいちばん右側にある実際にスタイルが適応されるセレクタ。
- 上書き(オーバーライド):キーセレクタの値が継承に基づいて意図的に修正される状況。
- 接頭辞:クラス名の先頭につける識別子やベンダープレフィックス。 例:`tp-`, `-webkit-`。
- オーサリングスタイルシート:PostCSSやSassなどのスタイリングルールを作成するファイル。
- CSS:ツールによって生成され、最終的にブラウザで解釈されるCSSファイル。

## ECSSが目標とすること
ECSSは主に、CSSのシンタックスにあるブレース(`{}`)の外側をどのように扱うのかに主眼をおいています。そして、プロパティというブレースの内側のDRYではなく、キーセレクタこそが本当にDRYにすべきものだとしています。
そのため、変数や最低限のmixinなどで共通化はするものの、ブレースの内側をDRYにすることには「見て見ぬ振りをすることが大切」だとも言っています。

### キーセレクタをDRYにする
キーセレクタのDRYとは、コンテキストが違うコンポーネントは既存のコンポーネントと似ていても別のものとして考えること、既存のコンポーネントを(OOCSSのStrucrureやmixinなどで)抽象化したり拡張して表現しないということです。そして、キーセレクタは1つのブレースの中で完結している(DRYである)必要があります。

抽象化したモジュールは変更に対する影響範囲が必然的に大きく、扱いづらくなってしまいます。多少冗長であっても、キーセレクタをDRYにすることで、変更しやすく削除しやすいモジュールにすることが、大規模なプロジェクトを長期間にわたって管理し続けるために大切なことだとしています。

## モジュールと命名規則
他のCSSの手法と同じく、ECSSも特定のスコープでUIを分割します。分割したUIをモジュールとよび、モジュールは以下の要素から構成されます。

- namespace(名前空間):クラス名の衝突を防ぐための接頭辞で、コンテキストやモジュールをあらわす。
- Module(モジュール):視覚的に認識できる個別の機能領域のもっとも大きな区分。
- Component(コンポーネント):Moduleに含まれる機能性を持つ部品。
- ChildNode(子ノード):Componentに含まれる独立した部品。
- variant(バリアント):Module内の部品のバリエーション、もしくは部品が動的に変化した状態。

### ECSSとBEM
ECSSの命名規則はBEMの命名規則と似ています。

- ModuleとComponentはBlock
- ChildNodeはElement
- variantはModifier

BEMのBlockとECSSのModuleの違いは粒度の考え方です。  
BlockはModifierによってバリエーションを追加することができますが、Blockの上位にあるDOMにクラスが追加された場合はどう解釈すればいいでしょうか?ECSSでは上位のDOMをModule、内包される要素をComponentのように考えます。  
ECSSはBEMよりも粒度を大きくすることで、様々なケースに対応できるように考えられています。

### ECSSとAtomic Design
ECSSのModuleとComponentの考え方はAtomic DesignのOrganismsとMoleculesの考え方にも似ています。

- ModuleはOrganisms
- ComponentはMolecules

ただし、Atomic Designの場合は小さなものから組み合わせるという考え方ですが、ECSSの場合はいちばん大きなものを探して、その中にはどんな要素が必要なのかを考えていきます。

### 命名規則
モジュールは以下のようなシンタックスで表現されます。

```css
namespace-ModuleName_ChildNode-variant
namespace-ComponentName_ChildNode-variant
```

`namespace`はModule名になることもあります。

```css
modulename-ComponentName_ChildNode-variant
```

namespaceとvariantはローワーキャメルケースで、それ以外はアッパーキャメルケースになります。

ECSSのComponentはModuleの中にある、一定以上の大きさや機能をもったUIのことを指します。例えば、以下のようなものが考えられます。

- ヘッダーやフッターのような共通部分(Structure)のロゴやナビゲーション、検索フォーム(`.st-Logo`, `.st-Nav`, `.st-Search`)。
- トップページ内のaboutエリア、商品リスト、関連リンク(`.tp-About`, `.tp-ProductList`, `.tp-RelatedLink`)。
- `hero`名前空間に属したスタンダートなメインビジュアル(`.hero-Standard`)。
- `doc`名前空間に属したドキュメンテーションエリア(`.doc-Main`)。

クラス名だけでは、それがModuleなのかComponentなのか分からない場合もありますが、ECSSではそれも許容しています。必要なことはnamespaceでコンテキストごとに分割して、その中で重複しないことです。重複しないのであれば、細かな組み立て方は設計者に委ねられます。


### 名前空間(namespace)
CSSは最終的に1つのCSSファイルに結合されます。クラス名の重複などでスタイルの意図せぬ衝突を避けるために、ECSSでは必ず名前空間(namespace)をつけます。

- トップページ → `TopPage` → `.tp-`
- カテゴリートップ → `CategoryTop` → `.ct-`
- ショッピングカート → `ShoppingCart` → `.sc-`

省略は必須ではないので、`.home-`のようにしてもいいでしょう。

名前空間は`.hero-`や`.doc-`といったModuleをあらわすこともあります。例えば`hero`名前空間を持っているシンプルなModule(メインビジュアル)です。

```css
/* `hero`名前空間を持つComponent */
.hero-Standard {}
.hero-Title {}
.hero-Strap {}
```

上記のような名前ではコンポーネントの粒度が大きすぎると感じるのであれば、`.hero-Title`ではなく`.hero-Standard_Title`のようにChildNodeとしてスコープを作ると重複をより避けることができます。もしくは、`.tp-Hero`のようにトップページの`Hero`コンポーネントという意味合いを持たせてもいいでしょう。

```css
/* `hero`名前空間を持つComponent */
.hero-Standard {}
.hero-Title {}
.hero-Strap {}

/* `hero`名前空間を持つComponentとChildNode */
.hero-Standard {}
.hero-Standard_Title {}
.hero-Standard_Strap {}

/* `tp`名前空間を持つComponentとChildNode */
.tp-Hero {}
.tp-Hero_Title {}
.tp-Hero_Strap {}
```

いずれの場合も、名前空間というスコープを作ることでModuleやComponentなどの名前をつけやすくすることができます。

名前空間が重複しないように、コンテキストやモジュール数の多い案件では注意が必要です。例えば、コンテキストは省略をして、Moduleは省略をしないルールにするのもいいかもしれません。

#### サイト共通の構造的なModule
ヘッダーやフッターのようなサイト共通で使われる構造的なModuleは「Structure」という意味の`.st-`名前空間が紹介されています。

- グローバルヘッダー → `.st-Header`
- グローバルフッター → `.st-Footer`
- サイト共通のグリッドレイアウト:`.st-Grid`, `.st-Grid_Item`

#### モジュールのバージョン管理
ECSSではModuleは(例えばトップページやカテゴリートップページのような)特定のコンテキストを持っています。コンテキストをスコープとしているので、Moduleは簡単に削除することができます。

例えばトップページの改修があったとき、`.tp-`(TopPage)という名前空間を持ったModuleは迷わず削除することができます。改修後のModuleは同じ`.tp-`名前空間を使ってもいいですし、`.tp2-`(TopPage2)という名前空間に変更してもいいでしょう。

### サイト共通の汎用的なModule
サイト内で使われる汎用的なModuleは「SiteWide」という意味の`.sw-`名前空間が紹介されています。Atomic DesignのAtomsのように小さな部品のようなもので、例えばボタンやリストのようなモジュールです。

- サイト共通のボタン:`.sw-Button`
- サイト共通の順序つきリスト:`.sw-OrderedList`

### layout名前空間
トップページは1カラム、詳細ページは2カラムのように、ページによって大枠のレイアウトが大きく変わる場合があります。

- サイトトップページ
- カテゴリートップページ
- カテゴリー詳細ページ
- 採用情報ページ
- 検索結果ページ
- サイトマップページ

このようなレイアウトを管理する`layout-`名前空間を作ってもいいでしょう。

- サイトトップページ:`.layout-Home`
- カテゴリートップページ:`.layout-Top`
- カテゴリー詳細ページ:`.layout-Detail`

### 汎用的なModuleのメリット・デメリット
ECSSでは汎用的なModuleは極力作るべきではないとされているため、メリットとデメリットをよく見定める必要があります。

汎用的なModuleを作るメリットは

- デザインの再利用ができる(工数の削減、よく似ているデザインを防ぐ)
- 小さなModuleごとにテストができる
- 同じルールセットを減らすことができる

汎用的なModuleを作るデメリットは

- 影響範囲が大きく変更・削除しにくい
- 異なるnamespaceが混ざるので複雑になる(mixinなどで抽象化しても同じ)

サイト共通の見た目であることと、実装として同じコードであることは違います。今は同じでも、改修によって例外的なデザインになる可能性もあります。  
例外を含んでいないか、サイト共通のコードとして実装してもいいのかを合意形成してから共通化する必要があります。  
実装時には、以下のようなことについて注意するといいでしょう。

- 見た目をあらわした名前にしない
- できるだけコンテキストを含んだ名前にする
- できるだけ最低限のスタイルを持たせる
- 充分にテストをしてから使う
- スタイルガイドなどで一覧化できるようにする

## ディレクトリ構造
ECSSではコンテキストをスコープとしてファイルを管理します。スコープごとに必要なものを分割することで、見つけやすく、削除しやすくします。  
スコープごとにまとめられたフォルダをアセットと呼びます。

ECSSはWebアプリケーションを想定しているため、CSSとJSを並列に管理することを推奨していますが、このドキュメントではWebサイトを想定しているため以下のようなファイル構成を提案します。

```
root or assets
├── css
│   ├── font/
│   ├── base/
│   │   ├── variable/
│   │   ├── function/
│   │   ├── mixin/
│   │   ├── _normalize.scss
│   │   ├── _base.scss
│   │   └── _Icon.scss
│   ├── SiteWide/
│   │   ├── _Button.scss
│   │   └── _Embed.scss
│   ├── Structure/
│   │   ├── _Grid.scss
│   │   ├── _Footer.scss
│   │   └── _ContentsFooter.scss
│   ├── namespace/
│   │   ├── layout/
│   │   │   ├── _HomePage.scss
│   │   │   ├── _Top.scss
│   │   │   └── _Detail.scss
│   │   ├── news/
│   │   ├── product/
│   │   ├── results/
│   │   ├── search/
│   │   └── sitemap/
│   └── site.scss
├── img/
│   ├── common/
│   │   ├── Header/
│   │   ├── Footer/
│   │   └── SideBanner
│   └── products/
└── js
    ├── jquery-2.2.0.min.js
    ├── common/
    │   └── smooth-scroll.js
    └── namespace/
        ├── SiteWide/
        ├── js/
        │   └── smoothScroll.js
        └── product/
```

ディレクトリは以下のようなクラス名になります。

- /src/namespace/Structure/Module1:`.st-Module1`
- /src/namespace/SiteWide/Module1:`.sw-Module1`
- /src/namespace/TopPage/Module1:`.tp-Module1`
- /src/namespace/CategoryTop/Module1:`.ct-Module1`


例えば、`.st-Module1`の中には以下のようなクラス名が含まれることになります(逆に`.st-Module2`は含まれません)。

- `.st-Module1`
- `.st-Module1_ChildNode`
- `.st-Module1-variant`

namespaceディレクトリ内を見ることで、名前空間が重複していないかをいつでも確認することができます。

CSSファイルはglobパターンを使って一括でインポートします。[ecss-postcss-shell](https://github.com/benfrain/ecss-postcss-shell/blob/master/gulpfile.js)では[postcss-import](https://github.com/postcss/postcss-import)を使った例が紹介されています。

```js
// Create the styles
gulp.task("styles", ["lint-styles"], function () {
    var processors = [
        postcssImport({glob: true}),
        mixins,
        simpleVars,
        colorFunction(),
        nested,
        autoprefixer({ browsers: ["last 2 version", "safari 5", "opera 12.1", "ios 6", "android 2.3"] }),
        cssnano
    ];
    return gulp.src("preCSS/styles.css")
    // start Sourcemaps
    .pipe(sourcemaps.init())
    // We always want PostCSS to run
    .pipe(postcss(processors).on("error", gutil.log))
    // Write a source map into the CSS at this point
    .pipe(sourcemaps.write())
    // Set the destination for the CSS file
    .pipe(gulp.dest("./build"))
    // If in DEV environment, notify user that styles have been compiled
    .pipe(notify("Yo Mofo, check dem styles!!!")); 
});
```

CSSは以下のようにしてインポートします。namespaceディレクトリ内のModuleは依存関係を持たないようにする必要があります。

```scss
@import "base/variable/**/*.scss";
@import "base/function/**/*.scss";
@import "base/mixin/**/*.scss";
@import "base/_normalize.scss";
@import "base/_base.scss";
@import "base/_Icon.scss";

@import "SiteWide/**/*.scss";
@import "Structure/**/*.scss";
@import "namespace/**/*.scss";
```

## Moduleの状態変化
Moduleの状態変化は[WAI-ARIA](https://github.com/momdo/momdo.github.io/wiki#aria%E9%96%A2%E9%80%A3)を使うことが推奨されています。

| 属性            | 意味                                                            |
|---------------  |---------------------------------------------------------------- |
| aria-selected   | trueで選択、falseで非選択を示す                                  |
| aria-disabled   | trueで無効、falseで通常を示す                                   |
| aria-hidden     | trueで非表示、falseで表示状態を示す                              |
| aria-expanded   | trueで展開、falseで格納を示す                                   |
| aria-busy       | trueで更新中、falseで通常を示す                                  |
| aria-current    | 表示されているページを視覚的に表すリンクを示す(WAI-ARIA 1.1)   |

`.is-active`のようなクラスを追加するよりも名前のバラつきが起こりにくいことや、標準化された支援技術によってアクセシブルになることが期待できます。

WAI-ARIAを使わない場合は`.is-`のような名前空間でなく、variantを使うことを勧めています。

```html
<!-- Allow -->
<button class="co-Button is-Selected">Old Skool Button</button>

<!-- Good -->
<button class="co-Button co-Button-selected">Old Skool Button</button>
```

## CMSから生成されたコンテンツ
CMSでコンテンツを作成するときに、すべての要素にクラスを指定することが難しいことがあります。そういった場合には無理にクラスを指定せずに、Module内の要素セレクタに対してスタイルを指定することも許容されています。

```css
.st-Main {
  h1 {
    /* Styles for h1 */
  }
  p {
    /* Styles for p */
  }
  ul {
    /* Styles for ul */
  }
  li {
    /* Styles for li */
  }
}
```

クラス指定のない要素に限定するのもいいでしょう。

```css
.st-Main {
  h1:not([class]) {}
  p:not([class]) {}
  ul:not([class]) {}
  li:not([class]) {}
}
```

## ツール
ECSSではCSSプリプロセッサとLintの使用を推奨しています。どのCSSプリプロセッサやタスクランナーを使うのかといったことは、プロジェクトの要件によっても違いますし、時期によっても最適なものは違います(ECSS本ではPostCSSとGulp、Stylelintを使用)。  
必要な機能は以下の通りです。

- 変数:サイズや色を取得したり、定数化することによるヒューマンエラーの軽減。
- mixins:フォントファミリーなどの特定の設定のマクロのようなもの。
- アンパサンド記号:(`&`)でキーセレクタを参照する。
- loop:長いルールセット(例えば、100種類の異なる色のヘッダー)のループを書く機能。
- partials:オーサリングスタイルシートを特定のスコープごとに分割。
- Lint:適切でないコードをデプロイするのを防ぐ。
- 積極的なMinify:コードの最適化。
- Autoprefixer:正確にベンダープレフィックスを付与し、オーサリングスタイルシートにベンダープレフィックスが存在しないようにする。

### Stylelint
PostCSSではStylelintを使います。`.stylelintrc`には以下のように設定します。

```js
// Config for linting
module.exports = { 
    "rules": {
        "block-no-empty": true,
        "color-no-invalid-hex": true,
        "declaration-colon-space-after": "always",
        "declaration-colon-space-before": "never",
        "function-comma-space-after": "always",
        "function-url-quotes": "double",
        "media-feature-colon-space-after": "always",
        "media-feature-colon-space-before": "never",
        "media-feature-name-no-vendor-prefix": true,
        "max-empty-lines": 2,
        "number-leading-zero": "never",
        "number-no-trailing-zeros": true,
        "property-no-vendor-prefix": true,
        "declaration-block-no-duplicate-properties": true,
        "block-no-single-line": true,
        "declaration-block-trailing-semicolon": "always",
        "selector-list-comma-newline-after": "always-multi-line",
        "selector-no-id": true,
        "string-quotes": "double",
        "value-no-vendor-prefix": true,
        "function-linear-gradient-no-nonstandard-direction": true,
        "selector-no-universal": true,
        "declaration-block-no-shorthand-property-overrides": true,
        "indentation": 4,
        "selector-max-specificity": "0,2,0"
    } 
}
```

'selector-max-specificity'という「セレクタが持つことができるセレクタ特異性の最大レベルを制御する」ルールもあります。その他のECSSプロジェクトに有効なルールは以下の通りです。

- オーバーライドとメディア照会のみをネストすることができます(親(`&`)セレクターを使用しないネストを防止します)。
- キーセレクタがECSS命名規則に合っていることを確認してください(これを行うには、Stylelintに ['selector-class-pattern'](https://stylelint.io/?/src/rules/selector-class-pattern/README.md)ルールが追加されました)。
- キーセレクタが複合化されないようにします(例:`.ip-Selector.ip-Selector2 {}`)。
- キーセレクタが特異であることを確認します(例:`.ip-Thing`ではなく`.a-Parent .ip-Thing {}`)。


## 健全なスタイルシートの十戒
1. すべてのキーセレクタは"Single Source of truth"であること
2. 入れ子にしてはいけない(メディアクエリ、上書き、本当に必要であると感じない限りは)
3. IDセレクタを使用しない(必要だと感じていても)
4. オーサリングスタイルシートにベンダープレフィックスを書いてはいけない
5. サイズや色、z-indexに変数を使用する
6. モバイルファーストで書く(max-widthを避ける)
7. mixinを控えめに使用する(extendを避ける)
8. すべてのマジックナンバーとブラウザハックに対してコメントを書く
9. インラインイメージを使わない
10. 複雑なCSSを書かず、同じように動くシンプルなCSSを書く

### 1. すべてのキーセレクタは"Single Source of truth"であること
キーセレクタ(実際にスタイルが適応されるセレクタ)に対するスタイルの指定は1つのブレース内で完結するようにします。重複をなくして管理をしやすくするため、アセットを削除しやすくするのと同じようにキーセレクタも削除しやすくするためです。

ブレース内は常にキーセレクタを参照した処理をおこないます。

```css
.key-Selector {
  width: 100%;

  @media (min-width: $M) {
    width: 50%;
  }

  .an-Override_Selector & {
    color: $color-grey-33;
  }
}
```

ネストをしたときのパターンとして、キーセレクタを`&`で参照したり、メディアクエリで上書きする場合などが考えられます。  
許容されるネストは3つです。

1.標準的な上書き  
この結果、`ip-HomeCallouts`のクラスを持つ要素の内部にある場合、`ip-Carousel`のフォントサイズが大きくなります。

```css
.ip-Carousel {
  font-size: $text13;

  .ip-HomeCallouts & {
    font-size: $text15;
  }
}
```

2.要素にクラスを追加してオーバーライドする  
`.ip-ClassificationHeader`を追加された`.ip-Carousel`の背景色は変更されます。

```css
.ip-Carousel {
  background-color: $color-green;
  
  &.ip-ClassificationHeader {
    background-color: $color-grey-a7;
  }
}
```

3.メディアクエリによる上書き  
横幅は50%に上書きされます。

```css
.key-Selector {
  width: 100%;
  
  @media (min-width: $M) {
    width: 50%;
  }
}
```

いずれもキーセレクタはブレース内でカプセル化されます。他のキーセレクタが混ざり込むこともありません。

### 2. 入れ子にしてはいけない(メディアクエリ、上書き、本当に必要であると感じない限りは)
子要素をネストすることによって別のセレクタを生成することを禁止します。  
以下の例では、`.key-Selector`の中で`.key-Selector_Item`を生成してしまい、`.key-Selector_Item`に関する情報が重複する可能性があります。

```css
/* Good */
.key-Selector {}
.key-Selector_Item {}

/* Bad キーセレクタが2箇所に存在する */
.key-Selector {

  &_Item {

  }
}
.key-Selector_Item {}
```

子要素をネストすることによって詳細度を上げることも禁止します。  
キーセレクタである`.key-Selector`と子要素である`.key-Selector_Item`が結合されることで詳細度が上がり、ルールが複雑になってしまいます。

```css
/* Good */
.key-Selector {}
.key-Selector_Item {}

/* Bad */
.key-Selector {

  .key-Selector_Item {

  }
}
```

オーサリングスタイルシートのセレクタに`h1.yes-This_Selector`のような他のセレクタを追加する必要もありません。  
以下のようなデメリットがあります。

- 望ましくない特異性(詳細度の上昇)を作り出してしまう
- より具体的なセレクタにする(詳細度を上げる)必要があるため、維持するのが難しくなります
- 生成されたCSSのファイルサイズが不必要に大きくなります
- 要素タイプの場合、ルールを特定の要素や構造に結びつけてしまいます

### 3. IDセレクタを使用しない(必要だと感じていても)
ECSSではIDセレクタの使用を禁止しています。IDセレクタには以下のようなデメリットがあります。

- クラスセレクタよりも具体的で上書きを難しくしてしまう
- ページ内で一度しか使えない

どうしてもIDを使わなければいけない場合は、属性セレクタを使ってクラスセレクタと同じ詳細度にします。

```css
[id="Thing"] {
  /* Property/Values Here */
}
```

### 4. オーサリングスタイルシートにベンダープレフィックスを書いてはいけない
PostCSSのAutoprefixerによって必要なベンダープレフィックスを自動で付与することができます。わざわざ手書きをしたり、mixinで用意する必要はありません。

ただし、以下のような独自実装のプロパティは手動で追加する必要があります。

```css
.ui-ScrollPanel {
  -webkit-overflow-scrolling: touch;
}

.ui-Component {
  &::-webkit-scrollbar {
    -webkit-appearance: none;
  }
}
```

### 5. サイズや色、z-indexに変数を使用する
抽象化はなるべく避けますが、サイズ・色・z-indexは変数として管理することを推奨しています。

サイズと色を変数化することで微妙に異なる値に気づくことができるため、一貫性を保つことができます。
z-indexに関してはスタッキングコンテキストを完全にカバーすることはできませんが、全体のバランスを見て数値を決めるのに役立ちます。

### 6. モバイルファーストで書く(max-widthを避ける)
最小のビューポートを基準にすることで、スタイルの継承を促し、必要なときにだけ、最小限のスタイルの上書きをすることができます。

基本的にはmax-widthを使うことはありませんが、中間の範囲にだけスタイルを当てたいときに使うことがあります。

```css
.med-Video {
  position: relative;
  background-color: $color-black;
  font-size: $text13;
  line-height: $text15;

  /* Between medium and large sizes we want to bump the text up */
  @media (min-width: $M) and (max-width: $L) {
    font-size: $text15;
    line-height: $text18;
  }
}
```

### 7. mixinを控えめに使用する(extendを避ける)
mixinを使った抽象化はなるべく避けてください。有用なケースとしては以下のようなものがあります。

- テキストの切り捨て(@mixin Truncate)
- iOSスタイルの慣性スクロールパネル
- さまざまなブラウザに適した数の擬似セレクタ
- 複雑なフォントスタック

単純なフォントスタックは変数で定義します。それ以外の(例えば`font-family`以外のプロパティを持っている)複雑なフォントスタックはmixinで定義するほうが合理的です。

プロジェクトのmixinは10個以下になるようにします。それより多い場合は不必要に抽象化されている可能性があります。

Sassの@extendディレクティブは、あるセレクタのスタイルを別のセレクタに継承することができます。ファイルサイズの削減が期待できますが、オーサリングの時点では予測ができない処理をしてしまうため、デバッグが難しくなります。

Minify時はmixinよりもextendのほうがファイルサイズの削減ができますが、Gzipをするとそれほど変わらなくなります。extendで得られる(Gzipではわずかな)ファイルサイズの削減よりも、mixinによる保守性を選択します。

### 8. すべてのマジックナンバーとブラウザハックに対してコメントを書く
ピクセルベースのまだ変数として定義されていない値を入力するときには注意が必要です。オーサリングスタイルシートにマジックナンバー(第三者は数字の意味が分からないが正常に動作すること)を入力するときは、上の行にコメントを追加して「なぜ必要なのか」を説明してください。今は余分に思えるかもしれませんが、他の人や1か月後の自分が見たときのことを考えましょう。

```css
.med-Video {
  position: relative;
  background-color: $color-black;
  font-size: $text13;
  line-height: $text15;
  /* 絶対配置されたアイコンに対応するためには、上記のスペースが必要です */
  margin-top: 20px;
}
```

特定のブラウザに対するハックを書くときは`/ * HHHack:* /`をコメントに追加します。

```css
.med-Video {
  background-color: $color-black;
  font-size: $text13;
  line-height: $text15;
  /*HHHack Windows Phone 8.1をフルサイズで表示させるために必要, reference ticket SMP-234 */
  width: 100%;
}
```

この種のハックは可能な限りルールの最下位に記述します。

### 9. インラインイメージを使わない
インラインイメージはHTTP環境ではHTTPリクエストを減らすことができるメリットがあります。ただし、オーサリングスタイルシートにインラインアセットを展開することは避けます。そのアセットが何であるかを把握しにくいからです。

代わりにツールを使ってインラインイメージに変換しましょう。例えば[postcss-assets](https://github.com/borodean/postcss-assets)です。

```css
.rr-Outfit {
  min-height: $size-quadruple;
  background-image: inline("/path/to-image/relevant-image-name.png");
}
```

### 10. 複雑なCSSを書かず、同じように動くシンプルなCSSを書く
できるだけ多くの人が理解できるように、できるだけシンプルなCSSを書きましょう。ループ、mixin、関数を書くのは最小限にします。  
原則として、ルールのバリエーションが10未満の場合は手で書きます。30以上のスプライト画像であればツールを使っていきましょう。

シンプルさはレイアウトにも適応されます。DOM構造が同じであれば、よりサポートされているレイアウトアルゴリズムを使いますが、DOM構造をよりシンプルにできるのであれば、その方法も検討しましょう。

## 参考リンク
- [Enduring CSSの設計思想 - ECSSが目指す設計 | CodeGrid](https://app.codegrid.net/entry/2016-ecss-1)
- [抽象化を避けるCSS設計方法論「Enduring CSS」 第1回 | HTML5Experts.jp](https://html5experts.jp/takazudo/21946/)
- [PostCSSでECSSビルド環境構築 - PostCSSの基本的な使い方 | CodeGrid](https://app.codegrid.net/entry/2016-ecss-build-1)

================================================
FILE: image-naming-rule.md
================================================
# 画像の命名規則
## ファイル名とフォルダ名に使う文字と記号
ファイル名に使うのは半角英数字とハイフンとアンダースコアのみとします。

* 半角英数字
* `-`ハイフン
* `_`アンダースコア

これ以外の文字・記号はファイルのやりとりで文字化けしたり、サーバーが対応していない可能性がある、見落としやすい、機種依存文字といった理由で使用しません。

## フォルダ名とディレクトリ構造のルール

画像ファイルはルートディレクトリにassetsディレクトリを作り、CSSやJavaScriptと同じ階層に保存します。

```
root
├── assets/
│   ├── css/
│   │   └── icon/
│   ├── img/
│   │   ├── common/
│   │   └── page/
│   ├── js/
│   └── svg/
├── index.html
└── page/
    └── index.html
```

* 画像フォルダ名はimgとします。
* 画像は基本的に`/assets/img`ディレクトリに保存します。
* `/assets/img`ディレクトリ以下にページのディレクトリ構造にあわせてフォルダを作り、画像を保存します。トップページの画像は`/assets/img`ディレクトリ直下に保存します。
* サイト共通の画像は`/assets/img/common`ディレクトリに保存します。
* 各ディレクトリ共通の画像は`/assets/img/page/common`のようにcommonディレクトリを作って保存します。
* アイコンフォント用のSVGファイルは`/assets/css/icon`ディレクトリに保存します。
* インラインSVG用のSVGファイルは`/assets/svg`ディレクトリに保存します。
* img要素で表示させるSVGファイルは`/assets/img`ディレクトリにJPGなどと同じように保存します。
* PDFファイルのようなブラウザ上に表示させないファイルも、JPGなどと同様に扱います(`pdf`ディレクトリなどは作らない)。
* ファイル名とフォルダ名は適切な英単語を使用し、ローマ字を使いません。ただし、ローマ字表記が仕様上正しい場合は使用します。
* 英単語は半角英数字を使います。
* 英単語はハイフンで区切ります。
* ブログの投稿画像のような数が増えていくものは2016と01のように西暦4桁と月2桁でフォルダを分けます(更新数が少ない場合は西暦だけで管理)。

ただし、CSSをstylesheet、JSをJavaScriptと省略表記にしていない場合は、imgではなくimageとします。

## 画像のパス指定
画像のパスは以下のようなルート相対パスで指定します。

* `/assets/img/common/logo.svg`
* `/assets/img/page/image01.jpg`

### ルート相対パスのメリットとデメリット
ルート相対パスには以下のようなメリットがあります。

* どの階層からでも同じパスで参照できるため、パーツを共通化した場合でも扱いやすい。
* CMSでは絶対パスで出力されることが多いので、CMS化が容易。
* パスから階層構造をつかみやすい。
* ルートディレクトリ近くにまとめておけばパスが短く保てる。

ルート相対パスにはデメリットもあります。以下の点に注意して制作をします。

* フォルダ名を変更するとリンク切れになってしまう。
* サーバーを通さないと、ローカル環境で画像が表示できない。
* テキストエディタでパスの補完機能を使うには、若干の設定が必要。
* 階層の深いファイルへのパスが長くなる。

## ファイル名のルール
画像ファイルは以下のような順番で名前をつけていきます。ファイル名は画像の役割や連番などを示すようにします。  
どこで使われるかはファイル名ではなく、ファイルを格納するディレクトリ名で示します。

1. 種類(UIの大分類)
2. 詳細(どのような場面で使うのか)
3. 連番(2桁もしくは3桁)
4. 状態(ユーザーの操作やページの状態で画像を切り替える場合)

ファイル名の共通ルールとして、ファイル名には半角英数字を、単語の区切りにはハイフンを、分類の区切りにはアンダースコアを使用します。

### 単語の省略
`background`や`navigation`のような長い単語でなければ基本的に単語の省略はしません。  
省略する単語は以下にリストアップしてください。

* `background` → `bg`
* `navigation` → `nav`

### 1. 種類
ボタンやタイトルのようなUIの種類(大分類)をつけます。

* メインビジュアル → `hero`
* 一般的な画像 → `image`
* 地図 → `map`
* リストやグラフ → `chart`
* バナー・広告 → `banner`
* アイコン → `icon`
* ロゴマーク → `logo`
* タイトル → `title`
* 見出し → `heading`
* テキスト(見出し以外のテキスト画像) → `text`
* 背景画像 → `bg`
* ファビコン → `favicon`
* OGP画像 → `ogp`

### 2. 詳細
`種類_詳細` もしくは  
`種類`

「種類」につけた名前に対して、どのような場面で使うのかを示します。「種類」との間にアンダースコアをつけます。特定のシチュエーションを限定できない場合は省略します。

* メインビジュアルの画像 → `hero` ※「詳細」の省略
* 一般的な画像 → `image` ※「詳細」の省略
* アバウトセクションの画像 → `image_about`
* オープンアイコン → `icon_open`
* クローズアイコン → `icon_close`
* ブランドのロゴ → `logo_brand-name`
* タイトル → `title` ※「詳細」の省略
* 導入部分の見出し → `heading_intro`
* タイトルの背景画像 → `bg_title`
* グローバルナビゲーションの背景画像 → `bg_global-nav`

「詳細」が2つ以上の英単語からなる場合はハイフンで区切ります。  
`pankuzu`のようなローマ字表記は禁止とします。ただし、ローマ字表記が仕様上正しい場合は使用します。  
`button_red`のような見た目を直接あらわしているような名前は極力避けてください。

画像を書き出す段階でデザインが終わっていなどの理由で適切な単語をつけられない場合は、無理に「詳細」をつけずに、このあとの「連番」だけで管理をします。

### 3. 連番
`種類_詳細+連番` もしくは  
`種類+連番`


ボタンのように数が多かったり、サムネイル画像のように頻繁に追加されるものに関しては、「種類」と「詳細」のあと、もしくは「種類」のあとに01から始まる2桁の連番をつけます。「連番」の前にはアンダースコアをつけません。「詳細」がない場合は必ず連番をつけます。

* メインビジュアルの1つ目(カルーセルで使用) → `hero01` ※「詳細」の省略
* 一般的な画像の1つ目 → `image01` ※「詳細」の省略
* アバウトセクションの画像の1つ目 → `image_about01`
* 「詳細」をつけるのが難しい見出し → `heading01` ※「詳細」の省略


### 4. 状態
`種類_詳細+連番_状態` もしくは  
`種類_詳細_状態` もしくは  
`種類+連番_状態` もしくは  
`種類+連番_状態_状態`

マウスオーバー、モバイルとPC、解像度などで画像の切り替えをする場合などには状態を示します。状態の前にはアンダースコアをつけます。

* マウスオーバーで切り替わる前の画像 → `image01_off`
* マウスオーバーしたときの画像 → `image01_on`
* モバイルで表示する画像 → `image01_sp`
* PCで表示する画像 → `image01_pc`
* 2倍の解像度で表示する画像 → `image01_2x`


================================================
FILE: svg-operating-rules.md
================================================
# SVG運用ガイドライン
## SVG作成時に注意すること
SVGとして使うアイコンやロゴなどを*作るとき*に気をつけることをまとめています。Illustratorで作成することを前提に書いているので、SketchなどIllustrator以外のツールを利用する場合は適宜読みかえてください。

通常の画像と違いコード(XML)として書き出されるので、作り方によってはIllustratorの指定を無視したり、変換されることによって意図しないデザインとして出力される、ファイルサイズを増やしてしまうといった原因になります。

### Illustratorの基本設定

Illustratorで作成する場合の基本的な設定です。一部は使いやすいように変更してもかまいません。

環境設定の初期設定。

- [単位]はすべてピクセル
- [一般]の[キー入力]は0.5px
- [一般]の[プレビュー境界を使用]にチェックを入れる([整列]パネルからでも設定可能)
- [テキスト]のトラッキングは10/1000em(`letter-spacing:0.1;`に相当)
- [ガイド・グリッド]の[グリッド]を10px、[分割数]を2px

新規ドキュメントの初期設定。

- [単位]はピクセル
- [カラーモード]はRGB
- [ラスタライズ効果]はスクリーン(72ppi)
- [プレビューモード]はピクセル
- [新規オブジェクトをピクセルグリッドに整合]のチェックを外す

アートボードの初期設定。

- [ウィンドウ]メニューの[ワークスペース]を[Web]
- [表示]メニューの[定規]の[定規を表示]のチェックを入れる(command + R)
- [表示]メニューの[定規]の[アートボード定規に変更]のチェックを入れる(command + option + R)
- [表示]メニューの[スマートガイド]のチェックを入れる(command + U)
- [表示]メニューの[ピクセルプレビュー]のチェックを入れる(command + option + Y)
- [アートボード]パネルの[アートボードオプション]の基準点を左上にする(`width`属性と`height`属性を書き出せるようにするため)
- [アピアランス]パネル(shift + F6)の[新規アートに基本アピアランスを適用]のチェックを外す
- [線]パネルは[線を中央に揃える]で作業をする(内側と外側に揃えると書き出し時に分割されるため)
- [変形]パネルの[線幅と効果を拡大縮小]のチェックを外す

### SVG作成時のルールと注意点

基本的なルール。

- 単位はピクセルで、なるべく端数を出さない(端数の桁数はデザイナーと要相談)
- アートボードの座標は0,0(左上)を起点にする
- [オブジェクト][パス][単純化]でアンカーポイントの数を最低限にする
- 非表示にしているレイヤーも書き出されてしまうため削除する(サイズ削減のため)
- レイヤー名とグループ名、SVGフィルターは適切な単語(半角英数字)に変更する([レイヤー_1_]などと日本語で書き出されてしまう)

出力時に書き出されないこと。

- アートボードの外にある要素は書き出されない

変換されて出力されること。

- 文字データはアウトライン化する(アウトライン化をしないと`<text>`要素として書き出されるため、環境によって指定したフォントで表示されない場合がある)
- [線]以外のアピアランスはうまく書き出されない
- アピアランス、ブラシ、ブレンド、エンベロープは分割されてしまうため最低限にする(サイズ削減のため)
- メッシュグラデーションと画像ブラシ、演算、レイヤー効果はラスタライズされてしまうため最低限にする(サイズ削減のため)
- 同じ図形はシンボル登録してから配置する(`<symbol>`要素と`<use>`要素で自動的にモジュール化してくれる)
- 1回しか使わないシンボル図形は[シンボルへのリンクの解除]をする(サイズ削減のため)
- 変形や回転、拡大縮小などを最低限にする(`transform`属性として書き出されるため、その分ファイルサイズが増えてしまう)

## SVG書き出し時に注意すること
Illustratorを使った場合の書き出しに関する注意点をまとめています。レイアウト崩れの原因を取り除いたり、不要なコードを最低限にします。一部の設定は変更してもかまいません。

1. [別名で保存]をクリック(Macの場合はcommand + shift + S)
2. [ファイル形式]は[SVG(.svg)]を選択
3. [詳細オプション]をクリックしてオプションを開く
4. 以下のリストを参考にオプションを指定する

- [SVG プロファイル]はSVG1.1(最新版を指定)
- [フォント]の[文字]は[SVG]、[サブセット]は[なし(システムフォントを使用)]
- [Illustrator の編集機能を保持]をチェックしない(サイズ削減のため)
- [CSS プロパティ]は[プレゼンテーション属性]を指定する(スタイルの裏書をしやすくするため)
- [未使用グラフィックスタイルを含める]をチェックしない(サイズ削減のため)
- [小数点以下の桁数]を1もしくは2にする(サイズ削減のため)
- [エンコーディング]は[UTF-8]
- [`<tspan>` エレメントの出力を制御]をチェックにする(サイズ削減のため)
- [パス上テキストに <textPath> エレメントを使用]をチェックにする(サイズ削減のため)
- [レスポンシブ]のチェックを外す(`width`と`height`属性がないとIEとAndroidで表示がおかしくなる)
- [スライスデータを含める]をチェックしない(サイズ削減のため)
- [XMP を含める]をチェックしない(サイズ削減のため)
- svgzでminifyしない(再編修正を考えて)

インラインSVGで使う場合はパスをコピーして、テキストエディタにペーストすることもできます。

Illustrator CCを使っている場合は[画像アセットとして書き出す](https://helpx.adobe.com/jp/illustrator/using/collect-assets-export-for-screens.html)ことができます。書き出し時の設定を変更します。

1. [ウィンドウ]メニューの[アセットの書き出し]をクリックしてパネルを開く
1. パネルの設定から[形式の設定…]を選択
1. [SVG]を選択し、以下のようにオプションを指定する

<!--  -->

- [スタイル]は[プレゼンテーション属性]
- [フォント]は[SVG]
- [画像]は[リンク]
- [オブジェクトID]は[レイヤー名]
- [小数点以下の桁数]は1
- [縮小]にチェックを入れる
- [レスポンシブ]のチェックを外す

アイコンフォント用のSVGは500×500pxのようなアートボード単位で書き出します。アセットで書き出す手順は、

1. 新規ドキュメント(command + N)を開く
1. [アートボードの数]で任意の数(例えば10)を指定する
1. [横列数]は2を指定する
1. [幅]と[高さ]を500pxなどにする
1. [基準点が]左上にする
1. [アートボード]パネルで[アートボードを複製]を選択して複製する(例えば未使用のアートボードが残り5つなったら複製する)
1. 任意の個数のアートボードを作成したら[アートボード]パネルの[アートボードを再配置]を選択、[レイアウト]を[横に配列]、[配列数]を[5]など、[オブジェクトの一緒に移動]にチェックを入れた状態で[OK]をクリックする
1. アイコンを作成してグループ化をしたら、オブジェクトをクリックしてメニューから[アートボードに整列]を選択、[整列]パネル(shift + F7)の[オブジェクトの整列]で上下左右の中央に配置する
1. command + option + Eで[画面に書き出し]を表示
1. [アートボード]を選択して、アートボードの名前を書き出したいファイル名に変更する
1. サムネイルをクリックして書き出すアートボードを選択
1. [書き出し先]でSVGを書き出す場所を選択
1. [フォーマット]は[SVG]
1. [アートボードを書き出し]で書き出す

## SVGをimg要素で表示させる
pngで表示していたような画像の代わりとしてSVGを使うのがいちばん手軽な方法です。通常の画像と同じように`<img>`要素で指定します。

```html
<img src="image.svg" alt="">
```

使用するSVGファイル内には`viewBox`属性、`width`属性と`height`属性を必ず指定します(IEとAndroid対応)。

### バグフィックス

SVGファイル内で`width`と`height`属性が指定されていない場合にIEとAndroidでアスペクト比がおかしくなることがあります。`width`と`height`属性を指定し直します。

`preserveAspectRatio="none"`をSVGファイルに指定して直す方法もあります。仕様上、viewBoxのアスペクト比と`width`と`height`属性でのアスペクト比が異なる場合、アスペクト比と維持しながらスケーリングし、中央寄せで表示されます。`preserveAspectRatio`属性はこの挙動を変更するもので、`none`と指定することでHTML側で指定したサイズでviewBoxがフィットするようになります。

### フォールバック
フォールバックは処理が冗長になるので、IE8に対応するのであればSVGは使わないようにするのがベターです。

SVG非対応ブラウザ向けのフォールバックにはHTMLでの対応とJavaScriptでの対応の2パターンがあります。

HTML側で対応する場合は`<img>`要素ではなく、`<object>`要素を使います。`<object>`要素は下記のようにフォールバックを含めた記述ができます。

```html
<object data="image.svg" type="image/svg+xml" width="100" height="100">
 <object data="fallback.png" type="image/png" width="100" height="100">
 </object>
</object>
```

JavaScript側で対応する場合は、SVG非対応ブラウザのときには.svgを.pngに置換します。

```js
if(!window.SVGSVGElement){ //SVG非対応ブラウザの判別
  $('img[src*="svg"]').attr('src', function() {
    return $(this).attr('src').replace('.svg','.png'); //拡張子を置換
  });
}
```

フォールバック画像の作成は[svg2png](https://www.npmjs.com/package/gulp-svg2png)などで自動的に生成することができます。

`<a>`要素を`<object>`要素でラップする場合、リンクがクリックできなくなります(`<img>`要素は問題ありません)。

```html
<a href="#">
  <object data="image.svg" type="image/svg+xml" width="100" height="100">
   <object data="fallback.png" type="image/png" width="100" height="100">
   </object>
  </object>
</a>
```

CSSでは以下のように指定するとリンクをクリックできるようになります。

```css
a {
  display: inline-block; /* もしくは`display:block;` */
}

object {
  pointer-events: none; /* IE10以下未対応 */
}
```

### フルードイメージ
`<img>`要素と`<object>`要素をフルードイメージにする場合はCSSで以下のように指定します。

```css
/* 属性値が.svgで終わる要素に適応 */
[src$=".svg"],
[data$=".svg"] {
  max-width: 100%;
  width: 100%; /* IE対応 */
  height: auto;
}
```

## 背景画像としてSVGを表示させる
通常の画像と同じく`background-image`プロパティでSVGも表示させることができます。

```css
.bg {
  background-image: url("image.svg");
}
```

フォールバックをする場合はフォールバック用のpng画像を先に指定します。

```css
.bg {
  background-image: url("fallback.png");
  background-image: url("image.svg"), none;
}
```

使用するSVGファイル内にはviewBox属性、width属性とheight属性を必ず指定します(IEとAndroid対応)。

## SVGをアイコンフォントで使う
SVGのアイコンの数が多い、色を変更する必要がある、複数箇所で指定する場合はアイコンフォントとして使います。

### アイコンフォントの生成
Gulpなどで自動でアイコンフォントを生成する環境を作るのが理想的です。

- [gulp-iconfont](https://www.npmjs.com/package/gulp-iconfont)
- [gulp-iconfont-css](https://www.npmjs.com/package/gulp-iconfont-css)

Gulpを使わない場合は以下のようなツールを使って管理します。

- [icoMoon](https://icomoon.io/)
- [Font Awesome](http://fontawesome.io/)

### マークアップ
マークアップ時の注意点として、アイコンフォントを擬似要素で表示させる場合にスクリーンリーダーが`content`内の意味のない単語を読み上げてしまう問題があります。WAI-ARIAを使用して以下のような対応をします。

- `aria-hidden="true"`を指定して読み上げを防止します
- アイコンとテキストをセットにして、アイコンが表示できない場合でも意味が伝わるようにします
- テキストを非表示したうえで読み上げはできる`.sr-only`のようなクラスを使用します
- `aria-label=""`で読み上げさせるテキストを記述します

```html
<span class="p-icon p-icon--home" aria-hidden="true"></span>ホーム

<span class="p-icon p-icon--home" aria-hidden="true"></span>
<span class="u-sr-only">ホーム</span>

<span class="p-icon p-icon--home" aria-label="ホーム"></span>
```

```css
.u-sr-only {
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important; 
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  border: 0 !important;
}
```

`aria-hidden="true"`はテキストを併記できる場合やアイコン自体の意味を伝える必要がない(装飾的な場合)に指定します。  
`aria-label=""`はアイコンだけで意味を伝える必要がある場合に指定します。例えばパンくずリストでホームアイコンだけを表示している場合などがそれに当たります。

読み上げをさせなくさせるCSSの`sperk:none;`はほとんどの視覚系ブラウザ(ChromeやIEなど)やスクリーンリーダーで対応していません。なので、`<span>`で空タグを作ってアイコンを表示、`aria-hidden="true"`や`aria-label=""`で読み上げに対応するというのが現時点でのベタープラクティスです。

HTML5の仕様を踏まえて、`<i>`要素ではなく`<span>`要素でマークアップします。理由は以下の通りです。

1. `aria-hidden="true"`で読み上げを防止するようなアイコンは装飾的だと考えられるので`<span>`要素が適切
1. `<i>`要素自体にはテキストは記述しないため、具体的な意味を持つ要素でマークアップするのは適切でないと考えられる(`before`擬似要素はHTML5の範囲に入るのか?)
1. `<i>`要素は日本語の文章ではあまり使用されるシチュエーションがない意味(「技術用語、外国語のフレーズ、または架空の人物の思考など、何らかの理由で他のテキストと離して配置して区別されるテキスト」)を持つため、アイコンで使うのは適切でないと考えられる
1. アイコンの意味を読み上げた場合(テキストとセットで読み上げた場合も含めて)、 アイコンを「何らかの理由で他のテキストと離して配置して区別されるテキスト」とするのは不自然だし、斜体として表現されるようなものでもない

## インラインSVGで表示させる
HTML内に`<svg>`要素で記述するインラインSVGはSVGの機能のすべてを使うことができます。ただし、HTMLファイル内にSVGコードを貼る必要がありファイルサイズを増やしてしまうので、`<img>`要素や`background-image`プロパティ、アイコンフォントで指定するのが適切でない場合に使うようにします。

### 不要なコードの削除
インラインSVGとして使う場合に不要なコードが書き出されます。随時削除(省略)するか、Gulpなどのツールで自動的に削除できるようにしておきます。

- `<?xml`から始まるXML宣言の`version="1.0"`(バージョンが1.0であれば省略可)
- `<?xml`から始まるXML宣言の`encoding="utf-8"`(UTF-8で書き出している場合は省略可)
- `<?xml`から始まるXML宣言の`standalone="no"`
- `<!-- Generator: Adobe Illustrator`から始まるコメント(不要)
- `<!DOCTYPE svg PUBLIC`から始める文書型宣言(SVG1.1では非推奨)
- `<svg>`要素の`xmlns:a=""`
- `<svg>`要素の`x=""`と`y=""`が両方とも0(px)の場合
- `<svg>`要素の`enable-background=""`
- `<svg>`要素の`xml:space="preserve"`
- `id`属性が日本語になっている場合は適切な半角英数字に修正

### 必須なコード
ルート要素となる`<SVG>`要素の属性。

- `xmlns="http://www.w3.org/2000/svg"`(SVG名前空間宣言)
- `xmlns:xlink="http://www.w3.org/1999/xlink"`(XLink名前空間宣言)
- `version`属性
- `width`属性と`height`属性(pxは省略可)
- `viewBox`属性

```html
<!-- 修正前 -->
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="レイヤー1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
	 x="0px" y="0px" width="600px" height="600px" viewBox="0 0 600 600" enable-background="new 0 0 600 600" xml:space="preserve">
<path fill="#040000" d="M492,300c0,17.695-1.536,32-19.232,32H127.231C109.567,332,108,317.695,108,300c0-17.696,1.567-32,19.231-32
	H472.8C490.464,268,492,282.304,492,300z"/>
</svg>
```

```html
<!-- 修正後 -->
<svg version="1.1" id="question_x5F_answer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600px" height="600px" viewBox="0 0 600 600">
<path fill="#040000" d="M492,300c0,17.695-1.536,32-19.232,32H127.231C109.567,332,108,317.695,108,300c0-17.696,1.567-32,19.231-32
	H472.8C490.464,268,492,282.304,492,300z"/>
</svg>
```

### アクセシビリティ

- [&lt;title&gt;](https://developer.mozilla.org/ja/docs/Web/SVG/Element/title)要素(タイトル)と[&lt;desc&gt;](https://developer.mozilla.org/ja/docs/Web/SVG/Element/desc)要素(説明)を指定する
- `<title>`要素と`<desc>`要素を読み上げさせるための`aria-labelledby="title desc"`を指定する
- 適切な`role`属性(`role="img"`や`role="link"`など)を指定する

### SVGスプライト(svgstore)

SVGは`<symbol>`要素と`<use>`要素でコンポーネント化ができます。これをSVGスプライト(svgstore)と呼びます。

`<symbol>`要素は`<svg>`要素の中に記述し、その中にコンポーネント化したい要素を置きます。`<symbol>`要素には固有のid属性を指定しておきます。`<symbol>`要素内に記述したSVGは表示されず、`<use>`要素で参照することで表示することができます。

```scss
<svg>
  <symbol id="svg-title-facebook" viewBox="0 0 110 110">
    <title id="svg-title-facebook">Facebook</title>
    <path d="M55 0C24.6 0 0 24.6 0 55s24.6 55 55 55 55-24.6 55-55S85.4 0 55 0zm14.6 54.8H60v34H45.9v-34h-6.7v-12h6.7V35c0-5.6 2.6-14.2 14.2-14.2h10.5v11.6H63c-1.2 0-3 .6-3 3.3v7.1h10.8l-1.2 12z"></path>
  </symbol>
</svg>
```

`<use>`要素を使ってSVGを呼び出します。`role`属性や`aria-labelledby`属性でアクセシブルにしている点に注意してください。

```html
<svg viewBox="0 0 110 110" role="img" aria-labelledby="svg-title-facebook">
  <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#svg-title-facebook"></use>
</svg>
```

SVGスプライトはEJSやJadeのようなテンプレートエンジンで外部ファイル化をすると管理がしやすくなります。

注意点。

- IEとEdgeは`<use>`要素による外部SVGファイルの参照ができないため、`<body>`要素直下にSVGファイルを直書きする
- `<defs>`要素よりも`<symbol>`要素の方が柔軟に指定できる(サイズの変更ができる)ためSVGスプライトは`<symbol>`要素で定義する

### CSS

SVGで指定できるCSSは限定されています。またSVG独自のプロパティも用意されています。例えば以下のようなプロパティがあります。

- stroke(線の色)
- stroke-width(線の幅)
- fill(塗りの色)
- fill-opacity(塗りの透明度)
- stroke-dasharray(線の長さ)
- stroke-dashoffset(線の開始位置)

インラインSVGには`height:auto;`が効かないので、フルードイメージにする場合は以下のCSSを指定します。

```scss
.c-embed {
  display: block;
  overflow: hidden;
  position: relative;
  height: 0;
  margin: 0;
  padding: 0;
  .c-embed__item,
  iframe,
  embed,
  object,
  video {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
    border: 0;
  }
}

/**
 * アスペクト比 16:9
 */
.c-embed--16to9 {
  /* (横幅 / 高さ) * 100% */
  padding-bottom: percentage(9 / 16) !important;
}
```

### リンク
インラインSVGにリンクを貼る場合`<a>`要素で`<svg>`要素を囲んでも動作しません。`<svg>`要素内のタグを`<a>`要素で囲み、`xlink:href`属性でリンク先を指定します。

```html
<svg>
  <a xlink:href="#">
    <path></path>
  </a>
</svg>
```


## 参考リンク
- [SVG 1.1 仕様 (第2版) 日本語訳](https://triple-underscore.github.io/SVG11/index.html)
- [SVG | MDN](https://developer.mozilla.org/ja/docs/Web/SVG)
- [svg要素の基本的な使い方まとめ](http://www.h2.dion.ne.jp/~defghi/svgMemo/svgMemo.htm)
Download .txt
gitextract_j70as5z8/

├── .gitignore
├── LICENSE
├── README.md
├── css-class-name-list.md
├── css-coding-rule.md
├── css-styleguide.md
├── how-to-bem.md
├── how-to-ecss.md
├── image-naming-rule.md
└── svg-operating-rules.md
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (210K chars).
[
  {
    "path": ".gitignore",
    "chars": 4,
    "preview": ".git"
  },
  {
    "path": "LICENSE",
    "chars": 1081,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Manabu Yasuda\n\nPermission is hereby granted, free of charge, to any person obt"
  },
  {
    "path": "README.md",
    "chars": 109,
    "preview": "# styleguide\nリポジトリを変更してガイドラインを整理しました。\n[coding-guidelines](https://github.com/manabuyasuda/coding-guidelines)\n"
  },
  {
    "path": "css-class-name-list.md",
    "chars": 5714,
    "preview": "# CSS クラス名リスト\n名前をつけることは難しいですが、とても重要なことです。\n\nCSSには設計思想が必要ですが、実践するにあたり、名前と機能の意味がとおり、名前のつけ方にブレがないようにするべきです。\n\nこのドキュメントでは、CSSで"
  },
  {
    "path": "css-coding-rule.md",
    "chars": 27928,
    "preview": "# CSSコーディングルール\n## ファイル・ディレクトリ構成\nファイルの構成は[FLOCSS](https://github.com/hiloki/flocss)をベースにします。\n\n```\nroot\n└── assets/\n    └─"
  },
  {
    "path": "css-styleguide.md",
    "chars": 28478,
    "preview": "# CSS Styleguide\n## はじめに\nこのスタイルガイドはCSSを扱う上でベターだと思われる方法をまとめたものです。必ずしも正しいものかは分かりません。このスタイルガイドの目的は共通の認識や知識を得ることにあります。\n\nこのスタ"
  },
  {
    "path": "how-to-bem.md",
    "chars": 15528,
    "preview": "# BEM(MindBEMding)によるCSS設計\n\n## BEMとは?\n\n[BEM](https://github.com/juno/bem-methodology-ja/blob/master/definitions.md)は[Yan"
  },
  {
    "path": "how-to-ecss.md",
    "chars": 18224,
    "preview": "# ECSS\n[Enduring CSS](http://ecss.io/)\n\n「Enduring CSS」(以降ECSSと表記)は(ファイルサイズ、UIの数、開発者の数などが)大規模なWebアプリケーションのCSSを合理的に書くためアプロ"
  },
  {
    "path": "image-naming-rule.md",
    "chars": 3535,
    "preview": "# 画像の命名規則\n## ファイル名とフォルダ名に使う文字と記号\nファイル名に使うのは半角英数字とハイフンとアンダースコアのみとします。\n\n* 半角英数字\n* `-`ハイフン\n* `_`アンダースコア\n\nこれ以外の文字・記号はファイルのやり"
  },
  {
    "path": "svg-operating-rules.md",
    "chars": 12163,
    "preview": "# SVG運用ガイドライン\n## SVG作成時に注意すること\nSVGとして使うアイコンやロゴなどを*作るとき*に気をつけることをまとめています。Illustratorで作成することを前提に書いているので、SketchなどIllustrato"
  }
]

About this extraction

This page contains the full source code of the manabuyasuda/styleguide GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (110.1 KB), approximately 54.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!