Skip to content

KingOfTac/postcss-plugin-random

Repository files navigation

postcss-plugin-random

A PostCSS plugin that implements the CSS random() function as per the CSS Values & Units Level 5 draft. This plugin lets you generate random values (optionally stepped) directly in your CSS and supports value sharing semantics.

Caution

This is an experimental implementation; some parts of the spec require browser/DOM context and are approximated at build time. See limitations below.

Roadmap

  • random(min, max[, step]) with:
    • Unit/type consistency checks between min, max (and step if present)
    • Uniform selection; step logic with epsilon = step / 1000 and “snap-to-max within epsilon”
  • <random-value-sharing> support (build-time approximation):
    • auto (default): distinct base value per function occurrence
    • --dashed-ident: shared base value for the same ident within a processing run
    • element-shared: shared base value globally within the processing run
    • fixed <number>: deterministic base value in [0,1) (1 is clamped to the next representable value below 1)
    • Property-aware caching keys (approximate "PROPERTY N") to better mimic default sharing behavior
  • Safer scanning (skip comments/strings; robust tokenization)
  • <calc-sum> and percentage resolution (at least partial)
  • Additional edge cases for argument ranges (NaN/Infinity)
  • Add Playwright tests for coverage against the current WebKit implementation
  • Proper demo and docs

Examples

.random-rect {
	width: random(100px, 200px);
	height: random(100px, 200px);
}

.shared-named {
	width: random(--size, 100px, 200px);
	height: random(--size, 100px, 200px); /* same as width */
}

.shared-global {
	width: random(element-shared, 100px, 200px);
	height: random(element-shared, 100px, 200px); /* same across all matches */
}

.fixed {
	width: random(fixed 0.5, 100px, 200px);  /* 150px */
	height: random(fixed 0.5, 100px, 200px); /* 150px */
}

Limitations

  • Property-aware caching keys (the spec's default of "PROPERTY N") are not yet implemented; this plugin currently can't know property names in a pure token stream. We simulate sharing through in-process cache keys (dashed ident/global) during the PostCSS run.
  • We don't evaluate <calc-sum> (e.g. calc() or unit mixing). Such values are left as-is; numeric+unit prefixes are parsed only.
  • NaN / Infinity edge cases are not fully modeled per spec's Argument Ranges; invalid ranges generally cause the original random(...) to be left unchanged.
  • Scanning is naive: we don't skip comments/strings yet; nested functions are handled via basic parentheses counting only.
  • Type consistency is verified via unit strings; more advanced CSS type resolution (percentages, font-relative units) would require layout context.

Dev

install wasm-pack if you haven't already:

cargo install wasm-pack

The npm dev command will compile the wasm binary and bundle the demo CSS before serving the demo page.

npm run dev

To compile the wasm binary separately:

wasm-pack build --target nodejs