Skip to main content

Conditionals and iteration

Similar to JavaScript, reserves a few $ keywords to use for conditional evaluation and recursive iterations (loops).

$if, $else, $else if

These conditionals evaluate pretty much how you would expect. Note that even though control flow names start with $, they are not expressions, and expressions after them must be started with $.

Examples

1. Theme Switching

$theme: "dark";

$if ($theme = "dark") {
body { background: #111; color: #eee; }
} $else {
body { background: #fff; color: #222; }
}

2. Feature Flags for Styles

@-use 'https://example.com/my-flags.json';

.card {
border-radius: 8px;
$if ($my-flags.enableFancyShadows) {
box-shadow: 0 8px 32px #0002;
}
}

3. Seasonal settings

// An NPM module that gives us a season method
@-use "some-date-fns" as date;

$season: $date.getSeason($date.now()); // e.g., returns "spring", "summer", etc.

$if ($season = "spring") {
body { background: #d8f5d1; }
} $else if ($season = "summer") {
body { background: #ffe066; }
} $else if ($season = "autumn") {
body { background: #ffbe76; }
} $else {
// winter (or whatever else you want to handle)
body { background: #a5b8e7; }
}

4. Dumb Easter Eggs (Because You Can)

$shouldTroll: false;

$if ($shouldTroll) {
h1 { font-family: "Comic Sans MS"; color: hotpink; }
}

Block scoping

Unlike rulesets and at-rules, conditionals and iteration blocks do not create a new scope. That means that rules declared in a conditional or iteration block are automatically merged with their containing block.

.box {
$my-color: red;
$if (true) {
$my-color: blue;
}
color: $my-color; // blue
}

$for

$for is Jess's source-dependent iteration protocol, in the spirit of JavaScript for…of: the source determines the entry shape, and the header says which parts of that entry the loop names. Lists and ranges supply values in source order; collections can supply key/value entries. This is Jess syntax, not a spelling of Less each().

$sections: header, sidebar, footer;

$for ($section, $i of $sections) {
.box-${section} {
padding-left: $($i * 20px);
}
}

You can also iterate over a range of numbers:

$for ($i of 1 to 3) {
.box-${i} {
value: $i;
}
}

A range is inclusive of the start and end values. To exclude the end value, you can use this familiar syntax from other programming languages:

$for ($i of 1 to <3) {
.box-${i} {
value: $i;
}
}

You can also destructure a collection entry:

$collection: { header: red; footer: blue; };

$for ([$key, $value] of $collection) {
.box-${key} {
value: $value;
}
}
info

In the first example, i is the key of sections. Because sections is a list, that key is its 1-based source-order position.

The single-name form names the entry value. The comma form may also name the source key and loop counter. For a list, the key and counter have the same source-order position; for a Jess collection, the key is the declaration name. Bracket binding is key/value destructuring for collection entries, so [$key, $value] names the collection key first and its value second. The canonical header shapes are $for ($item of …), $for ($item, $key, $counter of …), and $for ([$key, $value] of …).