リセット CSS とノーマライズ CSS の違い - 何をどこまで消すのか

ブラウザにはデフォルトのスタイルシート(User Agent Stylesheet)が組み込まれていて、CSS を何も書かなくても h1 は大きく太字になり、ul にはインデントと黒丸が付き、body にはマージンがあります。このデフォルトスタイルはブラウザごとに微妙に異なるため、何も対策しないとブラウザ間で見た目がずれます。

リセット CSS とノーマライズ CSS はどちらもこの問題に対処するものですが、アプローチが正反対です。

リセット CSS の考え方

リセット CSS は「ブラウザのデフォルトスタイルをすべて取り除いて、まっさらな状態から始める」というアプローチです。2007 年に Eric Meyer が公開した Reset CSS が広く知られています。

/* Eric Meyer's Reset CSS(抜粋) */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}

このコードは h1pspan もすべて同じ見た目にします。h1 の太字も大きなフォントサイズも消え、ul の黒丸もインデントも消えます。すべての要素が同じ起点に立つので、そこから自分で全部スタイルを定義し直すことになります。

ノーマライズ CSS の考え方

ノーマライズ CSS は「ブラウザ間の差異だけを統一し、有用なデフォルトスタイルは残す」というアプローチです。Nicolas Gallagher と Jonathan Neal が開発した Normalize.css が代表的です。

/* Normalize.css(抜粋) */
h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

b, strong {
  font-weight: bolder;
}

small {
  font-size: 80%;
}

h1 は大きいまま、b は太字のまま残ります。ただしブラウザによって 2em だったり 2.1em だったりするフォントサイズを 2em に統一する、という修正が入ります。デフォルトスタイルを壊さずに、ブラウザ間の差異だけを吸収するのが目的です。

リセット CSS

すべてのデフォルトスタイルを消す。h1p も見た目が同じになる。ゼロから自分でスタイルを構築する前提。

ノーマライズ CSS

有用なデフォルトスタイルは残す。h1 は大きく、b は太字のまま。ブラウザ間の差異だけを修正する。

実務上の影響の違い

リセット CSS を使うと、たとえば h1h6 の見出しにフォントサイズや太字を自分で定義し直す必要があります。ulol にもリストスタイルやインデントを再設定する必要があります。これはプロジェクト初期の作業量が増える反面、「ブラウザのデフォルトに引きずられない」という利点があります。

ノーマライズ CSS ではそのような再定義は不要ですが、デフォルトスタイルが残っているぶん「この margin はどこから来ているのか」と調べたときに、自分が書いた CSS なのかノーマライズが残したものなのか判別しにくいことがあります。

リセット CSS が向く場面

デザインカンプに忠実に再現する案件。デフォルトスタイルが残っていると邪魔になるので、全部消して 1 から組むほうが効率的。

ノーマライズ CSS が向く場面

ブログや文書主体のサイトで、ブラウザの基本的な文書表現をそのまま活かしたい場合。スタイルの記述量を減らせる。

現代のリセット系ライブラリ

Eric Meyer のリセット CSS は 2007 年のもので、2011 年にノーマライズが登場して以降、両者のアプローチを折衷した新しいリセット系ライブラリが出ています。

2007
Eric Meyer's Reset CSS

すべてのデフォルトスタイルを削除する最初期のリセット。広く普及したが、全要素のスタイルを自分で再定義する手間が批判された。

2011
Normalize.css

ブラウザ間の差異のみを統一するアプローチ。有用なデフォルトは残すという発想で、リセットの対抗馬となった。

2018
modern-normalize

Normalize.css の軽量版で、モダンブラウザのみを対象にして不要な修正を削除したもの。IE 対応を切ったことでコード量が大幅に減った。

2019
A Modern CSS Reset (Andy Bell)

リセットとノーマライズの折衷。box-sizing: border-box の全要素適用、スクロール挙動の設定、アクセシビリティへの配慮などモダンな実務で必要な設定を含む。

Andy Bell の A Modern CSS Reset はこの折衷アプローチの代表例です。

/* A Modern CSS Reset(抜粋) */
*, *::before, *::after {
  box-sizing: border-box;
}

body, h1, h2, h3, h4, p,
figure, blockquote, dl, dd {
  margin: 0;
}

ul[role='list'],
ol[role='list'] {
  list-style: none;
}

マージンは消すが、h1h4 のフォントサイズや太字はそのまま残しています。ul のリストスタイルも、role="list" が明示されている場合のみ消すという判断をしています。完全リセットでもなく完全ノーマライズでもない、実務で本当に必要な調整だけを入れるという思想です。

選定の基準

どれを採用するかは「リセット後にどれだけ自分でスタイルを書くか」で決まります。デザインシステムやコンポーネントライブラリを自前で構築するプロジェクトでは、デフォルトスタイルが残っているとむしろ邪魔になるのでリセット寄りが合います。既存のデフォルトを活かしつつ差異だけ潰したいなら、ノーマライズ寄りの選択になります。

ライブラリアプローチ対象ブラウザ
Eric Meyer's Reset完全リセットすべて
Normalize.cssノーマライズIE9 以上
modern-normalizeノーマライズモダンのみ
A Modern CSS Reset折衷モダンのみ

現在のプロジェクトで IE を考慮する必要がなければ、modern-normalize か A Modern CSS Reset のどちらかが現実的な選択肢です。どちらを選んでも、その上に base レイヤーとしてプロジェクト固有のデフォルトスタイルを載せていく構成になります。