mrkeyoor.com_
Sat 08 Aug 22:51 UTC
npmWeb Frontendupdated 08 Aug 2026

sanitize.css

sanitize.css is a global CSS foundation that combines browser normalization with opinionated defaults such as border-box sizing, non-repeating backgrounds, zero body margin, a 1.5 root line height, overflow wrapping, normalized form quirks, vertical-only textarea resizing, collapsed table borders, and navigation-list cleanup. Most element rules use :where() for zero specificity so application styles can override them easily. Optional files separately cover forms, responsive assets, system typography, reduced motion, and legacy system font aliases. Despite the name, it does not sanitize untrusted CSS or HTML and provides no XSS protection.

Verdict

sanitize.css is a thoughtful, readable baseline for teams that agree with its opinions and test the global result. It is not a security tool, its IE claim conflicts with :where(), and the long gap between npm 13 and newer repository fixes makes pinning and source review essential.

API stability3/5CSS has no function API here, but selectors and defaults are an application-wide behavioral interface. Version 13's zero-specificity :where() approach makes downstream overrides easier, and optional concerns live in separate files with stable names. Stability is only moderate because every baseline rule affects arbitrary markup, main contains unreleased changes to assets, motion, horizontal rules, and mask backgrounds, and a future package release can visibly alter layouts without any JavaScript compile error.
Docs4/5The README is exceptionally readable for a reset: it labels opinions, prints the exact CSS for core defaults and every optional file, explains its relationship to normalize.css and reset.css, lists browser targets, and shows link, CSS import, JavaScript import, and webpack setups. The point lost is significant: main-branch docs include changes not present in npm 13.0.0, the old webpack tilde syntax is dated, and the Internet Explorer 9 claim is incompatible with the widespread :where() selectors in the published stylesheet.
Maintenance3/5The repository is not abandoned: four substantive changes landed in March 2026, including responsive assets and reduced-motion updates, and a security policy was added in 2024. However, npm 13.0.0 was published in September 2021, so consumers have not received those main-branch fixes as a release. Twenty-two open issues and pull requests include dialog scrolling, reduced-motion harm, flex list behavior, iframe backgrounds, stale rules, and requests asking whether the project is maintained.
Ecosystem5/5The package recorded 3,147,520 downloads in the measured week and the repository has 5,298 stars and 301 forks. It is developed alongside normalize.css under CSSTools, works through plain CSS in any framework, and offers modular files for common foundation concerns. Because it has no JavaScript runtime and no dependency graph, adoption is straightforward across static sites, bundlers, and design systems, though global CSS means interoperability must still be tested rather than assumed.

Use it if

  • You want a documented global baseline that goes further than standards-only normalization
  • Your design system benefits from zero-specificity element defaults that component styles can override cheaply
  • You want to opt into separate form, asset, typography, or reduced-motion foundations rather than one monolithic reset
  • You support modern browsers and can review every opinionated global rule against your existing UI
Skip it if

Setup reality

Install sanitize.css and import the root stylesheet once near the start of your global CSS or application entry. There are no JavaScript dependencies, peer packages, native builds, credentials, or runtime configuration. It is CSS, so a JavaScript import requires bundler CSS handling; a plain browser can use a link element instead. Pin CDN URLs to a version rather than copying the README's floating endpoints into production. The root import does not include forms.css, assets.css, typography.css, reduce-motion.css, system-ui.css, or ui-monospace.css. Add only the optional files whose behavior you have reviewed. forms.css makes controls transparent, inherits typography, adds borders and padding, and replaces the select arrow with a data-URI SVG. assets.css caps several replaced and form elements at 100 percent width. typography.css chooses long system font stacks. reduce-motion.css applies !important timing overrides to every element and pseudo-element when the user asks for reduced motion; that is broad enough to break components that depend on transitionend or animationend, and the repository has an open concern about harmful cases. The published 13.0.0 root file is 7,381 bytes before transfer compression and contains global selectors. Most rules use :where() to carry zero specificity, but universal rules for box-sizing and background-repeat do not, and typography.css uses ordinary html and element selectors. Import order still matters when specificity ties. A CSS layer can make the baseline's cascade position explicit, but confirm your build tool preserves layer semantics. Audit screenshots, focus behavior, printed output, native controls, rich-text content, and navigation lists. In particular, the inserted zero-width pseudo-element on nav list items has an open flexbox complaint. The documentation on the main branch includes 2026 changes that are absent from npm 13.0.0, so inspect the installed files rather than assuming the website always describes the published artifact exactly.

Patterns

Load the core foundation from JavaScriptimport-core-styles

import 'sanitize.css';
import './app.css';

Import sanitize.css before application styles so equal-specificity rules in app.css come later. Your bundler must be configured to process CSS imports.

Load the foundation from global CSSimport-from-css

@import 'sanitize.css';

/* Project tokens and components follow. */
@import './tokens.css';
@import './components.css';

Package import resolution depends on the CSS build tool. The README's webpack tilde form is unnecessary in many current toolchains.

Use a version-pinned browser stylesheetload-pinned-cdn

<link rel="stylesheet" href="https://unpkg.com/sanitize.css@13.0.0/sanitize.css">

A pinned URL prevents an upstream release from changing every page unexpectedly. A CDN remains an availability and policy dependency.

Opt into the separate forms baselinenormalize-form-controls

import 'sanitize.css';
import 'sanitize.css/forms.css';

forms.css changes borders, padding, backgrounds, inherited fonts, range and color inputs, and select appearance. It is not included by the root import.

Keep common assets within their containerconstrain-page-assets

import 'sanitize.css';
import 'sanitize.css/assets.css';

In npm 13.0.0 this affects iframe, img, input, video, select, and textarea. Newer main-branch documentation may describe a different selector list.

Apply the optional system font stacksuse-system-typography

import 'sanitize.css';
import 'sanitize.css/typography.css';

typography.css uses ordinary html, code, kbd, samp, and pre selectors rather than zero-specificity :where(), so overrides need normal cascade planning.

Load the reduced-motion policyrespect-reduced-motion

import 'sanitize.css/reduce-motion.css';

Version 13 applies !important duration and delay overrides globally. Test components that rely on animation or transition completion events before enabling it.

Put sanitize.css in a low-priority layerplace-in-cascade-layer

@layer reset, tokens, components, utilities;

@import 'sanitize.css' layer(reset);
@import './tokens.css' layer(tokens);
@import './components.css' layer(components);

Layer ordering can make the baseline predictable even when selector specificity differs. Verify that your target browsers and CSS processor preserve import layers.

Replace an opinionated root defaultoverride-root-defaults

:root {
  line-height: 1.4;
  overflow-wrap: normal;
  tab-size: 2;
}

The core root declarations use :where(:root), which has zero specificity, so a later ordinary :root rule overrides them cleanly.

Restore list styling inside navigationrestore-navigation-markers

nav ul.docs-tree {
  list-style: disc;
  padding-inline-start: 1.5rem;
}

nav ul.docs-tree > li::before {
  content: none;
  float: none;
}

The core sheet removes nav list markers and inserts a zero-width pseudo-element for Safari semantics. Override both when a navigation tree needs visible bullets or flex-safe children.

Opt a component back into repeating backgroundsrestore-repeating-background

.checkerboard {
  background-image: var(--checker-pattern);
  background-repeat: repeat;
}

The universal core rule sets background-repeat: no-repeat on every element and pseudo-element, so repeating patterns must opt back in.

Inspect the exact CSS shipped by npmaudit-installed-version

npm ls sanitize.css
node -e "console.log(require.resolve('sanitize.css/sanitize.css'))"

The website follows repository main, while npm 13.0.0 predates 2026 source changes. Review the resolved file when a documented rule seems absent.

Alternatives

PackageRegistryPick it when
normalize.cssnpmYou want browser bug corrections that stay closer to CSS specifications and add fewer opinions
modern-normalizenpmYou target modern browsers and want a compact maintained normalization baseline
ressnpmYou want an opinionated reset with broad element coverage and a different set of defaults
destyle.cssnpmYou want a stronger blank-slate reset and intend to restyle nearly every element yourself