コーディングガイド by @mdo

柔軟で、恒久的であり、持続性のあるHTMLとCSSの標準。

目次

HTML

CSS

黄金のルール

どんな時も、合意されたガイドラインに従おう。それがこのガイドでも、あなた独自のものでも関係ない。もし間違いを見つけたら、それが大きなものでも小さなものでも指摘しよう。このガイドに対して、追記や協力をして頂ける方はGitHubでイシューを開いて連絡してください

全てのコードはあたかも一人の人間が書いたように見えなければならない。どれだけの人が関与したかに関わらず。

HTML

HTMLシンタックス

<!DOCTYPE html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    <img src="images/company-logo.png" alt="Company">
    <h1 class="hello-world">Hello, world!</h1>
  </body>
</html>

HTML5 doctype

このシンプルな宣言で、可能な限り全てのブラウザーでスタンダードモードを使用しよう。

<!DOCTYPE html>
<html>
  <head>
  </head>
</html>

lang要素

HTML5仕様より

ウェブサイトの作成者は、サイトにふさわしいlang属性をhtml要素に対して指定することを推奨する。これはスクリーンリーダがどんな発音や方言を使ってサイトを読み上げるか、翻訳ツールがどのようなルールで翻訳するか理解するのを助けてくれる。

さらに詳細はHTML5仕様lang属性を参照。

言語コードの一覧はこちらを参照

<html lang="ja-jp">
  <!-- ... -->
</html>

IE 互換モード

Internet Explorerは<meta>タグを使った互換モードをサポートしていて、IEのどのバージョンでサイトが表示されるべきかを指定できる。特に特別な理由がないのなら、edge modeを使って、最新バージョンを指定しておこう。

さらに詳細はこの素晴らしいStack Overflowの記事を参照

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

文字エンコード

素早く、そして簡単に適切なレンダリングがされるよう文字エンコードを宣言しよう。こうすることで、HTMLコードの中で特殊文字を使わなくてもよくなる(普通はUTF-8)。

<head>
  <meta charset="UTF-8">
</head>

CSSとJavaScriptのインクルード

HTML5の仕様によると、通常はCSSやJavaScriptのロードにtext/csstext/javascriptといったtypeは必要ない。

HTML5仕様へのリンク

<!-- 外部CSS -->
<link rel="stylesheet" href="code-guide.css">

<!-- インラインCSS -->
<style>
  /* ... */
</style>

<!-- JavaScript -->
<script src="code-guide.js"></script>

潔癖さより実用性

HTML標準とセマンティクスを追求するべきだけど、実用性を犠牲にしないようにしよう。可能な限り最小限のマークアップを心がけよう。

属性の順序

HTMLの要素は可読性の向上のために、適切な順序で記述しよう。

classは最も再利用されるコンポーネントなので最初にくる。idはより詳細で、最小限の使われ方(ページ内のブックマークとか)をするべきなので、二番目にくる。

<a class="..." id="..." data-modal="toggle" href="#">
  Example link
</a>

<input class="form-control" type="text">

<img src="..." alt="...">

ブーリアン型の属性

ブーリアン型の属性は値を必要としない。XHTMLでは値を要求されるが、HTML5にそのような仕様はない。

詳細はWhatWGのブーリアン型属性のセクションを参照:

ブーリアン型の属性値が存在する場合、それは真として評価される。もし存在しない場合は負として評価される。

もしも属性に対して値を記述しなければならないのなら(必要ないはずだけど)下記のWhatWGのガイドラインを参照してみて:

もしも属性値が存在するなら、その値は空の文字列か、属性と同じ名前にして、末尾にスペースを含めないこと。

簡潔に言えば、値を記述しないこと。

<input type="text" disabled>

<input type="checkbox" value="1" checked>

<select>
  <option value="1" selected>1</option>
</select>

マークアップの削減

可能な限り、不要な親要素を作らないこと。多くの場合でそのためには繰り返しとリファクタリングが必要になるけど、コードを削減できる。次の例を見てみよう:

<!-- あまり良くない例 -->
<span class="avatar">
  <img src="...">
</span>

<!-- 良い例 -->
<img class="avatar" src="...">

JavaScriptによるマークアップ

JavaScriptのファイルの中にマークアップを記述するのは、可読性を低下させ、検索し辛く、編集し難くする上に、パフォーマンスが劣化する。可能な限り回避しよう。

CSS

CSSシンタックス

ここでの用語に質問がある?Wikipediaのカスケードスタイルシートのシンタックスセクションを参照。

/* 悪い例 */
.selector, .selector-secondary, .selector[type=text] {
  padding:15px;
  margin:0px 0px 15px;
  background-color:rgba(0, 0, 0, 0.5);
  box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}

/* 良い例 */
.selector,
.selector-secondary,
.selector[type="text"] {
  padding: 15px;
  margin-bottom: 15px;
  background-color: rgba(0,0,0,.5);
  box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}

宣言の順序

関連するプロパティは下記の順序でグルーピングすること。

  1. Positioning(位置関係)
  2. Box model(ボックスモデル)
  3. Typographic(フォント関係)
  4. Visual(見た目)

位置関係は場合によって要素を通常のフローから外してボックスモデルを上書きすることもあるので最初にくる。ボックスモデルは要素の大きさや位置を決定するのでその次にくる。

その他全ては要素の中のことだったり、位置やボックスモデルに関係しないので最後にくる。

全順序のリストについてはRecessを参照。

.declaration-order {
  /* Positioning */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  /* Box-model */
  display: block;
  float: right;
  width: 100px;
  height: 100px;

  /* Typography */
  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;

  /* Visual */
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  /* Misc */
  opacity: 1;
}

@importを使わない

<link>に比べると、@importは遅く、ページリクエストが追加され、予期しない問題を招く。代替の手法を活用しよう。

さらに詳細はSteve Soundersのこの記事を参照

<!-- link要素を使うこと -->
<link rel="stylesheet" href="core.css">

<!-- @importsは避けよう -->
<style>
  @import url("more.css");
</style>

Media queryの記述場所

可能な限り、media queryはそれが関係する要素の近くに記述すること。別のファイルにまとめたり、ファイルの最後にまとめたりしないこと。そうすると将来的に誰かが見落とす可能性が高くなるだけだ。

.element { ... }
.element-avatar { ... }
.element-selected { ... }

@media (min-width: 480px) {
  .element { ...}
  .element-avatar { ... }
  .element-selected { ... }
}

プリフィックスされたプロパティ

ベンダープリフィックスを付与する時は、値が揃う位置までインデントして揃えること。こうする事で、複数行の編集が容易になる。

Textmateなら、Text → Edit Each Line in Selection (⌃⌘A)が使える。Sublime Text 2なら、Selection → Add Previous Line (⌃⇧↑)とSelection → Add Next Line (⌃⇧↓)が使える。

/* Prefixed properties */
.selector {
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
          box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

1行だけの宣言

もし宣言する要素が1つだけなら、1行にまとめることを検討しよう。より見やすく、編集しやすくなる。複数の宣言があるなら、必ず複数行に分けて記述しよう。

ここでのキーポイントはエラーの発見しやすさにある。例えばCSSバリデータが183行目にエラーがあると報告してきた場合、宣言が1つだけなら間違えようがないけど、複数の宣言がある場合、それらを複数行に分けておくことは、あなたが正気を保つために必要だ。

/* 1つの宣言を1行で */
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }

/* 複数の宣言は複数行で */
.sprite {
  display: inline-block;
  width: 16px;
  height: 15px;
  background-image: url(../img/sprite.png);
}
.icon           { background-position: 0 0; }
.icon-home      { background-position: 0 -20px; }
.icon-account   { background-position: 0 -40px; }

省略する記述

省略形の宣言は、全ての値を設定する場合のみに留めること。一般的な省略形の宣言は:

多くの場合、全ての値を設定する必要はない。例えばHTMLのヘッダーはほとんどの場合上下のマージンしか必要としないから、上書きする場合もその二つだけを上書きすれば済む。過度な省略形の活用は、よりしょぼいコードと予期しない副作用を生み出すことが多い。

Mozillaの開発者ネットワークに素晴らしい記事がある。省略形のプロパティはその記法と挙動に明るくない人にとって良い参考になる。

/* 悪い例 */
.element {
  margin: 0 0 10px;
  background: red;
  background: url("image.jpg");
  border-radius: 3px 3px 0 0;
}

/* 良い例 */
.element {
  margin-bottom: 10px;
  background-color: red;
  background-image: url("image.jpg");
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}

LessとSassでのネスト

必要ないネストは避けること。ネストできるからといって、ネストしなければいけないことはない。親スタイルのスコープに複数の要素を含めなければいけない場合にだけネストしよう。

// ネスト無し
.table > thead > tr > th { … }
.table > thead > tr > td { … }

// ネスト有り
.table > thead > tr {
  > th { … }
  > td { … }
}

コメント

コードは人によって書かれ、メンテされる。コードは必ず説明的で、良くコメントが書かれ、人にとって分かりやすいものにしよう。良いコメントはコードの内容や目的を表す。単純にコンポーネントやクラス名を複製するだけにならないようにしよう。

長いコメントは必ず文章として書き、一般的なフレーズは簡潔に記述しよう。

/* 悪い例 */
/* Modal header */
.modal-header {
  ...
}

/* 良い例 */
/* .modal-titleと.modal-closeのラッパー要素 */
.modal-header {
  ...
}

クラス名

これらルールはSassやLessの変数名を考える時にも有用だ。

/* 悪い例 */
.t { ... }
.red { ... }
.header { ... }

/* 良い例 */
.tweet { ... }
.important { ... }
.tweet-header { ... }

セレクタ

参考情報:

/* 悪い例 */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }

/* 良い例 */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }

整理

/*
 * コンポーネントのセクション見出し
 */

.element { ... }


/*
 * コンポーネントのセクション見出し
 *
 * 見出しに説明文を追加する必要がある場合もある。必要ならここに書こう。
 */

.element { ... }

/* 分かりやすいサブコンポーネントやモディファイアー */
.element-heading { ... }

テキストエディターの設定

あなたのエディタには下記を設定しよう。不統一なコードや汚いdiffを防いでくれる。

これらの設定をあなたのプロジェクトの.editorconfigに含めることを検討しよう。例えばBootstrapのものを参考に。さらに詳細はEditorConfigについて参照