HTML,CSSコーディングで気をつけたい基本的なポイント

#コーディングで押さえておきたいポイント

##1.構造と見た目を分離する
HTMLは文書構造。CSSはスタイリング。
と役割を分担させたコーディングをする。

* ``br``タグを連続で打ってスペースを空ける
* 行頭を1字分空ける、または揃えるために空白文字を使う
* 文章構成上必要ない、背景に配置するような画像やアイコンを``img``タグで設置する。
* カラムの端から端まで見出しになっているデザインにおいて、スタイリングし難いという理由で``section``タグ（または共通で囲ってる``div``タグなど）から外側に見出しを出してしまう

上記の例は全てHTML側で見た目をコントロールしています。
このような使い方は極力避けましょう。
またCSSは、後述する保守性等を考慮して直接インラインや``style``タグで書くのは避け、外部ファイルにまとめます。

##2.Validなソースを書く
W3Cの仕様に基づいた正当なコードを書くように心掛けましょう。
特にHTMLについては、文法違反があると思わぬレイアウト崩れや、保守性・再利用性の低下、JavaScriptの誤作動等を招きます。
Validatorで検証しながら書きましょう。

**Markup Validation Service**
http://validator.w3.org/

ただ、毎回W3CのValidationでチェックするのは大変なので、ブラウザに以下のようなアドオンを入れておくとすんごい捗ります。

**Firefox**
https://addons.mozilla.org/ja/firefox/addon/html-validator/

**Chrome**
https://chrome.google.com/webstore/detail/w3c-xhtml-validator/fdicklfajomdgpciofajkedchajbnhkk

##3.保守性を考慮する
後述するパフォーマンスとの兼ね合いになるケースもありますが、基本的に以下を意識しながらコーディングを進めます。

* 運用とメンテナンスに適したディレクトリ構成、サイト設計を考える
* 共通パーツ化する（ヘッダー、フッター、ナビゲーション等）
* 見やすいコードを書く
* 汎用性、再利用性を考える（コード以外に、画像やファイル等も含む）


##4.ブラウザ対応について

###ブラウザ対応に対する考え方
最新のブラウザとレガシィブラウザの仕様の差が顕著に現れるようになって、ブラウザ対応に対する考え方自体に様々なものが出てきました。代表的なものを5つ紹介します。

* Cross Browser（クロスブラウザ）
* Multi Browser（マルチブラウザ）
* Progressive Enhancement（プログレッシブ エンハンスメント）
* Graceful Degradation（グレイスフル デグラデーション）
* Polyfill（ポリフィル）

####Cross Browser（クロスブラウザ）
> 動作するWebブラウザは明示せず、如何なる環境下でもコンテンツが何かしらの状態で提供されることを保証する

####Multi Browser（マルチブラウザ）
> 動作するWebブラウザを明示し、その環境下では動作が保証される

####Progressive Enhancement（プログレッシブ エンハンスメント）
> 「一般的環境を基準にし、進んだ環境をも視野に入れる」

####Graceful Degradation（グレイスフル デグラデーション）
> 「限られた古い環境を基準にする」よりも、「最近の環境を基準にし、古い環境にはレベルを落とす」

####Polyfill（ポリフィル）
> 「新しい環境を基準にし、古い環境を新しい環境に近づけて差をなくす」

有名なものでは、jQueryがPolyfillの概念で制作されたものです。
他にもhtml5shiv,css-mediaquriesなんかもそうですね。
より詳しく知りたい方は以下の記事を参考にしてみてください。

**「マルチブラウザ」と「クロスブラウザ」の違いは何か？**
http://furoshiki.hatenadiary.jp/entry/2013/10/16/083420

**HTML5&CSS3入門 第6回 Graceful DegradationとPolyfill**
http://www.adobe.com/jp/devnet/dreamweaver/articles/html5pack_css3_part6.html

これらの考え方をもとに、事前にどのような方針でブラウザ対応を行っていくか決めましょう。


###ブラウザチェックについて

####レイアウトだけチェックして終了ではない
よくあるのが見た目だけチェックして終了となるパターンです。
が、ちょっと待ってください。それで本当にブラウザ対応したと言えるのでしょうか？

レイアウトだけチェックして終了ではなく、ブラウザの基本機能（文字サイズ変更、ズーム、キーボードのフォーカス、印刷など）も正常に動くか確認しましょう。これによってザックリですが、ユーザビリティ/アクセシビリティのチェックも出来ます。
よく見かけるのはIEで [表示 > 文字サイズ] から文字サイズが変更出来ない、Firefoxでリンクにtabキーによるフォーカスが当たらないケースです。これらは非常に多いです。
また、JavaScriptの動作もブラウザによって違う場合があります。こちらも動作を確認しましょう。

####チェックツールの活用

ここでもアドオンを有効活用しましょう。

画像のalt,画像の高さ幅,js停止/エラーチェック,css非表示などの確認
https://addons.mozilla.org/ja/firefox/addon/web-developer/

リンク切れのチェック（チェック後にレポートで表示）
https://addons.mozilla.org/ja/firefox/addon/pinger/?src=api

####IEのチェックについて
IEの開発ツールによるドキュメントモード変更は、色々と再現出来てないのでオススメしません。
[IE Tester](http://www.my-debugbar.com/wiki/IETester/HomePage)はレンダリングが結構正確です。が、JS関係はイマイチです。

というわけで、最終的に確認するなら実機及び仮想環境が確実です。
仮想環境の構築は[modern.IE](https://www.modern.ie/ja-jp)がオススメです。

##5.パフォーマンスを意識する

ユーザーが快適に閲覧出来るサイトを目指し、Webサイトの高速化を考えながらコーディングしましょう。
Webサイトのパフォーマンスの向上は、トラフィックが集中したときのレスポンス以外にも、コンバージョンアップや離脱率を減らす意味でも効果があります。
さらにフロントエンドはバックエンドを改善するより、4倍の効果があるとも言われています。
以下で、比較的簡単にできるパフォーマンスの改善方法を紹介します。

###HTML
* 無駄な改行インデントスペースを無くし、必要最低限のタグで構成する。

###CSS
* 外部ファイルに書いてキャッシュさせる。複数ファイルがある場合は、ひとつにまとめる。
* 単純なアイコン等は画像を使用せずCSSで描画する
* パフォーマンスがよい書き方をする。
* ``@import``による読み込みは避ける。
* ファイルを圧縮する。

###JavaScript
* 外部ファイルに書いてキャッシュさせる。複数ファイルがある場合は、ひとつにまとめる。
* レンダリングを妨げないように``</body>``直前に``<script>``タグを配置する。
* パフォーマンスがよい書き方をする。
* ファイルを圧縮する。

###画像
* 小さいアイコンなどはまとめてCSS Spriteにする。
* ファイルを最適化する。

###Webフォント
* 使用する範囲に限定してフォントを読み込む。（文字単位）

他にもgzip圧縮など様々な方法がありますが、ここでは実践しやすいものを紹介しました。
これらを全て手動で行うと大変なことになるので、タスクランナー（Grunt,Gulp等）を利用して自動化しましょう。
Webサイトのパフォーマンス改善について、より詳しく知りたい方は以下の書籍が参考になります。
http://www.amazon.co.jp/gp/product/4873114462/


#HTMLで気をつけたいポイント
以下の点に気をつけてコーディングすることで、Validなソースに近づけることが出来ます。

##XHTML
XHTMLではブロックボックスによってネスト出来るタグが決まっています。
タグはそれぞれ以下の3要素に分かれますが、

* ブロックレベル要素
* インライン要素
* インラインブロック要素

基本的には、
ブロックレベル要素 > ブロックレベル要素/インライン要素/インラインブロック要素
インライン要素/インラインブロック要素 > インライン要素/インラインブロック要素
とコーディングすればほぼ間違いはないです。

##HTML5
HTML5ではXHTMLでの考え方は捨ててください。
タグのネストについてはブロックレベル要素か、インライン要素かといった判断は出来ません。
HTML5では、コンテンツ・モデルによって予めネスト出来るタグが決まっています。
正直、XHTMLよりややこしい。。。

###コンテンツ・モデルとは
* メタデータ・コンテンツ
* フロー・コンテンツ
* セクショニング・コンテンツ
* ヘッディング・コンテンツ
* フレージング・コンテンツ
* エンベッディッド・コンテンツ
* インタラクティブ・コンテンツ
* パルパブル・コンテンツ

全てのタグはこれらの何れかに属しており、複数のコンテンツに属しているタグもあります。
また上記に加えてトランスペアレントというコンテンツ・モデルがあります。
``a``タグ、``del``タグなどが当てはまります。
親のコンテンツ・モデルを引き継ぐという特性があります。

コンテンツ・モデルについてはこちらで詳しく解説されています。
https://w3g.jp/html5/content_models

###アウトラインについて
HTML5にはセクショニング・コンテンツというコンテンツ・モデルがあり、
文書のアウトラインを定義することが出来ます。
XHTMLに比べて、よりセマンティックなコーディングが可能で、アウトラインを意識して
コーディングすることがHTML5において重要な要素のひとつとなります。

アウトラインというのは、文書構造を示す目次のようなものです。
例えば、Wordで制作する資料などには、大抵最初のページ目次が記載されているはずです。
目次を見るといくつの章や節があるのか把握出来るようになっていますが、
同じことをWebサイトにおいて定義することだと理解しておいてください。

こちらもセクショニング・コンテンツを包含するセクショニング・ルートだとか、色々あってややこしいです。
ここでは説明を省きますが、以下で詳しく説明されていますので興味がある方はどうぞ。
https://developer.mozilla.org/ja/docs/Web/HTML/Sections_and_Outlines_of_an_HTML5_document

Validationとおなじようにこちらもチェックツールがあります。
アウトラインがどのように定義されているか確認することが出来ます。
https://gsnedders.html5.org/outliner/

ブラウザのアドオンはこちら
**chrome**
https://chrome.google.com/webstore/detail/html5-outliner/afoibpobokebhgfnknfndkgemglggomo


###その他
HTML5では閉じタグが省略可能なタグもありますが、省略できるタグと条件が事細かく決まっていたり、
XHTMLでは省略自体が出来ないため、閉じる方向で統一したほうがコーディングしやすい思います。


#CSSで気をつけたいポイント


##CSSセレクタの詳細度を理解する
詳細度はセレクタの優先順位のことです。

```css:example.css
*        { } /*詳細度0*/
li       { } /*詳細度1*/
.a       { } /*詳細度10*/
.a:hover { } /*詳細度11*/
.a .b    { } /*詳細度20*/
#a       { } /*詳細度100*/
#a .b    { } /*詳細度110*/
#a #b    { } /*詳細度200*/
style=""     /*詳細度1000 HTMLに直接記述*/
```

下に行くほど詳細度が高くなっています。
詳細度は高ければ高いほど、それにあわせて優先順位も高くなります。（詳細度が同一だった場合は下に記述されたものが優先。）
それぞれの詳細度は、

**全称セレクタ**(0)
**タグ、擬似要素**(1)
**class**(10)
**id**(100)
**style属性**(1000)

と覚えるとわかりやすいです。（あとは増えるごとに足し算）
ちなみに``!important``は詳細度と無関係ですが、必ずスタイルを上書きする性質を持っています。
この優先順位の関係を理解しておくと、CSSによる設計及びスタイリングがコントロールしやすくなります。

よく``style``属性でCSSを書くのが良くないと言われる理由には、保守性以外にも詳細度の問題があるからです。
詳細度1000で記述されてしまうと``!important``を使う以外に上書きのしようがないですからね。

詳細度について、より詳しく知りたい方はこちらを参考にしてください。
http://www.w3.org/TR/2011/REC-CSS2-20110607/cascade.html#specificity

##ボックスモデルを理解する
``margin``,``padding``,``width``,``border``といったプロパティを有効的に使うためには、ボックスモデルを理解しておくと役に立ちます。
ボックスモデルについては、こちらで詳しく解説されています。
http://html-coding.co.jp/knowhow/tips/000014/

基本的な概念さえ理解していれば、これらのプロパティを使うときはもちろんですが、
レガシィブラウザのボックスモデル関連のバグの対処を考えたり、box-sizingといったボックスモデルを操作するプロパティを活用できます。

##高さの指定はなるべく避ける
テキスト要素や要素が増減する可能性のあるコンテンツをコーディングをする際は、``height``の指定は避けましょう。
文字サイズの可変やコンテンツが増えた際に、表示できなくなる可能性があります。
該当の要素で高さを確保したい場合は、``min-height``を指定すると良いです。
ただし、``min-height``は``display:table-cell;``の要素には効かないので注意してください。


##要素間のmarginは上方向に取る

``margin``は相殺が働くややこしいプロパティのひとつなので（``float``や``display``の値で相殺されなくなったり、レガシィブラウザでは相殺関係のバグが多い）常に一定方向に取っていくことで、誰が見てもわかりやすいコーディングになります。
しかし、どちらの方向で取るのが最適か悩んだことはないでしょうか。

まずはこちらのソースコードをご覧ください。

```css:example.css
ul > li { margin-top: 12px; }
ul > li:first-child { margin-top: 0; }
```
```css:example.css
ul > li { margin-bottom: 12px; }
ul > li:last-child { margin-bottom: 0; }
```

上は最初の要素(``li``)の``margin-top``を削り、下は最後の要素(``li``)の``margin-bottom``を削っています。
どちらも同じようなレイアウトを意図したソースコードですが、大きく異なる点があります。
それはブラウザでサポートされるバージョンの違いです。
``:first-child``はIE7以上からサポートされていますが、``:last-child``はIE9以上のサポートになります。
よって、``margin-bottom``で取られてしまうとレガシィブラウザでの対応が難しくなります。

また、classで直接``margin-bottom: 0;``と指定する場合でも、メンテナンスの際に追加するコンテンツは一番下に追加していくケースが多いため、そういった意味でもmarginは上方向に取ったほうがよいでしょう。
ただし、``:first-child``を使用する場合においても、IE7ではブラウザのバグでコメントを最初の要素と認識してしまうので、コメントを使用する際は挿入する位置に気をつけてください。
``:first-child``を起点としていると``li:first-child + li + li``,``li:first-child + li + li ~ li``のような指定(※)にも繋げやすいのでオススメです。

※``+``隣接セレクタ、``~``間接セレクタは``:first-child``と同様にIE7以降から使えます。


##フォントサイズ
ベースとなるフォントサイズは**``em``**で指定したほうが良いです。
``px``だとIEで [表示 > 文字サイズ] から変更が出来ません。

こちらのサイトで``px``換算で、``em``に変換出来ます。
http://pxtoem.com/

あとは``px``と同様に``%``による相対指定をしてやれば良いです。

##単位指定の使い方
``background-position``等の指定において、こちらも``em``による指定をしたほうが良い場合があります。
例えば背景画像で矢印等を配置するときですが、

**``px``**で指定 = 完全にその位置に固定されるため、文字サイズ変更時についてこない
**``%``/``center``**で指定 = 行数が増えて2,3行となった際に中間に表示されてしまう
**``em``**で指定 = 指定されているフォントサイズ（ブラウザによる文字サイズ変更も含む）にあわせて、ある程度位置が補正される

スマホのボタン等では``%``指定が有効ですが、PCサイトの場合常に中央に位置させたくないという状況も多いです。
更になかに入るテキストの大きさによってある程度補正してほしい、文字サイズの変更にある程度追従してほしい場面は意外とあります。
``em``による指定は性質上、レスポンシブ・タイプセッティングに有効な単位です。

##CSS設計について
最近のCSS設計は多岐に渡っていて、OOCSS,BEM,SMACSSなど様々な手法が存在します。
制作するサイトの規模や納期、メンバーとの兼ね合いである程度使い分けできると良いですが、
毎回すべてのテンプレートとコーディング規約をCSS設計にあわせて書き換えるのも、それはそれで大変なので、
基本となる設計概念さえ理解していれば、それでいいんじゃないかと思ったりします。

あくまで個人的な話ですが、設計手法については大きな拘りはありません。
（強いて言えば、接頭語のないSMACSSとCSS Signatureの組み合わせのような設計をしています。）
どれも一長一短ありますし、どれが優れていてどれがダメだとかいうことはないと思います。
サイトの規模や納期、制作環境、メンバーとの兼ね合いによる向き不向きがありますので、実際に使ってみてどの程度プロジェクトに有効だったかを評価したり、設計概念の一部だけ取り入れてみるといったことも面白いんじゃないでしょうか。

###色々なCSS設計手法の特徴
個人的なイメージです。**ほぼ独断と偏見です。**（大事なことだから強調しました。）

####OOCSS
* 大規模サイト開発向き
* 再利用前提の設計でCSSもネストせず簡潔に書くタイプなので、パフォーマンス追求向き
* 一つの要素に、classが複数付きがち
* メンテナンスを含め、あらゆる場面を想定しないと行けないので、汎用スタイルの設定が難しい
* 一から作らなくても、bootstrapなどの便利なCSSフレームワークがある
* ほぼネスト無しのclass単独型なので、詳細度の点から壊れやすいんじゃないかという懸念、とにかくclassを大量に書くので命名の被りに注意が必要（安直な名前は避けたほうがよい）
* 固有のスタイル、レイアウトの扱いに困る
* それぞれのスタイルが把握できれば、コーディングが早い（スタイルガイドの有無で開発効率がかなり変わる）

####BEM
* 中～大規模サイト開発向き
* Block単位での設計
* id/classを見ただけで構成/パターンの有無を把握出来る
* 基本id/class名が長くなるが、OOCSSを比べると複数設定する場面はあまりない
* コーディングにはsassとかstylus使いたい
* それぞれのスタイルが把握できれば、コーディングが早い（スタイルガイドの有無で開発効率がかなり変わる）

####MCSS
* 規模はあまり関係ない？
* OOCSSとBEMの概念を取り入れたもの
* Multilayer CSSという名前の通り、CSSをレイヤーに見立てて構成順で読み込む（読み込むCSS数が増えるのがデメリット）
* ベースは変更せずに上書きしていくスタイルなので、ベースとなるCSSファイル自体を使い回せる

####SMACSS
* 中～大規模サイト開発向き
* 接頭語が面倒だが、id/classで構成を把握出来る
* スタイルの把握が必要なのは、moduleに該当するスタイルくらい（moduleのボリュームによっては、スタイルガイドの有無で開発効率がかなり変わる）
* CSS設計概念が確立されていなかった頃のコーディングスタイルでも割りと馴染みやすい

####CSS Signature
* 規模はあまり関係ない
* ネストが深くなりがちなので、壊れにくい（CSSプリプロセッサのネスト記法がある意味大活躍）
* しかし、裏を返せばCSSのパフォーマンスが悪い
* 固有のスタイル向き
* 付けたid/class等をjs等で地味に活用出来る

こうやって見ても特徴色々ありすぎてどれ選んだらいいかわかんねーよ！というのが、
率直な感想じゃないでしょうか。
ただ性質上、OOCSSとMCSSは詳細度において特に気を配る必要がありそうです。

##最近のブラウザの動向について
いまだIE8のシェア率があがってきているようです。IE11のシェア率とそう変わらないですね。
http://news.mynavi.jp/news/2015/01/06/202/

仕事では今のところIE8まで通常対応していますが、2017年4月にはvista（初期ブラウザIE7、
アップデートでIE9まで利用可能）のサポートが終了になるため、サポート期間の終了と同時に
IE9までは一気に切り捨て出来るようになるんじゃないかと考えています。