A best-practices CSS foundation

  • By CSS Tools
  • Last update: Jan 8, 2023
  • Comments: 16

sanitize.css sanitize

sanitize.css is a CSS library that provides consistent, cross-browser default styling of HTML elements alongside useful defaults.

sanitize.css is developed alongside normalize.css, which means every normalization is included, and every normalization and opinion are clearly marked and documented.

sanitize.css wraps styles in zero-specificity selectors using :where().

Usage

">
<link href="https://cdn.skypack.dev/sanitize.css" rel="stylesheet" />

Learn more about sanitize.css.

Forms CSS

A separate stylesheet that normalizes form controls without side effects.

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

Learn more about forms.css.

Assets CSS

A separate stylesheet that applies a comfortable measure to plain documents.

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

Learn more about assets.css.

Typography CSS

A separate stylesheet that normalizes typography using system interface fonts.

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

Learn more about typography.css.

Reduce Motion CSS

A separate stylesheet for restricting motion when the user has requested this at system level.

">
<link href="https://unpkg.com/sanitize.css/reduce-motion.css" rel="stylesheet" />

Learn more about reduce-motion.css.

System-UI

A separate stylesheet that adds support for using system-ui in Firefox.

">
<link href="https://unpkg.com/sanitize.css/system-ui.css" rel="stylesheet" />

UI-Monospace

A separate stylesheet that adds support for using ui-monospace in Chrome, Edge, and Firefox.

">
<link href="https://unpkg.com/sanitize.css/ui-monospace.css" rel="stylesheet" />

Install

npm install sanitize.css --save

Webpack Usage

Import sanitize.css in CSS:

@import '~sanitize.css';
@import '~sanitize.css/forms.css';
@import '~sanitize.css/typography.css';

Alternatively, import sanitize.css in JS:

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

In webpack.config.js, be sure to use the appropriate loaders:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ]
      }
    ]
  }
}

Download

See https://csstools.github.io/sanitize.css/latest/sanitize.css

What does it do?

  • Normalizes styles for a wide range of elements.
  • Corrects bugs and common browser inconsistencies.
  • Provides common, useful defaults.
  • Explains what code does using detailed comments.

Browser support

  • Chrome (last 2)
  • Edge (last 2)
  • Firefox (last 2)
  • Firefox ESR
  • Opera (last 2)
  • Safari (last 2)
  • iOS Safari (last 2)
  • Internet Explorer 9+

Differences

normalize.css and sanitize.css correct browser bugs while carefully testing and documenting changes. normalize.css styles adhere to css specifications. sanitize.css styles adhere to common developer expectations and preferences. reset.css unstyles all elements. Both sanitize.css and normalize.css are maintained in sync.

Features

Box sizing defaults to border-box
*, ::before, ::after {
  box-sizing: border-box;
}
Backgrounds do not repeat by default
*, ::before, ::after {
  background-repeat: no-repeat;
}
Pseudo-elements inherit text decoration and vertical alignment
::before,
::after {
  text-decoration: inherit;
  vertical-align: inherit;
}
Cursors only change to hint non-obvious interfaces
html {
  cursor: default;
}
Text has a comfortable line height in all browsers
html {
  line-height: 1.5;
}
Tabs appear the same on the web as in a typical editor
html {
  tab-size: 4;
}
Words break to prevent overflow
html {
  word-break: break-all;
}
Documents do not use a margin for outer padding
body {
  margin: 0;
}
Navigation lists do not include a marker style
nav ol, nav ul {
  list-style: none;
  padding: 0;
}
Media elements align to the text center of other content
audio, canvas, iframe, img, svg, video {
  vertical-align: middle;
}
SVGs fallback to the current text color
svg:not([fill]) {
  fill: currentColor;
}
Tables do not include additional border spacing
table {
  border-collapse: collapse;
}
Textareas only resize vertically by default
textarea {
  resize: vertical;
}
Single taps are dispatched immediately on clickable elements
a, area, button, input, label, select, summary, textarea, [tabindex] {
  -ms-touch-action: manipulation;
  touch-action: manipulation;
}
ARIA roles include visual cursor hints
[aria-busy="true"] {
  cursor: progress;
}

[aria-controls] {
  cursor: pointer;
}

[aria-disabled="true"], [disabled] {
  cursor: default;
}
Visually hidden content remains accessible
[aria-hidden="false"][hidden] {
  display: initial;
}

[aria-hidden="false"][hidden]:not(:focus) {
  clip: rect(0, 0, 0, 0);
  position: absolute;
}

Forms

sanitize.css includes a separate stylesheet for normalizing forms using minimal, standards-like styling.

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

Forms Features

Form controls appear visually consistent and restyle consistently
button, input, select, textarea {
  background-color: transparent;
  border: 1px solid WindowFrame;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  padding: 0.25em 0.375em;
}

[type="color"],
[type="range"] {
  border-width: 0;
  padding: 0;
}
Expandable select controls appear visually consistent
select {
  -moz-appearance: none;
  -webkit-appearance: none;
  background: no-repeat right center / 1em;
  border-radius: 0;
  padding-right: 1em;
}

select:not([multiple]):not([size]) {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='4'%3E%3Cpath d='M4 0h6L7 4'/%3E%3C/svg%3E");
}

::-ms-expand {
  display: none;
}
Placeholders appear visually consistent in Internet Explorer
:-ms-input-placeholder {
  color: rgba(0, 0, 0, 0.54);
}

Assets

sanitize.css includes a separate stylesheet for normalizing restricting the size of assets in all browsers.

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

Assets Features

Assets use a comfortable measure in all browsers
iframe,
img,
input,
select,
textarea {
  height: auto;
  max-width: 100%;
}

Typography

sanitize.css includes a separate stylesheet for normalizing typography using system interface fonts.

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

Typography Features

Typography uses the default system font
html {
  font-family:
    system-ui,
    /* macOS 10.11-10.12 */ -apple-system,
    /* Windows 6+ */ Segoe UI,
    /* Android 4+ */ Roboto,
    /* Ubuntu 10.10+ */ Ubuntu,
    /* Gnome 3+ */ Cantarell,
    /* KDE Plasma 5+ */ Noto Sans,
    /* fallback */ sans-serif,
    /* macOS emoji */ "Apple Color Emoji",
    /* Windows emoji */ "Segoe UI Emoji",
    /* Windows emoji */ "Segoe UI Symbol",
    /* Linux emoji */ "Noto Color Emoji";
}
Pre-formatted and code-formatted text uses the monospace system font
code, kbd, pre, samp {
  font-family:
    /* macOS 10.10+ */ Menlo,
    /* Windows 6+ */ Consolas,
    /* Android 4+ */ Roboto Mono,
    /* Ubuntu 10.10+ */ Ubuntu Monospace,
    /* KDE Plasma 5+ */ Noto Mono,
    /* KDE Plasma 4+ */ Oxygen Mono,
    /* Linux/OpenOffice fallback */ Liberation Mono,
    /* fallback */ monospace;
}

Reduce Motion

sanitize.css includes a separate stylesheet for restricting motion when the user has requested this at a system level.

">
<link href="https://unpkg.com/sanitize.css" rel="stylesheet" />
<link href="https://unpkg.com/sanitize.css/reduce-motion.css" rel="stylesheet" />

Reduce Motion Features

Animations, scrolling effects, and transitions are reduced in all browsers
@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-delay: 0s !important;
    transition-duration: 0s !important;
  }
}

Contributing

Please read the contribution guidelines in order to make the contribution process easy and effective for everyone involved.

Acknowledgements

sanitize.css is a project by Jonathan Neal, built upon normalize.css, a project by Jonathan Neal, co-created with Nicolas Gallagher.

Github

https://github.com/csstools/sanitize.css

Comments(16)

  • 1

    Set background on body instead of html?

    Setting a background color on html instead of on body may confuse people as it will make the latter "shrink" vertically--as this demo shows. May be better/safer to style body.

  • 2

    Add Stylus and LESS?

    How would feel about adding Stylus and LESS versions of sanitize.scss?

    I can make a PR with the current version of the SCSS file converted into those preprocessors if you want.

  • 3

    (Suggestion) word-break: break-all

    word-break: break-all and overflow-wrap: break-word seem to only be suggested across internet as a solution to non-wrapping long words/URLs, which easily break flexible layouts.

    ... but I couldn't find any drawbacks on having this as default across the site. It doesn't sound like it would break anything (except, well, words) so what do you think about adding it to sanitize.css on html?

  • 4

    Custom text selection color causes text selection not to be visible in FireFox when in High-Contrast mode

    When text is selected by the user, a background highlight is shown to indicate the range of text that is selected. For users of the FireFox browser on Windows machines running High-Contrast mode the text selection highlight is invisible when custom colors are used. For accessibility purposes, it is best practice to not overwrite text selection colors.

    Please consider removing the following. ::-moz-selection { background-color:#b3d4fc; color:#000; text-shadow:none }

    ::selection { background-color:#b3d4fc; color:#000; text-shadow:none }

  • 5

    iOS Safari radio inputs

    All radio input styles are being removed in iOS Safari but not other browsers. Is this intended behavior? They were easy enough to add back in, but it seemed like the goal was to keep the default OS/browser radio styles intact - I've only seen this not be the case in iOS Safari.

  • 6

    why can not use v2.1.0 with bower?

    sanitize.css is published v2.1.0 for npm but not for bower. Why is the version of the bower package supplied as the older version? I wish the bower package is published as v2.1.0.

  • 7

    Fixed package.json exporting for npm-css

    This should enable consumption via npm-css (and mostly likely parcelify).

    Also added npm scripts so all that is required to build is:

    $ git clone https://github.com/jonathantneal/sanitize.css
    $ cd sanitize.css
    $ npm install
    # Make modifications
    $ npm start
    # Newly built css file awaits
    

    Come to think of it, you might not even need to publish a built css file and building it on demand using postinstall scripts. see https://docs.npmjs.com/misc/scripts I'm not sure what best practice is, as I'm new to modules that need build steps but I'll let you know once I know more.

    Closes https://github.com/jonathantneal/sanitize.css/issues/1

  • 8

    What's with the page.css padding?

    Really want img { max-width: 100% } for every site I ever make, but the html padding in page.css is pretty awkward.

    https://github.com/csstools/sanitize.css/blob/5bd695fdc7be25221c542810a72c174a33d6fb00/page.css#L5-L13

  • 9

    Possible Addtion: @media(prefers-reduced-motion: reduce)

    Hello, I'm comparing css normalizers, and sanitize.css seems to be pretty ideal. However, there is a part of this one which seems like a good idea:

    @media(prefers-reduced-motion: reduce) {
      *,
      *::before,
      *::after {
        transition: none !important;
        animation: none !important;
        scroll-behavior: auto !important;
      }
    }
    

    Perhaps it's worth adding to this?

  • 10

    Perhaps create a test directory with HTML and PhantomCSS tests

    I know there is gh-pages, although I didn't know this until I read the previous issues about HTML tests. So test HTML could be made more prominent for people wanting to contribute or test Sanitize.css out.

    Perhaps a "tests" directory with specific tests for each case would be useful.

    Also, the use of PhantomCSS for visual regression testing could be really useful when testing on updates. Could possibly even automate the entire process and simply run it from "" in the package.json.

  • 11

    * { background-color:inherit; } is a major cause of pain

    @jonathantneal * { background-color: inherit; } is a major cause of pain for us.

    Especially in large projects which import components from external projects (read: enterprise scale apps and website).

    For example, global components like header, footer, login forms are breaking because of that: for example, transparent elements in a global component, assume undesired background colors from their container element in an app which requires that component.

    This has been a major cause of pain for us since we started using sanitize.css, because there is no way to reverse this rule - you'd have to manually add over-riding rules for each HTML element you want to fix - even though the correct background rules are already present in their respective components' stylesheets.

    Please consider dropping it, because otherwise we would be forced to drop using sanitize.css, which we favor due to it being great project with a modern approach.

    Thanks, Tom Alon Wix.com

  • 12

    Make images more responsive

    More info can be found here: https://www.zachleat.com/web/fluid-images/

    Relates to #170 but in this case it also avoids multi-weight selectors by using :where().

  • 13

    Update README.md

    README.md information is out of date and needs to be updated

    Planned Changes

    1. Deletion of the phrase "IE support"

    In v13, :where is used, and :where is not IE-compatible, so the phrase "IE-compatible" should be removed.

    refer: https://caniuse.com/?search=where

    2. Update on Area Features

    The information in part Features is out of date and needs to be updated. Since I don't know what the overall changes are, I will try to fix the selectors of existing rules and those that have already been removed.

    e.g.

    html { β†’ :where(:root)

    a, area, button, input, label, select, summary, textarea, [tabindex] {
      -ms-touch-action: manipulation;
      touch-action: manipulation;
    }
    

    ↓

    delete

  • 14

    Is this project alive/maintained?

    It seems like latest activities on this project was more than a year ago. Is this project not maintained anymore? What do you recommend we use instead if so?

  • 15

    Add svg to assets.css

    Would you be interested in adding svg to the list of elements in assets.css? Had to do that for a project to fix scaling issues, so figured I'd mention it here. Thanks!

  • 16

    fix(#233): made voiceover fix smaller

    Fixes #233 without breaking voiceover

    A fix mostly inspired by https://github.com/twbs/bootstrap/blob/1df098361cac04217d6a464c80e890c4335ecb5c/scss/mixins/_visually-hidden.scss