Base CSS endorsing semantic HTML and design token usage
Browsing through the issues of CSS Remedy, I came across an important observation by Jen Simmons:
Why don’t people use
<fieldset>
far more — instead of divs in their forms?Perhaps it’s because fieldset comes with ugly default styling.
This made me question common HTML rendering suggestions. Each design is different, so there isn’t a single set of sensible defaults for every website.
Style normalization is crucial for a consistent user experience among browsers. With the emergence of various design systems, however, CSS normalizers and resets should coexist and complement each other.
Catering to the needs of token-based theming systems, this project was born.
-
Install the library and a normalizer with your package manager (or use a CDN):
npm install css-homogenizer modern-normalize
Using either modern-normalize or @csstools/normalize.css is optional but recommended to fix common browser inconsistencies.
-
Include the following styles in the order below, before any custom CSS:
import "modern-normalize/modern-normalize.css"; import "css-homogenizer/reset.css"; // or "css-homogenizer/reset-scoped.css" import "css-homogenizer/base.css";
You may adopt each stylesheet one by one.
Please refer to your framework’s guidelines for importing CSS files at the top level. Plain
<link>
tags may also be used, but be aware of the performance costs.
Nullifies spacings, borders and several typography-related settings.
- Line heights are matched up with font sizes.
- Heading (
h1
–h6
),th
andaddress
elements inherit their font properties and text alignment from parents. - List (
ul
,ol
,menu
) anda
elements are unstyled to promote proper HTML semantics over misleading visuals. - Form controls are unstyled to cater for overrides.
- Placeholders have
opacity: 1
set for consistency between browsers. - Tables inherit their
border-color
for consistency between browsers.
Obsolete and deprecated HTML elements are ignored, as their usage is strongly discouraged.
A scoped variant of the reset, targeting classes instead of element types.
- Classes are prefixed by
_
to avoid collisions with other selectors. E.g.._p
contains declarations applicable top
elements. - Rules for
html
andbody
elements are omitted.
When using a compiler like Babel, the underlying JSX runtime may be overridden. This allows for auto-injecting scoped reset classes to plain HTML elements on the fly:
<p>Hi</p>
→<p class="_p">Hi</p>
<p className="custom">Hi</p>
→<p class="_p custom">Hi</p>
// babel.config.json
{
"presets": [
[
"@babel/preset-react",
{
"runtime": "automatic",
"importSource": "css-homogenizer/reset-scoped/react",
},
],
],
}
You may attach a scoped reset class to an element on your own, e.g.:
<p class="_p">Hi</p>
To see all the classes available, execute the following snippet:
import { getResetClassName, resetElements } from "css-homogenizer/reset-scoped";
console.log(resetElements.map((element) => getResetClassName(element)));
Helper methods also come in handy when dealing with third-party libraries, e.g.:
import { Listbox } from "@headlessui/react";
import { getResetClassName } from "css-homogenizer/reset-scoped";
function Select(/* … */) {
return (
<Listbox /* … */>
<Listbox.Button className={getResetClassName("button")}>
{/* … */}
</Listbox.Button>
{/* … */}
</Listbox>
);
}
Provides a minimalistic set of generally useful rules. Please refer to the file’s inline comments for further details.
- Latest Chrome
- Latest Firefox
- Latest Safari
This project was mainly inspired by Reset CSS, CSS Remedy and sanitize.css. It wouldn’t have been possible without the long-standing efforts of the authors behind those predecessors.
The logo’s test tube emoji is courtesy of Twemoji and the font in use is Lobster.