Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

normalize.css User Guide

Generated June 2026 from necolas/normalize.css at fc091cc

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

normalize.css is a small, dependency-free CSS file that makes browsers render HTML elements more consistently. You drop it into your page before your own styles, and it irons out the dozens of tiny differences in how Chrome, Firefox, Safari, Edge, Internet Explorer, and Opera apply their default styling — without wiping those defaults out the way a traditional "CSS reset" does.

This guide shows you how to install it, include it correctly, understand exactly what it changes, customize it, and troubleshoot the rough edges. Everything here is taken directly from the normalize.css source (v8.0.1) and the project's own documentation.

Note

normalize.css is a single static stylesheet. There is no command-line tool, no JavaScript, no configuration file, and no build step required to use it. If you can add a <link> tag or an @import, you can use it.


1. Quick Start

The fastest way to try normalize.css is to link it from a CDN and load it before your own stylesheet.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- 1. normalize.css FIRST -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.css">

    <!-- 2. your own styles SECOND, so they win -->
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <h1>Hello, consistent world</h1>
  </body>
</html>

That is the entire integration: one stylesheet, loaded before yours. From here, write your CSS as normal — you are now building on a level, cross-browser foundation.

Important

Order matters. normalize.css must be loaded before your own CSS. It only sets sensible defaults; your stylesheet is meant to override them. Load it last and your own rules may be silently overridden by normalize.css.

Tip

Pin a specific version (@8.0.1) rather than a floating "latest" URL. The project treats any change to a CSS rule as a breaking change (see Versioning), so an unpinned URL could shift your baseline styling without warning.


2. What normalize.css Does

normalize.css targets known, documented inconsistencies between browsers and nudges each element toward one predictable rendering. Its design goals, as stated by the project, are:

  • Preserves useful defaults, unlike many CSS resets — headings still look like headings, lists still have bullets.
  • Normalizes styles for a wide range of elements.
  • Corrects bugs and common browser inconsistencies.
  • Improves usability with subtle modifications (for example, the dotted underline on abbreviations).
  • Explains what code does using detailed comments, so the file is also documentation.

normalize.css vs. a CSS reset

A classic CSS reset (such as the well-known Meyer reset) strips all default styling to zero — every margin, every font size, every list bullet — and forces you to rebuild every element from scratch. normalize.css takes the opposite approach: it keeps the helpful browser defaults and only fixes the parts that differ between browsers or are outright bugs.

Aspect Traditional reset normalize.css
Default margins/padding Removed everywhere Kept where useful (only body margin is removed)
Headings (h1–h6) Flattened to body text Preserved; only h1-in-section sizing is corrected
Lists Bullets/numbers removed Preserved
Approach "Erase, then rebuild" "Fix only what's broken"
File focus Blanket overrides Targeted, per-element, commented fixes

Tip

Because normalize.css preserves defaults, you generally write less of your own CSS than you would after a full reset — you only style what you actually want to change.


3. Installation

normalize.css ships as a single file. Choose whichever delivery method fits your project.

npm

npm install --save normalize.css

Installs version 8.0.1 into node_modules/normalize.css/normalize.css.

Yarn

yarn add normalize.css

CDN

<link rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.css">

Any npm-backed CDN (jsDelivr, unpkg, cdnjs) serves the package, because the npm files list publishes normalize.css and LICENSE.md.

Download

Download the raw file and commit it into your project:

curl -O https://necolas.github.io/normalize.css/latest/normalize.css

Then link it locally:

<link rel="stylesheet" href="/css/normalize.css">

Copy & paste

The file is only ~350 lines. For a one-page demo you can paste its contents straight into the top of your own stylesheet or a <style> block. Keep the license header comment intact (/*! normalize.css v8.0.1 | MIT License ... */).

After installing via a package manager, the published package contains exactly two files:

File Purpose
normalize.css The stylesheet itself (the main and style entry point)
LICENSE.md MIT license text

Note

The npm package intentionally ships no minified build. If you want a minified normalize.min.css, run the file through your own bundler or a CSS minifier — the project does not publish one (a request for this was declined, issue #911).


4. Including It in Your Project

How you wire normalize.css in depends on your toolchain. In every case the rule is the same: normalize.css comes first, your styles come after.

4.1 Plain HTML

Two <link> tags, in order:

<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="app.css">

4.2 Sass / SCSS

Forward it at the very top of your main stylesheet so it sits at the base of the cascade:

// main.scss
@import 'normalize.css/normalize.css';

// ...your partials below
@import 'base';
@import 'layout';
@import 'components';

4.3 PostCSS / postcss-import

/* app.css */
@import 'normalize.css';

/* your rules follow */
body { font-family: system-ui, sans-serif; }

4.4 webpack / Vite / bundlers

Import it once, as early as possible in your entry file (before your own CSS imports), so it is emitted first in the bundle:

// main.js (entry point)
import 'normalize.css';   // base layer — must be imported before app styles
import './styles/app.css';

4.5 React / Vue / Angular

The same import rule applies — put it in your root entry file so every component inherits the normalized baseline:

React

// src/index.jsx
import 'normalize.css';
import './index.css';

Vue

// src/main.js
import 'normalize.css';
import './assets/app.css';

Angular

// angular.json -> projects > <app> > architect > build > options > styles
"styles": [
  "node_modules/normalize.css/normalize.css",
  "src/styles.css"
]

Warning

In bundlers, CSS is applied in import order, not file name order. If your app styles "win" when they shouldn't, or normalize's defaults override your overrides, check that import 'normalize.css' appears before every one of your own style imports in the entry file.


5. What It Normalizes — Reference

normalize.css is organized into the same eight thematic sections you will find as comment banners in the file. Each rule below lists the element(s) it targets, what it does, and which browsers it is correcting. Use this as a lookup: if an element renders unexpectedly, find it here to see whether normalize.css is already touching it.

5.1 Document

Selector What normalize.css sets Why
html line-height: 1.15 Corrects the default line height in all browsers
html -webkit-text-size-adjust: 100% Prevents font-size adjustments after orientation changes in iOS

5.2 Sections

Selector What normalize.css sets Why
body margin: 0 Removes the default body margin in all browsers (the one opinionated layout change)
main display: block Renders the main element consistently in Internet Explorer
h1 font-size: 2em; margin: 0.67em 0 Corrects font size and margin on h1 inside section/article in Chrome, Firefox, and Safari

Note

body { margin: 0 } is the single layout opinion normalize.css holds. Everything else is a correction of a genuine bug or inconsistency. If you need the default 8px body margin back, simply re-add it in your own CSS.

5.3 Grouping Content

Selector What normalize.css sets Why
hr box-sizing: content-box; height: 0 Adds correct box sizing in Firefox
hr overflow: visible Shows the overflow in Edge and IE
pre font-family: monospace, monospace Corrects font-size inheritance and scaling of preformatted text in all browsers
pre font-size: 1em Corrects the odd em font sizing in all browsers

Note

The duplicated monospace, monospace is intentional, not a typo. The repetition is a deliberate hack that fixes how browsers inherit and scale the font size of preformatted text. Leave it as-is if you copy rules out of the file.

5.4 Text-level Semantics

Selector What normalize.css sets Why
a background-color: transparent Removes the gray background on active links in IE 10
abbr[title] border-bottom: none Removes the bottom border in Chrome 57-
abbr[title] text-decoration: underline dotted Adds correct text decoration in Chrome, Edge, IE, Opera, and Safari
b, strong font-weight: bolder Adds the correct bold font weight in Chrome, Edge, and Safari
code, kbd, samp font-family: monospace, monospace; font-size: 1em Same monospace inheritance/scaling fix as pre
small font-size: 80% Adds the correct small font size in all browsers
sub, sup font-size: 75%; line-height: 0; position: relative; vertical-align: baseline Prevents sub/sup from affecting line height in all browsers
sub bottom: -0.25em Positions subscript correctly
sup top: -0.5em Positions superscript correctly

Tip

The abbr[title] rule gives you a tidy dotted underline (with a solid underline as a fallback for older browsers). It is one of the "usability improvement" rules — give your abbreviations a title attribute to benefit from it: <abbr title="HyperText Markup Language">HTML</abbr>.

5.5 Embedded Content

Selector What normalize.css sets Why
img border-style: none Removes the border on images inside links in IE 10

5.6 Forms

Form controls are where browsers differ the most, so this is the largest section.

Selector What normalize.css sets Why
button, input, optgroup, select, textarea font-family: inherit; font-size: 100%; line-height: 1.15; margin: 0 Makes form controls inherit your page font instead of the browser's; removes default margins in Firefox and Safari
button, input overflow: visible Shows overflow in Edge and IE
button, select text-transform: none Removes inherited text-transform in Edge, Firefox, and IE
button, [type="button"], [type="reset"], [type="submit"] -webkit-appearance: button Makes clickable button types stylable in iOS and Safari
button::-moz-focus-inner, [type="button"]::-moz-focus-inner, … border-style: none; padding: 0 Removes the inner border and padding in Firefox
button:-moz-focusring, … outline: 1px dotted ButtonText Restores the focus outline Firefox loses from the rule above (keeps keyboard focus visible)
fieldset padding: 0.35em 0.75em 0.625em Corrects fieldset padding in Firefox
legend box-sizing: border-box; color: inherit; display: table; max-width: 100%; padding: 0; white-space: normal Fixes text wrapping (Edge/IE), color inheritance (IE), and removes padding for consistency
progress vertical-align: baseline Adds correct vertical alignment in Chrome, Firefox, and Opera
textarea overflow: auto Removes the default vertical scrollbar in IE 10+
[type="checkbox"], [type="radio"] box-sizing: border-box; padding: 0 Adds correct box sizing and removes padding in IE 10
[type="number"]::-webkit-inner-spin-button, …-outer-spin-button height: auto Corrects the cursor style of the increment/decrement buttons in Chrome
[type="search"] -webkit-appearance: textfield; outline-offset: -2px Corrects the odd appearance in Chrome/Safari and the outline style in Safari
[type="search"]::-webkit-search-decoration -webkit-appearance: none Removes the inner padding in Chrome/Safari on macOS
::-webkit-file-upload-button -webkit-appearance: button; font: inherit Makes the file-upload button stylable in iOS/Safari and inherits font in Safari

Important

The form font rule (font-family: inherit; font-size: 100%) is the change you are most likely to notice. Without normalize.css, <button>, <input>, and <textarea> use the browser's own UI font; with it, they inherit your page font. This is intentional and almost always what you want — but if a control suddenly looks different from the raw browser default, this rule is why.

5.7 Interactive

Selector What normalize.css sets Why
details display: block Adds correct display in Edge, IE 10+, and Firefox
summary display: list-item Adds correct display (with disclosure triangle) in all browsers

5.8 Misc

Selector What normalize.css sets Why
template display: none Adds correct display in IE 10+
[hidden] display: none Adds correct display in IE 10 (makes the hidden attribute work)

6. Customizing and Extending

normalize.css gives you a baseline. You build on top of it with your own CSS.

6.1 Override after, never edit in place

The cleanest pattern is to leave normalize.css untouched and put your changes in your own stylesheet that loads afterward. Because your rules come later in the cascade (and CSS specificity ties break toward the last rule), they win:

/* normalize.css set body margin to 0 — bring back a default margin if you want it */
body {
  margin: 8px;
}

/* normalize.css set links transparent — give yourself a brand color */
a {
  color: #0b5fff;
}

Tip

Keeping normalize.css unmodified means you can drop in a newer version later by swapping one file, with no merge conflicts against your edits.

6.2 Be aware of the one opinion

The only purely opinionated layout rule is body { margin: 0 }. If your design expects the browser's default 8px body margin, add it back yourself (as shown above). Every other rule is a bug fix, so overriding those usually means you are re-introducing a browser inconsistency — do it deliberately.

6.3 Removing rules you don't need

If you are targeting only modern evergreen browsers and never Internet Explorer, some IE-specific corrections (for example the main { display: block } and several [type="…"] box-sizing fixes) are no longer strictly necessary. You can fork the file and delete the rules whose comments name only browsers you do not support. Keep the file's structure and comments intact so the next person understands what was removed.

Caution

Do not delete a rule just because you do not recognize the browser it names. Many corrections (the form font inheritance, sub/sup line-height, the abbr underline) apply to all browsers, including the newest ones. Removing those brings back real inconsistencies.


7. Browser Support

normalize.css v8 officially supports:

Browser Supported versions
Chrome Current
Edge Current
Firefox ESR and newer
Internet Explorer 10 and newer
Safari 8 and newer
Opera Current

Note

Support for older engines (Android 4, Internet Explorer 9 and below, Safari 7 and below) was removed in v8.0.0. If you still need those, you would have to use an older release of normalize.css — but doing so is rarely advisable on the modern web.


8. Troubleshooting

Each entry below follows the same shape: the symptom, why it happens, and what to do. These are drawn from the project's documented "known issues" and from real issues reported by its community.

Issue: Form controls don't use my page font

Cause: This is normalize.css working as intended — button, input, select, and textarea are set to font-family: inherit; font-size: 100%, so they inherit from their container.

Solution: Nothing to fix if your container has the font you want. If a control still looks wrong, set the font explicitly on it or on a shared ancestor:

button, input, select, textarea {
  font-family: inherit;
}

Prevention: Define your base font on body (or :root) so every control inherits it.

Issue: select won't take my font weight or border styling

Cause: By default, Chrome and Safari on macOS allow only very limited styling of <select> unless a border property is set, and the font weight on <optgroup> cannot be safely changed in those browsers.

Solution: Set a border on the select to unlock further styling, and accept that optgroup weight is not reliably controllable on macOS Chrome/Safari:

select {
  border: 1px solid #999;
}

Prevention: For fully custom dropdowns, build a custom component rather than restyling the native select.

Issue: Checkbox/radio inputs ignore my box-sizing, padding, or width

Cause: Firefox's implementation of [type="checkbox"] and [type="radio"] does not respect box-sizing, padding, or width. normalize.css already sets box-sizing: border-box; padding: 0 to make them consistent, but further sizing is unreliable.

Solution: The project explicitly recommends not styling the box of native checkboxes and radios. If you need custom visuals, hide the native control and draw your own with a sibling element.

Prevention: Reach for a custom-control pattern instead of fighting the native box model.

Issue: The number input's decrement-button cursor flickers to a text cursor

Cause: Certain font-size values on [type="number"] cause Chrome to change the cursor of the decrement button from default to text. normalize.css sets height: auto on the spin buttons to mitigate the appearance.

Solution: Avoid unusual font sizes on number inputs, or set an explicit cursor:

input[type="number"]::-webkit-inner-spin-button {
  cursor: default;
}

Issue: I can't style a search input's font, padding, border, or background

Cause: Search inputs are not fully stylable by default. In Chrome and Safari on macOS/iOS you cannot control font, padding, border, or background; on Windows the border only shows a 1px color you cannot fully control.

Solution: normalize.css already applies -webkit-appearance: textfield to [type="search"], which restores most styling control without removing the input's useful behaviors (such as showing past searches). If you still hit limits, fall back to a regular [type="text"] styled to look like a search box.

[type="search"] {
  -webkit-appearance: textfield;
}

Issue: <button> text is blue on iOS

Cause: iOS Safari's user agent stylesheet colors button text blue; this is a platform default outside the elements normalize.css resets (reported in issue #886).

Solution: Set the color explicitly:

button {
  color: inherit;
}

Issue: Buttons/inputs show a 2px border-radius in Microsoft Edge

Cause: Edge applies a small default border-radius to native controls (issue #838). normalize.css does not reset border-radius on buttons.

Solution: Zero it yourself if your design needs square corners:

button, input {
  border-radius: 0;
}

Cause: Strict CSP setups require a nonce (or hash) on style sources (issue #908). normalize.css is just a stylesheet — it has no special CSP handling.

Solution: Serve it as an external file and allow that origin in your style-src, or add the appropriate nonce to the <link>/<style> per your CSP configuration. There is nothing normalize-specific to change.

Issue: <progress> or [type="range"] looks vertically misaligned

Cause: Browsers disagree on the baseline of these controls (issue #904). normalize.css sets progress { vertical-align: baseline }, which helps but does not cover every range-slider quirk.

Solution: Set an explicit vertical-align (e.g. middle) on the control where the alignment matters to your layout.

Tip

For any element you find rendering oddly, first check Section 5 to see whether normalize.css is already touching it. If it is not listed there, the behavior is coming from the browser's own user-agent stylesheet, and you should override it in your CSS.


9. FAQ

Q: Do I still need normalize.css in 2025-era browsers? It remains useful for the rules that apply to all browsers — form-control font inheritance, sub/sup line-height, the abbr underline, consistent monospace sizing — even if the Internet-Explorer-specific fixes matter less to you. Many projects include it (or a fork of it) by habit because it is tiny and harmless.

Q: Will it conflict with my CSS framework? No. It only sets element-level defaults. Load it before your framework and your own styles, and both will override it where they specify rules.

Q: Does it include any JavaScript? No. normalize.css is a single CSS file with zero scripts and zero dependencies.

Q: Is there a minified version? The project does not publish one (issue #911). Run the file through any CSS minifier or your bundler to produce normalize.min.css yourself.

Q: Should normalize.css go before or after my own CSS? Before. It is a baseline; your styles are meant to override it.

Q: It removed my body margin — is that a bug? No. body { margin: 0 } is the one intentional layout opinion in the file. Add the margin back in your own CSS if you want it.

Q: Why is monospace written twice in the pre/code rule? That is a deliberate hack that fixes font-size inheritance and scaling for preformatted/monospace text across browsers. It is not a typo.

Q: Can I delete the Internet Explorer rules? If you truly do not support IE, you can fork the file and remove the rules whose comments name only IE. Keep the all-browser rules — they still apply to modern engines.

Q: How do I customize a normalized element? Write your own rule for it in a stylesheet that loads after normalize.css. See Section 6.

Q: Is the project still actively maintained? The latest release is 8.0.1 (November 2018), and the community has asked about maintenance status (issue #880). Treat v8.0.1 as a stable, frozen baseline. It continues to work because it targets long-standing browser behaviors, but do not expect new releases. See the Admin Guide's "Maintenance & Known Issues" section for a fuller picture.

Q: What license is it under? MIT — free to use, modify, and redistribute, including commercially. Keep the license header comment in the file.

Q: How do I verify it loaded? Open your page in a browser, inspect <body>, and confirm its computed margin is 0. The included test.html in the repo also exercises every normalization visually.


10. Reference

10.1 Package facts

Field Value
Name normalize.css
Version 8.0.1
Description A modern alternative to CSS resets
Main / Style entry normalize.css
License MIT
Dependencies None
Published files normalize.css, LICENSE.md
Homepage https://necolas.github.io/normalize.css

10.2 The eight sections at a glance

# Section Elements covered
1 Document html
2 Sections body, main, h1
3 Grouping content hr, pre
4 Text-level semantics a, abbr[title], b, strong, code, kbd, samp, small, sub, sup
5 Embedded content img
6 Forms button, input, optgroup, select, textarea, fieldset, legend, progress, [type="checkbox"], [type="radio"], [type="number"], [type="search"], file-upload button
7 Interactive details, summary
8 Misc template, [hidden]

10.3 Versioning and upgrades

The project follows semantic versioning with one unusual twist: because any change to a CSS rule changes how pages render, every rule change is a major version bump. There are effectively no "minor" releases — only major (rule changes) and patch (changes with no rendering impact). This is why pinning a specific version matters: upgrading across a major version may visibly shift your baseline styling, so test after upgrading.

10.4 Setup checklist

  • [ ] Installed normalize.css (npm, CDN, or download)
  • [ ] Linked/imported it before your own stylesheet
  • [ ] Pinned a specific version (8.0.1) rather than "latest"
  • [ ] Confirmed body computed margin is 0 in DevTools
  • [ ] Re-added the body margin in your own CSS if your design needs it
  • [ ] Verified form controls inherit your page font