https://github.com/kingoftac/postcss-plugin-random
A PostCSS plugin for the upcoming CSS random() function.
https://github.com/kingoftac/postcss-plugin-random
css css-random css-random-func css-random-function frontend frontend-web function html plugin postcss postcss-plugin postcss-plugin-random random rust-web ui wasm wasm-bindgen web web-assembly
Last synced: about 2 months ago
JSON representation
A PostCSS plugin for the upcoming CSS random() function.
- Host: GitHub
- URL: https://github.com/kingoftac/postcss-plugin-random
- Owner: KingOfTac
- License: mit
- Created: 2025-11-12T19:09:49.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-11-13T19:49:15.000Z (7 months ago)
- Last Synced: 2025-11-13T21:21:15.924Z (7 months ago)
- Topics: css, css-random, css-random-func, css-random-function, frontend, frontend-web, function, html, plugin, postcss, postcss-plugin, postcss-plugin-random, random, rust-web, ui, wasm, wasm-bindgen, web, web-assembly
- Language: Rust
- Homepage:
- Size: 133 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# postcss-plugin-random
> A PostCSS plugin that implements the CSS `random()` function as per the [CSS Values & Units Level 5 draft](https://drafts.csswg.org/css-values-5/#random). 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](#limitations) below.
## Roadmap
- [x] `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”
- [x] `` 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 `: 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)
- [ ] `` 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 `` (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:
```shell
cargo install wasm-pack
```
The npm dev command will compile the wasm binary and bundle the demo CSS before serving the demo page.
```shell
npm run dev
```
To compile the wasm binary separately:
```shell
wasm-pack build --target nodejs
```