CSSリセット入門:ブラウザ標準の余白を整える最小コードと使い分け
CSSを書いていないのに、見出しの上下が空く。ページの端に余白ができる。リストに黒丸が付く——。これは多くの場合、ブラウザが持つ標準スタイルによるものです。
CSSリセットを先に読み込むと、こうした初期値をプロジェクト側で管理しやすくなります。ただし、すべてを無条件に消すのが正解ではありません。初心者がまず使うなら、余白、ボックスサイズ、画像のはみ出しだけを整える小さなリセットから始めるのが安全です。
この記事では、次の内容を実際のコードとともに整理します。
- CSSリセットが必要になる理由
- 最小限のリセットCSSと読み込み方
- リセット前後で何が変わるか
- Reset CSSとNormalize.cssの違い
- フォーカス表示など、消してはいけない初期設定
- 導入後にレイアウトが崩れたときの確認手順
CSSリセットはブラウザの初期スタイルをそろえる設定
CSSリセットの役割は、ブラウザがHTML要素に適用する標準スタイルを上書きし、デザインを始める基準をそろえることです。
Chrome、Firefox、Safari、Edgeなどのブラウザは、CSSが指定されていないページでも内容を読みやすく表示します。たとえば、見出しは大きく太くなり、段落には上下の余白が付き、リンクには下線が表示されます。こうしたルールは、開発者ツールでは一般に「user agent stylesheet」として確認できます。
HTML Living Standardのレンダリング規定にも、HTML要素をどのように初期表示するかを示すユーザーエージェント向けのルールがあります。一方で、ブラウザはすべてを完全に同じ方法で表示しなければならないわけではありません。
そのため、何も調整せずに独自デザインを重ねると、次のような問題が起こります。
bodyの余白によって、背景やヘッダーが画面端まで届かないh1やpの標準マージンが、意図した間隔に加算されるulの字下げやマーカーがレイアウトに残る- フォーム部品の見た目がOSやブラウザによって異なる
widthにpaddingとborderが加わり、要素が親幅を超える
ここがポイント: CSSリセットは完成デザインを作るCSSではなく、独自デザインを載せる前の基準を決めるCSSです。
なお、CSSリセットを使っても、文字の描画、フォーム部品、日付入力、スクロールバーなどの差がすべて消えるわけではありません。OSやブラウザ固有の機能まで完全に同一化するものではない、と理解しておきましょう。
初心者向けの最小リセットCSS
最初から大量の要素を初期化する必要はありません。小規模なWebサイトなら、次のコードで主要なつまずきを減らせます。
/* reset.css */
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
margin-block: 0;
}
ul,
ol {
margin-block: 0;
padding-inline-start: 0;
}
img,
picture,
svg,
video {
display: block;
max-width: 100%;
}
button,
input,
textarea,
select {
font: inherit;
}
このコードは、すべての装飾を消す完全なリセットではありません。リンクの下線、ボタンの境界線、入力欄の外観、キーボード操作時のフォーカス表示などは残します。
box-sizing: border-boxで幅の計算を分かりやすくする
最も効果が分かりやすいのが、次の部分です。
*,
*::before,
*::after {
box-sizing: border-box;
}
CSSの初期値であるcontent-boxでは、指定したwidthに左右のpaddingとborderが加算されます。
たとえば、次の要素を考えます。
.card {
width: 300px;
padding: 20px;
border: 1px solid #999;
}
content-boxでの実際の横幅は、次の計算になります。
300px + 20px × 2 + 1px × 2 = 342px
border-boxなら、paddingとborderを含めて横幅が300pxになります。カードや入力欄を並べるときに計算しやすく、width: 100%の要素が親からはみ出す問題も減らせます。
MDNのbox-sizing解説でも、border-boxは指定した幅と高さの内側にパディングと境界線を含める値として説明されています。
余白は必要な要素に付け直す
見出しや段落の標準マージンを消した後は、コンポーネント側で余白を明示します。
.article {
line-height: 1.8;
}
.article > * + * {
margin-block-start: 1.5rem;
}
.article h2 {
margin-block-start: 3rem;
}
この書き方なら、「ブラウザが付けた余白」と「自分で設計した余白」が混ざりません。記事本文には広めの行間を設定し、見出しの前は3rem空ける、といった意図をコードから読み取れます。
画像や動画のはみ出しを防ぐ
画像にmax-width: 100%を指定すると、元画像が親要素より大きい場合に親幅まで縮みます。
img,
picture,
svg,
video {
display: block;
max-width: 100%;
}
ただし、imgの縦横比とレイアウトシフト対策には、HTML側でも画像本来のwidthとheightを指定するのが基本です。
<img
src="product.jpg"
alt="青い収納ボックス"
width="800"
height="600"
>
max-width: 100%は、HTMLのサイズ属性を削除するための設定ではありません。表示可能な最大幅だけを制限するものです。
フォームの文字を周囲に合わせる
フォーム部品は、本文と異なるフォントで表示されることがあります。次の指定により、親要素のフォント設定を引き継がせます。
button,
input,
textarea,
select {
font: inherit;
}
ただし、背景、枠線、内側の余白まで一括で消してはいません。フォーム部品は操作できることが見た目から分かる必要があるため、装飾はコンポーネントごとに慎重に上書きします。
リセットCSSを正しい順番で読み込む
リセットCSSは、サイト固有のスタイルより先に読み込みます。後から読み込んだ同程度の詳細度を持つルールが優先されるためです。
HTMLから読み込む場合は、次の順番にします。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
</head>
ファイルの役割は次のように分かれます。
reset.css: プロジェクト全体の初期値を決めるstyle.css: 配色、余白、レイアウト、部品の見た目を定義する
1つのCSSファイルにまとめる場合も、リセットを先頭付近に置きます。
/* 1. Reset */
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
}
/* 2. Base */
body {
color: #222;
font-family: system-ui, sans-serif;
line-height: 1.7;
}
/* 3. Components */
.button {
display: inline-flex;
padding: 0.75rem 1rem;
}
CSSレイヤーを使う場合
モダンブラウザを対象にするプロジェクトでは、カスケードレイヤーで優先順位を明示する方法もあります。
@layer reset, base, components, utilities;
@layer reset {
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
}
}
@layer base {
body {
color: #222;
font-family: system-ui, sans-serif;
}
}
これはチーム開発や規模の大きいCSSで有効です。一方、初めてCSSを学ぶ段階や数ページのサイトなら、ファイルの読み込み順をそろえるだけでも十分です。
リセット前後を小さなサンプルで確認する
効果を理解するには、同じHTMLをリセットの有無で見比べるのが早道です。
入力するHTML
<main class="container">
<h1>商品一覧</h1>
<p>今週入荷した商品です。</p>
<ul>
<li>収納ボックス</li>
<li>デスクライト</li>
</ul>
<img
src="sample.jpg"
alt="商品サンプル"
width="1200"
height="800"
>
</main>
リセット前に見える主な状態
ブラウザの標準スタイルが有効なため、一般に次のような表示になります。
- 画面端と
bodyの内容との間に余白がある h1とpに上下の余白があるulが字下げされ、各項目にマーカーが付く- 大きな画像がコンテナ幅を超える可能性がある
具体的な値やフォーム部品の外観は、ブラウザやOSによって異なることがあります。
リセット後に付けるデザイン
.container {
width: min(100% - 2rem, 720px);
margin-inline: auto;
padding-block: 2rem;
}
.container h1 {
font-size: 2rem;
line-height: 1.3;
}
.container p {
margin-block-start: 1rem;
}
.container ul {
margin-block-start: 1.5rem;
padding-inline-start: 1.5rem;
}
.container img {
margin-block-start: 2rem;
border-radius: 0.5rem;
}
ここでは、リストのマーカー自体は消していません。padding-inline-startを付け直し、マーカーを表示するための領域を確保しています。
このように、リセット後に必要な見た目を明示的に戻すのが基本です。消したままにするのではなく、デザインの意図に沿って再設定するところまでが一連の作業になります。
Reset CSSとNormalize.cssは目的が異なる
選び方の軸は、「初期スタイルをどこまで消したいか」です。
Reset CSS
Reset CSSは、見出し、段落、リストなどの標準的な余白や装飾を広く取り除き、平らな状態からデザインを始める考え方です。
向いている場面は次のとおりです。
- 独自デザインを細部まで管理するWebサイト
- UI部品を共通化したWebアプリ
- デザインシステムが整備されているチーム開発
その代わり、見出しの大きさやリストのマーカーなど、必要なスタイルを自分で付け直す作業が増えます。
Normalize.css
Normalize.cssは、有用なブラウザ標準スタイルを残しながら、不整合や既知の表示差を調整する方針のスタイルシートです。
向いている場面は次のとおりです。
- ブラウザ標準の読みやすさを活かしたいサイト
- 初期化後の再設定を減らしたいプロジェクト
- 既存サイトへ段階的に導入したい場合
npmを利用する環境なら、次のコマンドで追加できます。
npm install normalize.css
JavaScriptのビルド環境では、エントリーポイントなどから先に読み込みます。
import "normalize.css";
import "./style.css";
パッケージの導入方法や収録ルールは将来変わる可能性があるため、導入時には公式リポジトリと利用中のバージョンを確認してください。
自作の小さなリセット
この記事で示したように、必要な項目だけを自作する方法もあります。
- コードの目的を把握しやすい
- 不要な上書きを避けられる
- プロジェクトに合わせて段階的に追加できる
一方で、新しいHTML要素やブラウザ差を継続的に確認する責任はプロジェクト側にあります。小規模サイトには扱いやすい方法ですが、多数の画面やフォームを持つシステムでは、実績のあるリセットやCSSフレームワークの土台を利用する選択肢も検討できます。
使い分けの目安
- 独自デザインをゼロから厳密に作る: 広めのReset CSS
- 標準スタイルを活かしながら差を調整する: Normalize.css
- 学習用サイトや小規模ページ: 自作の最小リセット
- Tailwind CSSなどを利用する: フレームワーク付属の初期化を先に確認
- 既存のWordPressテーマを修正する: 独自リセットの追加より、テーマの既存CSSを調査
複数のリセットを重ねて読み込むと、どのルールが効いているのか分かりにくくなります。基本的には1つの方針にそろえましょう。
やってはいけないリセットと改善例
初期化の範囲を広げすぎると、操作性やアクセシビリティを損ないます。特に、フォーカス表示とフォーム部品は注意が必要です。
NG例1:すべての余白を一括で消す
* {
margin: 0;
padding: 0;
}
短くて便利に見えますが、すべての要素が対象になります。フォーム部品やダイアログなど、初期余白を持つ要素にも影響し、後から原因を追いにくくなります。
改善するなら、初期化したい要素を明示します。
body,
h1,
h2,
h3,
p,
figure,
blockquote {
margin: 0;
}
対象を限定すると、「なぜその値を消しているのか」が読みやすくなります。
NG例2:フォーカスの輪郭を消す
button:focus,
a:focus,
input:focus {
outline: none;
}
これは避けるべき指定です。キーボードでTabキーを使う人が、現在どの要素を操作しているか分からなくなります。MDNのoutline解説も、標準の輪郭を消す場合は、操作可能な要素に明確な代替フォーカス表示が必要だと説明しています。
独自デザインに変更する場合は、たとえば次のようにします。
:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 3px;
}
マウス操作時とキーボード操作時の扱いはブラウザが判断します。少なくとも、フォーカスを完全に見えなくする設定にはしないでください。
NG例3:リストの意味まで見えにくくする
ul,
ol {
list-style: none;
padding: 0;
}
ナビゲーションやカード一覧ではマーカーが不要なこともありますが、記事本文の箇条書きまで同じ設定を適用すると、項目の区切りが伝わりにくくなります。
用途が決まっているクラスだけに適用する方が安全です。
.nav-list {
margin: 0;
padding: 0;
list-style: none;
}
通常のulとolにはマーカーを残し、ナビゲーションだけを初期化できます。
NG例4:アニメーションを常に一括停止する
リセットの一部として、次のような強い指定を入れる例があります。
* {
animation: none !important;
transition: none !important;
}
これでは、状態変化を伝えるために必要な動きまで止まります。動きを抑える場合は、利用者のOS設定を検出するprefers-reduced-motionを使い、不要なアニメーションを個別に調整します。
@media (prefers-reduced-motion: reduce) {
.decorative-animation {
animation: none;
}
html {
scroll-behavior: auto;
}
}
MDNのprefers-reduced-motion解説では、このメディア特性は、端末で不要な動きを減らす設定を有効にした利用者の希望を検出するものとされています。
CSSリセットで崩れたときの確認手順
リセット導入後の崩れは、消した初期スタイルを必要な場所で戻していないことが主な原因です。闇雲に値を追加せず、どの宣言が効いているかを確認します。
1. 開発者ツールで対象要素を選ぶ
ChromeやFirefoxなどの開発者ツールを開き、崩れている要素を検査します。Stylesまたはスタイル欄で、次を確認してください。
reset.cssのどのルールが適用されているか- 打ち消し線になっている宣言は何か
user agent stylesheetに元の値があるかbox-sizingの計算結果がどうなっているか- 親要素から継承した
fontやline-heightがあるか
該当する宣言のチェックを一時的に外すと、リセットが原因かどうかを切り分けられます。
2. CSSの読み込み順を確認する
次の順番になっているか確認します。
リセットCSS → 基本スタイル → コンポーネントCSS → 個別調整
独自スタイルより後にリセットを読み込むと、せっかく設定した余白やフォームの見た目が消える場合があります。
3. 詳細度をむやみに上げない
リセットを上書きできないときに、すぐ!importantを追加するのは避けます。
/* 原因を追いにくくする例 */
.card-title {
margin-bottom: 16px !important;
}
まずは次を確認します。
- リセット側のセレクターが必要以上に具体的ではないか
- CSSファイルの読み込み順が逆ではないか
- 同じクラスが別ファイルでも定義されていないか
- インラインスタイルが付いていないか
リセットのセレクターは低い詳細度に保つと、その後のCSSから上書きしやすくなります。
4. 主要な環境で操作まで試す
見た目だけでなく、次の操作を確認します。
- PC幅とスマートフォン幅で横スクロールが出ないか
- Chrome、Firefox、Safari、Edgeの対象環境で大きく崩れないか
- Tabキーでリンク、ボタン、入力欄を追えるか
- リストの項目と階層を見分けられるか
- 入力欄、チェックボックス、選択欄を操作できるか
- 文字サイズを拡大しても内容が重ならないか
すべての環境を同じ見た目にすることより、内容を読めて操作できることが優先です。
既存サイトへの追加は影響範囲を限定する
運用中のサイトへCSSリセットを後付けすると、全ページの余白や部品サイズが変わる可能性があります。特にWordPressでは、テーマ、ブロックエディター、プラグインがそれぞれCSSを持っているため、サイト全体への一括適用は慎重に行う必要があります。
安全に試す手順は次のとおりです。
- 本番サイトへ直接追加せず、ローカル環境かステージング環境を用意する
- 変更前の主要ページを画面幅ごとに記録する
- まず
box-sizingやbodyの余白など、少数のルールだけを追加する - 記事、固定ページ、フォーム、検索結果、管理対象のランディングページを確認する
- 問題がなければ対象を段階的に広げる
特定の新規画面だけで使いたい場合は、コンテナの内側に限定できます。
.new-page,
.new-page * ,
.new-page *::before,
.new-page *::after {
box-sizing: border-box;
}
ただし、bodyの標準余白のようにコンテナ外で決まる値は、この方法では変わりません。既存テーマでは、まず現在のベースCSSを確認し、本当に追加のリセットが必要かを判断してください。
導入時の実務チェックリスト
CSSリセットを採用するときは、次の項目を確認すると事故を減らせます。
- リセットの目的を「余白」「幅計算」「ブラウザ差」など具体的に決めた
- リセットCSSを独自スタイルより先に読み込んだ
- 外部ライブラリを使う場合はバージョンを固定した
- 見出し、段落、リストに必要な余白を付け直した
- リストのマーカーを必要な場所まで消していない
- リンクとボタンを見分けられる
- キーボードのフォーカス表示が残っている
- 画像や動画がコンテナからはみ出さない
- フォーム部品を主要なOSとブラウザで操作した
- スマートフォン幅と文字拡大時の表示を確認した
最初に導入するなら、box-sizing: border-box、body { margin: 0; }、メディア要素のmax-width: 100%を中心に始めるのが実用的です。その後、実際に繰り返し上書きしている標準スタイルだけをリセットへ追加します。
CSSリセットの価値は、コードの長さではなく、プロジェクトの初期値を開発者が説明できる状態にすることにあります。次に確認すべきなのは、リセット後の画面がきれいかどうかだけではありません。Tabキーで一周し、フォームを入力し、狭い画面で横スクロールが出ないかまで試して、初めて安全な土台になります。
