One of the most useful tools in FSCSS for cutting down repetitive CSS is the array system. Arrays let you store ordered lists of values and expand them into repeated rules automatically, instead of writing five or six nearly identical blocks by hand.
This post walks through how @arr works, how the loop trigger behaves, and the pattern used in real FSCSS modules like siri-wave.fscss.
Declaring Arrays
Arrays in FSCSS are 1-indexed and string-native. The first item is [1], not [0].
@arr colors[magenta, cyan, green, purple, orange, blue]
@arr delays[0.1s, 0.25s, 0.45s, 0.15s, 0.35s, 0.55s]
@arr indexes[count(6,1)] /* generates 1,2,3,4,5,6 */
count(n, start) is the standard way to generate a numeric index array. You can also declare literal lists of any CSS value type: colors, sizes, times, strings.
Accessing Individual Items
background: @arr.colors[1]; /* magenta */
animation-delay: @arr.delays[3]; /* 0.45s */
The Loop Trigger: Empty Brackets
The core feature is the empty bracket syntax, @arr.name[].
When FSCSS sees @arr.name[] inside a selector that's followed by a block, it expands the rule once for every item in the array.
@arr delays[0.1s, 0.3s, 0.5s]
@arr colors[#ef4444, #f59e0b, #10b981]
@arr indexes[count(3,1)]
.loading-dot:nth-child(@arr.indexes[]) {
animation-delay: @arr.delays[@arr.indexes[]];
background: @arr.colors[@arr.indexes[]];
}
This compiles to:
.loading-dot:nth-child(1) {
animation-delay: 0.1s;
background: #ef4444;
}
.loading-dot:nth-child(2) {
animation-delay: 0.3s;
background: #f59e0b;
}
.loading-dot:nth-child(3) {
animation-delay: 0.5s;
background: #10b981;
}
A Real Example: siri-wave.fscss
Here's the pattern as it's actually used in siri-wave.fscss:
@define siri-blob-colors(st:.blob){`
@arr siri-colors[magenta, cyan, green, purple, orange, blue]
@arr siri-colors-i[count(6,1)]
@siri-blob-variant(@use(st)[email protected][@arr.siri-colors-i[]], @arr.siri-colors[@arr.siri-colors-i[]])
@use(st){
/* Need a block to trigger the loop */
--siri-loop-index: @arr.siri-colors-i[];
}
`}
Breaking down what happens:
- Two parallel arrays are declared: one for values, one for indexes.
- The empty
[]sits inside a selector/argument that's followed by a block. - FSCSS expands the whole statement six times, once per index.
- Each expansion calls
@siri-blob-variantwith the matching color name, producing.blob.magenta,.blob.cyan, and so on.
This index-array-plus-parallel-values pattern is the recommended way to generate multiple variants cleanly, without writing each variant out by hand.
Rules for Reliable Looping
-
@arr.name[]must appear in a selector position followed by a{ }block. A bare reference inside a mixin argument alone won't trigger the loop reliably. - Prefer an explicit index array (
count(n,1)) whenever you need to index into other arrays. - Arrays are expanded entirely at compile time. The output is plain CSS, with no runtime array logic left behind.
Array Methods
| Method | What it does | Example |
|---|---|---|
.length |
Number of items | @arr.colors!.length |
.first / .last
|
First / last item | @arr.colors!.first |
.list |
Comma-separated list | @arr.colors!.list |
.join(sep) |
Join with custom separator | @arr.colors!.join(+) |
.reverse |
Reversed list | @arr.colors!.reverse |
.shuffle |
Random order | @arr.colors!.shuffle |
.indices |
1-based index list | @arr.colors!.indices |
.randint |
One random value for the compile | @arr.colors!.randint |
Short list
The Mental Model
Think of @arr.name[] as "for each item in this array, generate a rule." That's the entire mechanism behind the six colored blobs in siri-wave, generated without writing six almost-identical blocks by hand.
FSCSS isn't just a different syntax for writing CSS. It's growing into an ecosystem of reusable libraries, tools, and resources meant to make modern web development faster and less repetitive.
The siri-wave repo: siri-wave.fscss on GitHub
Top comments (0)