Skip to main content

Custom Property

CSS custom property is used to define and re-use variables that participate in the cascade, and to dynamically change their values at runtime.

This page goes over how Stylable handles custom properties, for more details about the language feature itself, checkout the following resources:

syntax

A CSS custom property name must start with the -- prefix.

Get / Set

A custom property can be referenced from a declaration property or within a value var() call:

.a {
/* set */
--x: green;
}
.a .b {
/* get */
color: var(--x);
}
.b {
/* fallback to yellow if property is unset */
color: var(--notSet, yellow);

/* fallback to --x if property is unset */
color: var(--notSet, var(--x));
}
no explicit definition

A custom property can be set and used without an explicit @property definition

Runtime definition

Use @property at-rule to register a configuration for a runtime property:

/* runtime type definition */
@property --x {
syntax: '<color>'; /* type */
inherits: true; /* is taken from cascade */
initial-value: green; /* default when unset */
}

.b {
/* get green from initial value
if --x is unset */
color: var(--x);
}

Build only definition

To define a custom property to be used outside of a stylesheet, without explicitly registering its runtime type or using it as a declaration property or value, you can define the @property at-rule without a body:

@property --x;
removed at build

A property with no configuration body is removed at build-time as it serves no purpose during runtime

Comparison to build vars

Stylable variables (build vars) and CSS custom properties offer different capabilities, and as such serve different use-cases.

Stylable variables exist only in your source code, and get replaced during build. They serve well for calculations that are not supported by native CSS, reducing code repetition, increasing readability and can benefit any static theme or styling without incurring any runtime performance cost.

CSS custom properties on the other hand do incur a very small runtime cost, but offer the ability to override their values during runtime, allowing for native CSS dynamic styling.

Import and Export

An exported custom-property can be imported into another stylesheet with the @st-import at-rule.

@st-import [--x] from "./common.st.css";

.a {
/* get --x value */
color: var(--x);
}

.b {
/* set/override --x value */
--x: gold;

/* get override 'gold' value */
background-color: var(--x); /* gold */
}

Runtime

A custom property can be used dynamically in JavaScript.

comp.st.css
@property --x;
comp.jsx
import { vars } from './comp.st.css';

/* inline style set property value */
<div style={{ [vars.x]: 'pink' }} />;

Namespace

Stylable automatically namespace any CSS custom property name according to the stylesheet it is defined in.

@property --x {
syntax: '<color>';
inherits: true;
initial-value: green;
}
.a {
--x: var(--x);
}

/* OUTPUT */
@property --NAMESPACE-x {
syntax: '<color>';
inherits: true;
initial-value: green;
}
.NAMESPACE__a {
--NAMESPACE-x: var(--NAMESPACE-x);
}

Disable namespace

In cases where the default namespace behavior is not wanted, st-global can be used to mark a custom property definition as global.

@property st-global(--x) {
syntax: '<color>';
inherits: true;
initial-value: green;
}

.a {
--x: var(--x);
}

/* OUTPUT */
@property --x {
syntax: '<color>';
inherits: true;
initial-value: green;
}

.NAMESPACE__a {
--x: var(--x);
}