Skip to content

Cascading consistency

Posted April 2018 in #dev

CSS is neither code nor markup. It’s not a query language, a configuration language, or a DSL. Instead, CSS is a style sheet language — a world of its own. Yet we haphazardly import rules from other fields. It’s far from given that our ideas about globals, inheritance, and modularity apply to the world of CSS.

The closest thing to a style sheet is not found in programming but in design. More than anything a style sheet resembles a style guide — a codified design specification. For what is a style guide but a set of design rules, invariants, and exceptions? And in both cases the ultimate goal is design consistency.

Good design is consistent. There are ground rules that apply by default, with extensions and exceptions as required. In other words, cascading inheritance is not a complexity brought by CSS, but an inherent challenge for any design language. Whether expressed in *.css or *.js, whether the cascade is implicit or explicit, inheritance is a fundamental property of good design.

This perspective informs one approach to writing CSS where we embrace cascading over isolation and inheritance over repetition. Instead of expecting consistent application of a written guide to isolated components, we use our limited pool of developer discipline for explicit reliance on global styles.

In this approach, any style that can be global should be global. Local styles should rely on styles defined further up the chain. Whenever possible, prefer unitless values and percentages to absolute measures. Prefer declarative centering to explicit offsets. Prefer intrinsics like currentColor to variables. Prefer em to rem and rem to px. Extend on a base without overrides.