Variables
Jess supports both scoped (Less- and CSS-style) and linear (Sass-style) variables.
Syntax
Jess uses Sass-style declarations and references of variables. The difference is that, in Jess, in the declaration $color, the name of the variable is color, not $color. In basic cases, this is not an important distinction, but it becomes important within expressions or in accessing namespaces.
Examples
$color: #06c; // normal declaration
.box {
color: $color; // normal usage
color: $(color); // same as $color
}
Assignment operators
Jess variables support a few assignment operators, written glued to the variable
name (except :=, which is spaced):
| Operator | Name | Meaning |
|---|---|---|
$foo: value | assign | normal declaration (scoped) |
$foo?: value | default-assignment | assign only if foo is not already defined. This is Jess's equivalent of SCSS !default (which is not Jess). |
$foo := value | nearest-outer (non-shadowing) assign | reassign the nearest enclosing scope that already defines foo (JS-block style), rather than creating a new shadowing local. This is NOT !global — it targets the nearest binding, not the top one. |
There is no variable compound-add operator — write it explicitly:
$foo?: 1; // sets foo to 1 only if it wasn't already defined
$n: $n + 1; // compound-add is spelled out; `+` follows $n's type
$foo := bar; // reassign the nearest enclosing `foo`, do not shadow
$foo := bar reassigns the nearest enclosing binding (not the global one — that
distinguishes it from Sass !global). $!foo: bar (the $!
live-binding form) is the related "assign the live binding"
spelling.
Scoped variables
Like CSS and Less, Jess variables have a value per scope. This is similar to how CSS custom properties work, but the scope is according to the stylesheet, instead of the DOM (as it is with CSS custom properties).
- Jess
- Less
- Sass (unsupported)
.btn {
// In Jess/Less this is fine
color: $color;
$color: #06c;
// In CSS this is also fine
background: var(--background);
--background: white;
}
.btn {
color: @color;
@color: #06c;
background: var(--background);
--background: white;
}
.btn {
color: $color; // Error
$color: #06c;
// ...
}
Live binding
By default a $var reference reads the value the variable had at that point in
the scope. Sometimes you want the live value — the latest value the variable
holds, even if it is reassigned later in the same scope. Jess writes this with the
$! sigil.
Reading $!foo yields the live value:
- Jess
- Sass
.btn {
$color: red;
color: $!color; // live: reflects the latest value
$color: blue; // color resolves to blue
}
.btn {
$color: red;
color: $color; // value is red (read at this point)
$color: blue;
}
You can also assign the live binding — reassign an existing outer variable
rather than shadowing it — with $!foo: value. This is the non-shadowing
counterpart to the := operator:
- JavaScript
- Jess
- Sass
let color = 'red';
{
color = 'blue'; // do not shadow, reassign
}
console.log(color); // blue
$color: red;
.btn {
$!color: blue; // reassign the existing `color`, do not shadow
}
.box {
color: $color; // blue
}
$color: red;
.btn {
$color: blue !global; // Sass's !global
}
.box {
color: $color; // blue
}
Readonly variables
Jess supports readonly (const-style) variables with !.
Prepend readonly variables (const-type vars) with !
!$color: red;
$color: blue; // Error
Private variables
Variables are "public" on a namespace by default. To make a variable private, prepend the variable or key name with _.
$colors: {
_private: unknown;
primary: #06c;
}
.box {
color: $colors.primary;
color: $colors._private; // Error, '_private' not found
}