Skip to main content

Interpolation

Jess has two interpolation forms:

  • $(...) for full Expression interpolation.
  • $[key] for identifier-style interpolation (Reference with role: 'ident').
    • Variable keys serialize as bare identifiers: $[theme]
    • Property lookup keys serialize as quoted literals: $['--custom-color']

Use $[key] when the interpolation input is a single reference. Use $(...) when you need an actual expression.

Jess also has explicit selector capture:

  • *[...] stores a selector or selector list as a selector-valued variable.

In selector contexts, that single reference may still resolve to a non-identifier selector fragment at runtime.

Quick guide: which form to use?

  • Selector/property/mixin names: use $[ident]
  • Selector-valued variables: use *[...]
  • Strings and custom property values: use $[ident] or $(...)
  • Normal values: use direct references like $var unless you need expression behavior

Selector capture

Use *[...] when the value itself should stay a selector, not just text output.

$target: *[.notice, .warning];

This differs from normal interpolation:

  • $(...) interpolates an expression into output.
  • *[...] captures parsed selector syntax so selector-aware features can use it later.

Interpolation examples

1. Selectors in style rules

$side: left;
.widget-$[side] {
float: $side;
}

.widget-left {
float: left;
}

2. Property names in declarations

$radius: top-right;
.card {
border-$[radius]-radius: 12px;
}

.card {
border-top-right-radius: 12px;
}

3. Custom property values

$theme: dark;
body {
--theme-mode: $[theme];
--theme-mode-fallback: $($theme);
}

.card {
border-color: rebeccapurple;
box-shadow: 0 0 0 2px $['border-color'];
}

body {
--theme-mode: dark;
--theme-mode-fallback: dark;
}

.card {
border-color: rebeccapurple;
box-shadow: 0 0 0 2px rebeccapurple;
}
info

Note: in normal property values, you can usually just use $theme. In custom property values, use interpolation ($[theme] or $(...)) so intent is explicit. $['border-color'] is different: it looks up another declaration value in scope, not a DOM-level custom property.

4. $extend

$type: *[.notice];
.notice {
color: orange;
}
.danger {
$extend $type;
}

.danger, .notice {
color: orange;
}

5. Plain CSS @imports

$family: "modern";
@import url("fonts/$(family).css");

@import url("fonts/modern.css");

6. Plain CSS function names

$fn: "min";
$s1: 30vw;
$s2: 50vw;
.container {
width: $[fn]( $s1, $s2 );
}

.container {
width: min(30vw, 50vw);
}

7. Less and SCSS source conversion

// Less input
.@{name} { color: red; }
// Jess output shape
.$[name] { color: red; }
// SCSS input (single variable interpolation in selector/property name)
.btn-#{$name} { color: red; }
// Jess output shape
.btn-$[name] { color: red; }

8. Any plain output

$color-name: "red";
.container {
color: ~"$[color-name]";
}

.container {
color: red;
}

TL;DR

  1. Use $() for dynamic bits—selectors, property names, and anything clever you want in output.
  2. Use *[] when the variable itself should hold a selector or selector list.
  3. Don't wrap variables for no reason; use direct variables unless you need interpolation.
  4. Never interpolate numbers if you want to do math with them.
  5. Escape strings with ~"" for clarity when you want to drop quotes from a string.

Jess is designed to be simple and clear.