- CSS
リセットCSSおすすめ比較2026 コピペで使える最小構成と選び方
リセットCSSとは、ブラウザが最初から持っているスタイル(余白・文字サイズ・リストの記号など)を打ち消したり揃えたりして、自分のCSSを書きやすくするための土台のCSSです。 2026年時点では「全部消す」よりも、「必要なところだけ整え、あとから上書きしやすくする」書き方が主流になっています。
この記事では、よく使われる7種類のリセットCSSを npm から実際に入れて、バージョン・公開日・ファイルサイズを測り、見出しやリストがどう変わるかを Chromium で計測して比べました。そのうえで、そのまま貼って使える注釈つきの最小リセット全文を載せ、1行ずつ「何を防ぐのか」を説明します。@layer と :where() による上書きしやすい書き方、text-wrap・interpolate-size・prefers-reduced-motion といった新しめの項目、Tailwind CSS の Preflight を使うときの扱いも取り上げます。計測は Chromium 141.0.7390.37(Playwright 1.56.0)、パッケージの情報は 2026-10-03 時点の npm レジストリのものです。
リセットCSSの選び方の早見表
| やりたいこと | おすすめ | ひとことで言うと |
|---|---|---|
| まず最小限だけ整えたい・中身を全部理解して使いたい | この記事の最小リセット、または Josh Comeau 版 | 15項目(コメント込みで約60行)。余白・画像・フォーム・文字の折り返しを整える |
| ブラウザ標準の見た目を活かしつつ差だけ揃えたい | modern-normalize | 見出しの大きさやリストの記号は残る |
| デザインカンプどおりに一から組みたい | destyle.css または The New CSS Reset | 見出しも本文と同じ大きさになり、ボタンの背景も消える |
| 余白は消したいが見出しの大きさは残したい | ress | 全要素の margin と padding を 0 にする |
| フォームやメディアまで幅広く整えたい | sanitize.css | ノーマライズ寄りで、用途別の追加ファイルがある |
| Tailwind CSS を使っている | 追加しない(Preflight が入っている) | 二重にかけると意図しない上書きが起きる |
| ブログ記事など文章中心のページ | modern-normalize か最小リセット | 箇条書きや見出しを自分で作り直す手間が少ない |
用語も先に整理しておきます。
| 用語 | 方針 | 代表例 |
|---|---|---|
| リセット | ブラウザ標準のスタイルを打ち消してゼロに近づける | destyle.css、The New CSS Reset、ress |
| ノーマライズ | 標準スタイルは残し、ブラウザ間の差だけを揃える | modern-normalize、sanitize.css、normalize.css |
| モダンリセット(最小リセット) | 作業の妨げになりやすい所だけを整える | modern-css-reset、Josh Comeau 版 |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「リセットCSSおすすめ比較2026 コピペで使える最小構成と選び方」
リセットとノーマライズの違いを実測で比べる
言葉の説明だけでは違いがつかみにくいので、同じHTML(h1・p・ul・button・幅300pxの箱に入れた 800×600 の img)に各CSSだけを当て、Chromium で計算後のスタイルを取りました。画像には width="800" height="600" の属性を付けています。
| CSS | h1 の大きさ/太さ | h1 上余白 | p 上余白 | ul の記号/左余白 | body 余白 | button 背景 | 画像(幅300pxの箱の中) |
|---|---|---|---|---|---|---|---|
| なし(ブラウザ標準) | 32px/700 | 21.44px | 16px | disc/40px | 8px | 灰色 | 800×600(はみ出す) |
| modern-css-reset 1.4.0 | 32px/700 | 0 | 0 | disc/40px | 0 | 灰色 | 300×600 |
| The New CSS Reset 1.11.3 | 16px/400 | 0 | 0 | none/0 | 0 | 透明 | 300×600 |
| destyle.css 4.0.1 | 16px/400 | 0 | 0 | none/0 | 0 | 透明 | 800×600 |
| ress 6.0.0 | 32px/700 | 0 | 0 | disc/0 | 0 | 透明 | 800×600 |
| modern-normalize 3.0.1 | 32px/700 | 21.44px | 16px | disc/40px | 0 | 灰色 | 800×600 |
| sanitize.css 13.0.0 | 32px/700 | 21.44px | 16px | disc/40px | 0 | 灰色 | 800×600 |
| normalize.css 8.0.1(参考) | 32px/700 | 21.44px | 16px | disc/40px | 0 | 灰色 | 800×600 |
| Tailwind Preflight 4.3.3 | 16px/400 | 0 | 0 | none/0 | 0 | 透明 | 300×225 |
| この記事の最小リセット | 32px/700 | 0 | 0 | disc/40px(role="list" を付けたものだけ none/0) |
0 | 灰色 | 300×225 |
この表から、3つのグループの性格が読み取れます。
- ノーマライズ系(modern-normalize、sanitize.css、normalize.css)は、body の余白を 0 にする以外、見出しや段落の見た目をほぼ変えません。
- リセット系(The New CSS Reset、destyle.css)は、見出しが本文と同じ 16px・通常の太さになり、リストの記号も消えます。 すべて自分のCSSで作り直す前提です。
- ress はその中間で、余白はすべて 0 にしつつ、見出しの大きさと太さ、リストの記号は残します(左余白が 0 になるので、記号は箱の外側にはみ出して表示されます)。
画像の列にも注目してください。modern-css-reset と The New CSS Reset は max-width: 100% で幅を 300px に収めますが、height: auto を指定していないため、HTML に height 属性が付いた画像は高さが 600px のまま残り、縦に伸びて表示されます。自分のCSSに img { height: auto; } を1行足すと 300×225 に収まります(この記事の最小リセットと Tailwind Preflight には最初から入っています)。
おすすめリセットCSS 7種の比較表
npm レジストリから取得した版・公開日と、パッケージ内のファイルを測ったサイズです。gzip は gzip -9 で圧縮したバイト数です。
| 名前 | 方針 | 最新版(公開日) | サイズ(通常/min) | gzip 後 | 見出し | リスト | ライセンス |
|---|---|---|---|---|---|---|---|
| modern-css-reset(Andy Bell) | モダンリセット | 1.4.0(2021-01-18) | 1,222B/623B | 382B(min) | 余白のみ 0(h1〜h4) | role="list" 付きだけ記号なし |
MIT |
| Josh Comeau 版 | モダンリセット | npm 配布なし(記事ページ掲載。ページの最終更新表記は 2026年6月) | 約40行 | 未計測 | 余白 0、text-wrap: balance |
そのまま(余白だけ 0) | 記事掲載コード |
| The New CSS Reset | リセット(all: unset) |
1.11.3(2024-08-24) | 2,901B/min 同梱なし | 1,307B | 本文と同じ大きさ・太さ | 記号なし・余白 0 | MIT |
| destyle.css | リセット | 4.0.1(2024-01-21) | 6,132B/2,238B | 969B(min) | 本文と同じ大きさ・太さ | 記号なし・余白 0 | MIT |
| ress | ノーマライズ+余白リセット | 6.0.0(2026-08-08) | 6,693B/2,281B | 889B(min) | 大きさは残り余白 0 | 記号は残り余白 0 | MIT |
| modern-normalize | ノーマライズ | 3.0.1(2024-09-05) | 3,338B/min 同梱なし | 1,345B | 標準のまま | 標準のまま | MIT |
| sanitize.css | ノーマライズ(拡張) | 13.0.0(2021-09-14) | 7,381B/min 同梱なし | 1,999B | 標準のまま | nav 内のリストだけ記号なし |
CC0-1.0 |
参考として、normalize.css は 8.0.1(2018-11-09 公開、6,138B、gzip 1,751B)、Tailwind CSS 4.3.3 に入っている preflight.css は 8,489B(gzip 2,934B)でした。
どれも gzip 後は 2KB 以下で、サイズの差が表示速度に与える影響はごく小さいといえます。選ぶ基準は「サイズ」よりも「見出しやリストをどこまで消したいか」に置くのがおすすめです。
導入方法(npm と CDN)
npm で入れる場合のコマンドと、パッケージ内のファイルパスです(パスは今回インストールして確認しました)。
npm i modern-css-reset the-new-css-reset destyle.css ress modern-normalize sanitize.css
| 名前 | パッケージ内のファイル | import の例 |
|---|---|---|
| modern-css-reset | dist/reset.css、dist/reset.min.css |
@import "modern-css-reset/dist/reset.min.css"; |
| The New CSS Reset | css/reset.css |
@import "the-new-css-reset/css/reset.css"; |
| destyle.css | destyle.css、destyle.min.css |
@import "destyle.css/destyle.min.css"; |
| ress | ress.css、dist/ress.min.css |
@import "ress/dist/ress.min.css"; |
| modern-normalize | modern-normalize.css |
@import "modern-normalize/modern-normalize.css"; |
| sanitize.css | sanitize.css(ほかに forms.css、typography.css、reduce-motion.css など) |
@import "sanitize.css/sanitize.css"; |
CDN から読み込む場合は、jsDelivr の「https://cdn.jsdelivr.net/npm/パッケージ名@バージョン/ファイルパス」という形式に、上の表のパスを当てはめます。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/destyle.css@4.0.1/destyle.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ress@6.0.0/dist/ress.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/modern-normalize@3.0.1/modern-normalize.css">
<link rel="stylesheet" href="css/style.css">
検証環境から CDN へは接続できなかったため、CDN の URL での読み込みは未実行です(パッケージ名・バージョン・ファイルパスは npm で確認済み)。使う前にブラウザで URL を開いて確かめてください。リセットCSSは自分のCSSより前に読み込むのが基本です。また、バージョンを @4.0.1 のように固定しておくと、あとから内容が変わって表示がずれることを避けられます。
7種それぞれの特徴
modern-css-reset(Andy Bell):モダンリセットの定番です。npm の 1.4.0 は 2021年公開で、全文は約70行。box-sizing、主要な要素の margin を 0、画像を display: block と max-width: 100%、フォームの font: inherit、動きを減らす設定が入っています。作者は 2023年9月18日に更新版「A (more) Modern CSS Reset」をブログで公開しており(今回ページを開いて確認)、そちらには text-wrap: balance、text-size-adjust: none、:target の scroll-margin-block などが加わっています。更新版は npm パッケージには反映されていないため、使う場合は記事からコピーします。
Josh Comeau 版(A Modern CSS Reset):記事ページに掲載されている10項目のリセットです。今回ページを開いて確認した内容では、*:not(dialog) に margin: 0、prefers-reduced-motion: no-preference のときだけ interpolate-size: allow-keywords、p に text-wrap: pretty、見出しに text-wrap: balance が入っていました。各行の理由が記事で丁寧に説明されているので、学習用にも向いています。
The New CSS Reset:all: unset と display: revert で、display 以外のブラウザ標準スタイルをまとめて外す方式です。セレクタ全体が :where() で包まれているため詳細度が 0 で、あとから書いたCSSで簡単に上書きできます。見出しもボタンも素の状態になるので、デザインシステムを一から組む場合に合います。
destyle.css:normalize.css をもとに、見出しの大きさ・太さ、リストの記号、ボタンやフォームの見た目までリセットします。min 版が同梱され、gzip 後 969B でした。日本語の制作記事でもよく紹介されています。
ress:normalize.css をベースに、* セレクタで全要素の margin と padding を 0 にします。2026年8月に 6.0.0 が公開されており、今回比べた中では npm の公開日がもっとも新しいものでした。見出しの大きさは残るので、文章の構造が見た目に残ります。
modern-normalize:normalize.css を現行ブラウザ向けに絞り込んだものです。box-sizing: border-box、system-ui を先頭にしたフォント指定、tab-size: 4、line-height: 1.15 などが入り、見出しや段落の余白は標準のままです。
sanitize.css:ノーマライズに加えて、nav 内のリストの記号を消す、background-repeat: no-repeat を既定にするなど、制作でよく書く指定を含みます。forms.css・typography.css・reduce-motion.css などの追加ファイルを必要に応じて足せる構成です。
コピペで使える注釈つき最小リセット全文
ここからは、ライブラリを入れずに自分のCSSの先頭へ貼って使える最小構成です。全体を @layer reset に入れ、要素セレクタを :where() で包んで、あとから書くCSSが必ず勝つようにしてあります。
/* ============================================
Minimal Reset 2026
自分のCSSより前に読み込む
============================================ */
@layer reset {
/* 1. 幅と高さに padding と border を含める */
*, *::before, *::after { box-sizing: border-box; }
/* 2. スマホを横向きにしたときの文字サイズ自動拡大を止める / タブ幅を4に */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; tab-size: 4; }
/* 3. height: auto へのアニメーションを許可(動きを減らす設定の人には適用しない) */
@media (prefers-reduced-motion: no-preference) {
html { interpolate-size: allow-keywords; }
}
/* 4. body の余白を消し、画面の高さいっぱいに。行間を読みやすく */
body { margin: 0; min-height: 100svh; line-height: 1.5; -webkit-font-smoothing: antialiased; }
/* 5. 見出し・段落などの上下余白を消す(大きさと太さは残す) */
:where(h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd) { margin: 0; }
/* 6. 見出しの各行の長さを揃える */
:where(h1, h2, h3, h4, h5, h6) { text-wrap: balance; }
/* 7. 長い英単語やURLが箱からはみ出さないよう折り返す */
:where(p, li, dd, h1, h2, h3, h4, h5, h6) { overflow-wrap: break-word; }
/* 8. 段落の最後の行に1語だけ残る折り返しを減らす */
:where(p) { text-wrap: pretty; }
/* 9. role="list" を付けたリストだけ記号と余白を消す */
:where(ul[role="list"], ol[role="list"]) { margin: 0; padding: 0; list-style: none; }
/* 10. 画像・動画を親の幅に収め、下の隙間をなくす */
:where(img, picture, video, canvas, svg) { display: block; max-width: 100%; }
/* 11. width/height 属性があっても縦横比を保つ */
:where(img, video) { height: auto; }
/* 12. フォーム部品の文字を周りと同じフォント・色にする */
:where(input, button, textarea, select) { font: inherit; color: inherit; }
/* 13. textarea のサイズ変更を縦方向だけにする */
:where(textarea) { resize: vertical; }
/* 14. 表のセルの境界線を1本にまとめる */
:where(table) { border-collapse: collapse; }
/* 15. 動きを減らす設定の人にはアニメーションをほぼ止める */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
}
当てる前と後の実測値
上のリセットを当てる前後で、Chromium 141 の計算後スタイルを比べました。
| 確認した項目 | リセットなし | リセットあり |
|---|---|---|
| body の margin | 8px | 0px |
| body の line-height | normal | 24px(16px × 1.5) |
| h1 の上余白/文字サイズ | 21.44px/32px | 0px/32px |
| h1 の text-wrap | wrap | balance |
| p の上余白/text-wrap-style | 16px/auto | 0px/pretty |
role="list" 付き ul |
disc・左余白 40px | none・左余白 0px |
| 属性なしの ul | disc・左余白 40px | disc・左余白 40px(変えない) |
| 幅300pxの箱の中の 800×600 画像 | 800×600、display: inline、箱の scrollWidth 800 | 300×225、display: block、scrollWidth 300 |
| 画像を入れた箱の高さ | 604px(下に4pxの隙間) | 225px(隙間なし) |
| button の文字 | 13.3333px/Arial | 16px/sans-serif(body を継承) |
| textarea のフォント | monospace | sans-serif(body を継承) |
| width:100px+padding:10px+border:5px の箱の実幅 | 130px | 100px |
| html の interpolate-size | numeric-only | allow-keywords(動きを減らす設定では numeric-only のまま) |
各行が何を防ぐのか
| 番号 | 指定 | 防げること・得られること |
|---|---|---|
| 1 | box-sizing: border-box |
width: 100px に padding や border を足すと 130px になり、横にはみ出すこと(実測 130px → 100px) |
| 2 | text-size-adjust: 100% |
スマートフォンを横向きにしたとき文字だけ大きくなること(スマートフォン実機では未実行)。tab-size: 4 はコード表示のタブ幅を 8 から 4 にする |
| 3 | interpolate-size: allow-keywords |
アコーディオンなどで height: 0 から height: auto へ変化させるとき、途中経過なしで一気に開くこと |
| 4 | body { margin: 0; min-height: 100svh; line-height: 1.5 } |
画面の端にできる 8px の余白、内容が少ないページでフッターが浮くこと、行間が詰まって読みにくいこと |
| 5 | 見出し・段落の margin: 0 |
要素ごとに異なる標準の余白(h1 は 21.44px、p は 16px)が、自分で決めた余白と足し合わさること |
| 6 | text-wrap: balance |
見出しの2行目に数文字だけ落ちること |
| 7 | overflow-wrap: break-word |
長いURLや英数字の連続が箱を突き抜けて横スクロールが出ること |
| 8 | text-wrap: pretty |
段落の最終行に短い語が1つだけ残ること |
| 9 | role="list" 付きリストのリセット |
ナビゲーション用のリストに記号と 40px の左余白が付くこと。本文の箇条書きは標準のまま残せる |
| 10 | 画像の display: block; max-width: 100% |
大きな画像が親をはみ出すこと、画像の下にできる数pxの隙間 |
| 11 | height: auto |
height 属性付きの画像が、幅だけ縮んで縦に伸びること(300×600 → 300×225) |
| 12 | font: inherit; color: inherit |
ボタンや入力欄だけ 13.33px の別フォントになること |
| 13 | resize: vertical |
textarea を横に引き伸ばしてレイアウトが崩れること |
| 14 | border-collapse: collapse |
表の罫線が二重になること |
| 15 | 動きを減らす設定への対応 | OS で「視差効果を減らす」などを有効にしている人に長いアニメーションを見せること |
見出しの大きさも本文に揃えたい場合や、すべてのリストの記号を消したい場合は、次の2行を自分のCSSに追加します。
@layer reset {
:where(h1, h2, h3, h4, h5, h6) { font-size: inherit; font-weight: inherit; }
:where(ul, ol) { margin: 0; padding: 0; list-style: none; }
}
追加した状態では、h1 が 16px/400、属性なしの ul が none・左余白 0px になることを確認しました。destyle.css や Preflight と同じ方針です。
@layer と :where() で上書きしやすくする
リセットCSSでつまずきやすいのが「リセットのほうが勝ってしまい、自分のCSSが効かない」という状況です。原因は詳細度(セレクタの強さ)と読み込み順にあります。短いCSSで確かめました。
:where() で詳細度をゼロにする
.menu { padding-left: 16px; } という自分のスタイルと、あとから読み込まれたリセットがぶつかる場合です。
/* A:通常のセレクタ */
.menu { padding-left: 16px; }
ul[role="list"] { padding: 0; }
/* B:要素名だけ :where() で包む */
.menu { padding-left: 16px; }
:where(ul)[role="list"] { padding: 0; }
/* B2:属性セレクタごと :where() で包む */
.menu { padding-left: 16px; }
:where(ul[role="list"]) { padding: 0; }
| 書き方 | リセット側の詳細度 | .menu の padding-left(実測) |
|---|---|---|
A ul[role="list"] |
0,1,1 | 0px(リセットが勝つ) |
B :where(ul)[role="list"] |
0,1,0 | 0px(同点なので後に書いたリセットが勝つ) |
B2 :where(ul[role="list"]) |
0,0,0 | 16px(自分のCSSが勝つ) |
:where() の外に属性セレクタやクラスが残っていると、その分の詳細度が残ります。 包むときはセレクタ全体を入れるのがポイントです。前述の最小リセットも B2 の形にしてあります。なお * セレクタはもともと詳細度が 0 なので、包まなくても同じです。
@layer で読み込み順に左右されなくする
@layer は、CSSを層に分けて優先順位を決める仕組みです。レイヤーに入っていないCSSは、レイヤーの中のCSSより常に優先されます。
/* C:レイヤーなし。後に書いたリセットが勝つ */
h1 { margin: 24px; }
h1, h2 { margin: 0; }
/* D:リセットをレイヤーに入れる */
h1 { margin: 24px; }
@layer reset { h1, h2 { margin: 0; } }
| パターン | h1 の margin-top(実測) |
|---|---|
| C レイヤーなし | 0px(後に書いたリセットで上書きされた) |
D リセットを @layer reset に入れる |
24px(自分のCSSが勝つ) |
D では、リセットを自分のCSSより後に書いても自分のCSSが有効でした。複数のレイヤーを使う場合は、最初に順番を宣言します。
@layer reset, base, components;
@layer components { .t { margin: 8px; } }
@layer base { h1.t.t { margin: 32px; } }
@layer reset { h1 { margin: 0; } }
この例の h1 の margin-top は 8px でした。base 側のセレクタ(h1.t.t)のほうが詳細度は高いのに、後ろに宣言したレイヤー(components)が勝ちます。詳細度よりレイヤーの順番が先に評価されるためです。
既存のライブラリをレイヤーに入れることもできます。
@layer reset, base, components;
@import url("destyle.css/destyle.min.css") layer(reset);
(@import ... layer() での読み込みは、この記事では未実行です。)
レイヤーで知っておきたい2つの挙動
1. !important は順番が逆になる
.a { transition-duration: 2s !important; }
@layer reset { * { transition-duration: .01ms !important; } }
この場合の .a の transition-duration は 0.00001s(0.01ms)でした。!important 付きの宣言は、レイヤー内のものがレイヤー外より優先されます。 最小リセットの15番(動きを減らす設定)が、ほかのCSSに !important があっても働くのはこのためです。
2. ブラウザ標準に戻したいときは revert を使う
リセットで消したリストの記号を、記事本文の中だけ戻したい場合です。
@layer reset { ul { list-style: none; } }
@layer base { .prose ul { list-style: revert; } }
| 指定 | .prose ul の list-style-type(実測) |
|---|---|
list-style: revert |
disc(ブラウザ標準に戻る) |
list-style: revert-layer |
none(1つ前のレイヤー=reset の値に戻る) |
revert-layer は「前のレイヤーの値」に戻すため、リセットで消した値がそのまま返ってきます。ブラウザ標準を取り戻したいときは revert を使います。
2026年時点で加えたい項目
text-wrap: balance と pretty
text-wrap: balance は各行の長さを均等に近づけ、pretty は最終行に短い語だけが残るのを減らします。幅 300px・20px の見出しで、各行の幅を測りました。
| 指定 | 1行目の幅 | 2行目の幅 |
|---|---|---|
| なし | 281px | 220px |
text-wrap: balance |
241px | 260px |
指定なしでは 61px あった差が、balance では 19px に縮まりました。MDN の text-wrap のページ(今回開いて確認)では、プロパティ全体が Baseline「Widely available」(2024年3月から主要ブラウザで利用可能)とされ、一部の値は対応状況が異なる可能性があると注記されています。未対応のブラウザでは通常の折り返しになるだけなので、リセットに入れても表示が崩れることはありません。balance は行数の多い文章では計算量が増えるため、見出しのような短いテキストに使います。
interpolate-size: allow-keywords
これまで height: 0 から height: auto への変化は transition が効かず、一瞬で切り替わっていました。interpolate-size: allow-keywords を html に指定すると、auto などのキーワードへもなめらかに変化します。1秒の transition を開始して 0.4 秒後の高さを測りました(最終的な高さは 200px)。
| html への指定 | 0.4秒後の高さ(実測) |
|---|---|
| なし | 200px(すぐ最終値になる) |
interpolate-size: allow-keywords |
80px(途中経過を通って変化中) |
html { interpolate-size: allow-keywords; }
.panel { height: 0; overflow: hidden; transition: height 0.3s; }
.panel.is-open { height: auto; }
MDN の interpolate-size のページ(今回開いて確認)では「Limited availability」、つまり一部の主要ブラウザでは未対応とされています。今回動作を確かめたのは Chromium 141 のみです。未対応のブラウザでは従来どおり一瞬で開くだけなので、入れておいて困らない「先回りの指定」として扱えます。継承されるプロパティなので、html に1回書けばページ全体に効きます。
prefers-reduced-motion
OS の設定で動きを減らすよう指定している人に配慮するメディアクエリです。最小リセットでは2か所で使っています。
| 使っている場所 | 条件 | 内容 |
|---|---|---|
| 3番 | no-preference(設定していない人) |
interpolate-size を有効にする |
| 15番 | reduce(動きを減らしたい人) |
アニメーションとトランジションを 0.01ms にする |
Playwright で reducedMotion: 'reduce' を指定して開くと、html の interpolate-size は numeric-only のままで、3番が適用されないことを確認しました。15番で時間を 0 ではなく 0.01ms にしているのは、アニメーション終了時のイベントを待つ JavaScript がそのまま動くようにするためです。
そのほかの候補
Chromium 141 で CSS.supports() が true を返した、リセットに加える候補です。
| 指定 | 効果 | 入れるかどうかの目安 |
|---|---|---|
min-height: 100svh |
アドレスバーが出ている状態の画面の高さを基準にする | 最小リセットに採用済み |
field-sizing: content |
textarea や input が入力内容に合わせて伸びる | フォームが多いサイトで個別に指定 |
text-box: trim-both cap alphabetic |
文字の上下の余白を切り詰める | デザインに合わせて個別に指定 |
scrollbar-gutter: stable |
スクロールバーの有無で横幅が変わるのを防ぐ | 好みで html に追加 |
上の4つは Chromium 141 でサポート判定のみ確認し、表示の計測は行っていません。ほかのブラウザでの対応は未実行です。
Tailwind CSS の Preflight を使うときの扱い
Tailwind CSS には Preflight というリセットが最初から組み込まれています。tailwindcss 4.3.3 のパッケージに入っている preflight.css を読み、Chromium で当てて確認しました。
| Preflight の内容(4.3.3 のソースで確認) | 実測値 |
|---|---|
全要素の margin・padding を 0、border を 0 solid |
h1・p の上余白 0px、body の余白 0px |
見出しの font-size・font-weight を inherit |
h1 が 16px/400 |
ol・ul・menu の list-style: none |
ul が none・左余白 0px |
img・video などを display: block、max-width: 100%、height: auto |
幅300pxの箱で 300×225 |
フォーム部品の font: inherit、背景を透明に |
button の背景が透明、文字 16px |
| a の色と下線を inherit | リンクの下線なし、文字色は親と同じ |
html の line-height: 1.5 |
body の行間 24px |
Tailwind CSS 4 の index.css は @layer theme, base, components, utilities; で始まり、Preflight は base レイヤーに入ります。そのため扱いは次のようになります。
| 状況 | おすすめの扱い |
|---|---|
| Tailwind CSS だけで作る | リセットCSSを別に入れない。Preflight で足りる |
| 記事本文など、見出しやリストの見た目を戻したい | 対象の箱の中だけ list-style: revert などで戻す。または公式の typography プラグインを使う(未実行) |
Preflight にない項目(text-wrap、interpolate-size など)を足したい |
@layer base { ... } の中に必要な行だけ追加する |
| 既存サイトに Tailwind を部分的に入れる | Preflight が既存の見出しやリストの見た目を変えるので、theme と utilities だけを import して Preflight を外す構成を検討する(公式の手順は今回未確認・未実行) |
足す場合の例です。
@import "tailwindcss";
@layer base {
@media (prefers-reduced-motion: no-preference) {
html { interpolate-size: allow-keywords; }
}
:where(h1, h2, h3, h4, h5, h6) { text-wrap: balance; }
:where(p) { text-wrap: pretty; }
}
(Tailwind のビルドを通した確認は未実行です。preflight.css 単体を当てた結果と、index.css のレイヤー宣言の確認までを行いました。)
導入時のチェックリスト
| 確認すること | 見るポイント |
|---|---|
| 読み込み順 | リセットが自分のCSSより前にある。または @layer に入っている |
| 二重がけ | フレームワーク(Tailwind、Bootstrap など)のリセットと重ねていない |
| 見出し | h1〜h6 の大きさが意図どおり(リセット系は本文と同じになる) |
| 箇条書き | 本文の箇条書きに記号が必要なら、戻す指定を書いたか |
| 画像 | 親をはみ出さない。width/height 属性付きの画像が縦に伸びない |
| フォーム | ボタン・入力欄のフォントが周りと揃っている。フォーカス時の枠線が見える |
| バージョン固定 | CDN の URL や package.json で版を固定している |
| 動きの配慮 | OS の「動きを減らす」設定でアニメーションが止まる |
フォーカス時の枠線(outline)は、キーボードで操作する人にとって現在位置を知る手がかりです。リセット系のライブラリを使うときは、:focus-visible に自分のデザインの枠線を付けておくと親切です。
:where(a, button, input, select, textarea):focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
よくある質問
Q. リセットCSSは2026年でも必要ですか? A. ブラウザ間の差は以前より小さくなりましたが、body の 8px の余白、見出しや段落ごとに異なる余白、画像のはみ出し、フォーム部品だけ別のフォントになる、といった標準の挙動は今も残っています(この記事の「リセットなし」の実測値を参照)。全部を消す必要はなく、最小リセットのように必要な所だけ整える方法が扱いやすいです。
Q. リセットCSSとノーマライズCSSはどちらを選べばよいですか? A. 文章中心で標準の見出しや箇条書きを活かしたいならノーマライズ(modern-normalize)、デザインどおりに一から組むならリセット(destyle.css、The New CSS Reset)が合います。迷う場合は、余白と画像・フォームだけを整える最小リセットから始め、足りない分を足していくと、何が効いているかを把握しやすくなります。
Q. リセットCSSを入れたら自分のCSSが効かなくなりました。
A. リセット側のセレクタの詳細度が高いか、リセットが後から読み込まれている可能性があります。読み込み順を「リセット → 自分のCSS」にする、またはリセットを @layer reset { ... } に入れると、自分のCSSが優先されます(実測で h1 の余白が 0px から 24px に変わることを確認)。
Q. modern-css-reset は更新が止まっていても使えますか?
A. npm の 1.4.0 は 2021年公開ですが、内容は現在のブラウザでもそのまま働きます(Chromium 141 で確認)。text-wrap などの新しい項目は含まれていないので、必要なら作者の 2023年の更新版や、この記事の最小リセットを参考に数行足すとよいでしょう。画像に height: auto を足しておくと、height 属性付きの画像が縦に伸びるのを防げます。
まとめ
- リセットは「消す」、ノーマライズは「揃える」。実測では、destyle.css と The New CSS Reset は h1 が 16px/通常の太さになり、modern-normalize は body の余白以外ほぼ標準のまま。
- 7種とも gzip 後 2KB 以下。選ぶ基準はサイズより「見出し・リスト・ボタンをどこまで消したいか」。
- 2026-10-03 時点の npm 最新版は ress 6.0.0(2026-08)、modern-normalize 3.0.1(2024-09)、The New CSS Reset 1.11.3(2024-08)、destyle.css 4.0.1(2024-01)。
- 最小リセットは15項目。
box-sizing、余白、画像のmax-width: 100%とheight: auto、フォームのfont: inheritが中心。 @layer resetと:where()で包むと、読み込み順や詳細度を気にせず自分のCSSが勝つ。:where()はセレクタ全体を包む。text-wrap: balance/pretty、interpolate-size: allow-keywords、prefers-reduced-motionは、未対応ブラウザでも表示が崩れない追加項目。- Tailwind CSS では Preflight がリセットを兼ねるので、別のリセットは重ねず、足りない行だけ
@layer baseに追加する。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「リセットCSSおすすめ比較2026 コピペで使える最小構成と選び方」
株式会社RJCでは、リセットCSSの選び方やCSSの土台づくりを仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。