Open this example in the FSCSS IDE: Run it live
It is completely normal if this looks strange at first. FSCSS uses a small “template + loop” model so you can describe a pattern once and expand it into standard CSS.
@arr classes[ count(1000, 1) ] .item-@arr.classes[] { margin: @arr.classes[]px; } Three lines in. About a thousand rules out.
Line 1 — Build a list of numbers
@arr classes[ count(1000, 1) ] | Piece | Meaning |
|---|---|
@arr classes[...] | Declare an array named classes |
count(1000, 1) | Count from 1 up to 1000 |
Behind the scenes the list is effectively:
[1, 2, 3, …, 999, 1000] Arrays in FSCSS are 1-indexed and string-native. count(n, start) is the built-in that fills them without typing every value.
Line 2 — Loop the selector
.item-@arr.classes[] { | Piece | Meaning |
|---|---|
.item- | Fixed class prefix |
@arr.classes[] | Auto-loop: expand this rule once per item |
Empty [] means “for each entry in the array.” The compiler stamps out:
.item-1 { ... } .item-2 { ... } .item-3 { ... } /* … */ .item-1000 { ... } Line 3 — Reuse the same index in the value
margin: @arr.classes[]px; } Inside the same loop, @arr.classes[] is the current item. For .item-1 that becomes 1px; for .item-500, 500px.
So each expanded rule stays consistent: class number and property value come from the same step of the array.
Final CSS (abbreviated)
.item-1 { margin: 1px; } .item-2 { margin: 2px; } .item-3 { margin: 3px; } /* … hundreds of rules later … */ .item-1000 { margin: 1000px; } You are not shipping FSCSS to the browser forever. You either:
- prototype in the IDE / runtime, or
- compile with the CLI:
fscss input.fscss output.cssand ship plain CSS.
Real-world tweaks
Fixed step sizes (e.g. spacing scale):
@arr steps[4, 8, 12, 16, 24, 32, 48, 64] .gap-@arr.steps[] { gap: @arr.steps[]px; } Fewer utilities, still generated:
@arr n[count(32, 1)] .m-@arr.n[] { margin: calc(@arr.n[] * 0.25rem); } Pair with %n() multiplexing when several properties share one value:
@arr n[count(8, 1)] .box-@arr.n[] { %2(width, height[: calc(@arr.n[] * 8px);]) } Why this pattern exists
Utility sheets and design tokens often need many parallel rules (margins, radii, z-index layers, animation delays). Hand-writing them is slow and error-prone. A short FSCSS template:
- Defines the data (
@arr/count) - Loops selectors and values together (
[]) - Compiles to boring, predictable CSS
Same idea powers denser modules (charts, staggered delays, icon packs)—the 1,000-class demo is just the clearest “aha.”
Try it
- Open the IDE link above.
- Press Ctrl+Enter (Cmd on Mac) to compile.
- Scroll the CSS panel — you should see
.item-1through.item-1000.
Then change 1000 to 12 or replace count(...) with a hand-picked list and compile again.
![Why Object.keys(user) Returns string[], Not (keyof User)[]: TypeScript Means It](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2q4w48b9bzs43tynyhsf.png)
