ECSS is a set of recommendations for better CSS. It comes with a list of axioms, a list of examples, a Stylelint config for your editor, and a scaffolding library. Check it out here.
It makes the following claim:
No more naming everything, no more technological dependencies. Only intentional, consistent, simple, expressive, predictable, sustainable CSS.
Below are some of the authoring rules that resonate best with me.
All component selectors must start with its filename.
Or as I like to do, start with the component name. For instance my <Button />
components have an outer CSS class of Button
.
/* ✅ Do */
/* card.css */
.card {
...
}
/* ❌ Don't */
/* card.css */
.small-card {
...
}
Design tokens should be used for most numerical values.
Numerical values should only be used for exceptional alignments. These should be commented to communicate the intent. Even then, why not create a bespoke property meaningfully named?
/* ✅ Do */
.card {
padding: var(--small-spacing);
}
/* ❌ Don't */
.card {
padding: 20px;
}
All class entities besides components must be prefixed.
We propose this nomenclature of prefixes:
as-
for generic graphical form.of-
for a group of elements.is-
for interactive state of the system.on-
for user interaction.in-
for internal concept.with-
for functional rule.from-\*-to-
for adaptive patterns.
/* ✅ Do */
.card.as-circle {
width: 20px;
}
.card .in-ctn {
display: grid;
}
/* ❌ Don't */
.card.circle {
width: 20px;
}
.card .ctn {
display: grid;
}
Components cannot exert outside influence.
Components are made to fit into “holes”. These holes are managed by another component or a higher-level utility (e.g. a grid or carousel). No component in this sense should incorporate margins. These are applied as a rhythm by a parent. Thus, the components are versatile and reusable in various contexts.
/* ✅ Do */
.as-pile > * + * {
margin-top: 20px;
}
/* ❌ Don't */
.card {
margin-top: 20px;
}
These patterns can be used for vanilla CSS, CSS modules, and CSS in JS approaches.
Read all the rules at ecss.info.