Skip to main content

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):

OperatorNameMeaning
$foo: valueassignnormal declaration (scoped)
$foo?: valuedefault-assignmentassign only if foo is not already defined. This is Jess's equivalent of SCSS !default (which is not Jess).
$foo := valuenearest-outer (non-shadowing) assignreassign 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
info

$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).

.btn {
// In Jess/Less this is fine
color: $color;
$color: #06c;
// In CSS this is also fine
background: var(--background);
--background: white;
}

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:

.btn {
$color: red;
color: $!color; // live: reflects the latest value
$color: blue; // color resolves to 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:

let color = 'red';
{
color = 'blue'; // do not shadow, reassign
}
console.log(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
}