RSS Amplifier

Peiwen Lu · Mar 6, 2026

Blanksheet: A Principled CSS Reset

0
Sign in to vote or save

peiwen.lu

(Posts)
Mar 6, 2026

[ CSS , Reset]

show, don't tell https://github.com/P233/blanksheet

Blanksheet is a CSS reset built on five explicit principles; every rule traces back to one. Five principles classify every UA default on every element into exactly one category: reset it, keep it, skip it, set it, or normalize it. No property falls through the cracks, and no two principles compete for the same decision. The result is a reset you can audit against its own rules, and argue with on precise terms.

The five principles

Principle 1: Eliminate implicit layout

Zero every non-zero spatial property (margin, padding, vertical-align) so that all spacing in the final layout is fully under your control.

Media elements (<img>, <svg>, <video>, etc.) get vertical-align: bottom rather than display: block to close the baseline gap. Both work, but display: block breaks inline <svg> icons inside buttons and links.

Principle 2: Preserve text semantics

The test is scoped to a specific property on a specific element: does it carry semantic meaning that would be lost if reset? Remove font-weight: bold from <strong> and it looks identical to plain text. That’s semantic, so it stays. Same logic keeps font-style: italic on <em>, text-decoration on <a> and <del>, font-family: monospace on <code>, background-color on <mark>, and so on.

Heading font-size is the key exclusion. The semantic hierarchy lives in the HTML tag (<h1> through <h6>), not in the UA’s 2em0.67em scale. Every project defines its own type scale, so the UA value is universally replaced (→ P3). Heading font-weight: bold, by contrast, visually signals importance and stays.

Principle 3: Skip what developers always override

If no realistic production scenario keeps the UA default, resetting it is dead code; developers will override the reset anyway. Blanksheet simply skips it.

Property-level. Heading font-size, border on form controls / <fieldset> / <hr> / <iframe> / <dialog>, background on form controls and <dialog>, ::backdrop background. None of these UA values survive into production.

Element-level. <meter>, <progress>, and specialized inputs (date, time, datetime-local, month, week, color, range). In practice, projects always replace these entirely with custom design systems. Resetting properties on elements that won’t ship in their native form is dead code at a larger scale.

Worth noting: border is classified as a visual property (P3, not P1). border-width does occupy space, but developers override border for visual reasons, not spatial ones. Treating it as spatial would blur P1’s scope without meaningful benefit.

Principle 4: Apply real-world universal defaults

Conventions so broadly shared that omitting them creates universal boilerplate. The bar is high: must be correct for the vast majority of production projects, not merely convenient.

  • box-sizing: border-box via *, *::before, *::after
  • list-style: none on <ul>, <ol>, <menu>
  • border-collapse: collapse on <table>
  • font: inherit; color: inherit on form controls, fixing the UA inheritance break
  • appearance: textfield on <input type="number"> (spinners virtually always replaced)
  • list-style: none on <summary> (disclosure triangle virtually always replaced)

P4 actively sets a value to a convention that real-world projects have collectively settled on.

Principle 5: Normalize cross-browser inconsistencies

P5 is the catch-all for browser disagreements, applied only when browsers diverge on rendering the same element.

  • <sub> / <sup>: normalize positioning to prevent line-height disruption across engines
  • [type="search"]: WebKit’s non-standard appearance normalized to textfield
  • button::-moz-focus-inner: Firefox’s extra inner padding / border removed
  • text-size-adjust: 100%: prevents mobile Safari text inflation
  • ::placeholder opacity: Firefox’s reduced opacity normalized to 1
  • :-moz-ui-invalid: Firefox’s red box-shadow on invalid elements removed

P4 and P5 differ in scope: P4 applies when all browsers agree on a default that developers universally replace. P5 applies when browsers disagree on how to render the same element.

Where principles meet

One element, three principles

<h1>: margin is implicit layout, P1 resets it. font-weight: bold conveys importance, P2 preserves it. font-size: 2em is universally overridden, P3 skips it.

One declaration, two reasons

[type="search"] and [type="number"] share appearance: textfield for different reasons. [type="search"] is P5: WebKit’s non-standard appearance. [type="number"] is P4: all browsers agree on spinners, but they’re virtually always replaced. The principle system operates at the property-on-element level, not the declaration level.

What Blanksheet never does

No opinions: no cursor: pointer, no font-smoothing, no scroll-behavior: smooth. A reset subtracts UA defaults; it never adds behavior. And no !important — Blanksheet ships inside @layer reset, so any unlayered style wins automatically.

Every line has a reason

The source is annotated with [Principle N] references on every section, so every decision is traceable. If you think a rule doesn’t match its principle, or if you disagree with the principle itself, I’d genuinely love to hear about it. That’s the whole point of making the reasoning explicit.

Read the original on peiwen.lu

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.