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:
- MDN custom properties
- MDN @property
- MDN var()
- MDN - Using CSS custom properties
- Custom properties in spec
- Smashing Magazine - It's Time To Start Using CSS Custom Properties
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));
}
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;
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.
@property --x;
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);
}