Firefox's Support = TBC Experimental
I guess paint(...)
will be far from Firefox's supports, but Firefox is already doing some experimental supports on CSS Properties and Values via layout.css.property-and-value-api.enabled
and layout.css.properties-and-values.enabled
.
layout.css.property-and-value-api.enabled
layout.css.properties-and-values.enabled
- It can be turned to
true
in about:config
to get window.CSS.registerProperty
being supported.
- It does not really mean you can use
@property
.
- Using
typeof window.CSS.registerProperty !== 'undefined'
is not guaranteed to have the support on @property
.
- Note: Starting from Firefox 120, it is truly supported
CSS Detection
No @supports
for @property
There is no @supports (@property) {...}
.
You can use pure CSS or JavaScript to detect this feature is supported or not. (For pure CSS, it can just display the text to tell you it is not supported.)
Pure CSS Detection via Pseudo Element's content
- Set a number property
--num
with initial value above 0. (number 3)
- Use
counter
and counter-style
to generate the support message with number 3 and unsupported message with number 0.
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: #c0ffee;
}
@property --num {
syntax: "<integer>";
initial-value: 3;
inherits: false;
}
@counter-style my-style-fallback {
system: cyclic;
symbols: 'Not Supported''Not Supported';
}
@counter-style my-style {
system: cyclic;
symbols: 'Supported''Supported';
range: 2 4;
fallback: my-style-fallback;
}
#result-css {
counter-set: num var(--num);
}
#result-css::after {
content: 'Not Supported';
content: counter(num, my-style);
}
JavaScript Detection
No try catch block with CSS.registerProperty
- Note: At the time I write this post, it is still not handled correctly in Chrome.
The following code
window.CSS.registerProperty({
name: "--my-color",
syntax: "<color>",
inherits: false,
initialValue: "#c0ffee",
});
might not raise any error if you have defined the property via CSS not via JavaScript.
Note: If you use registerProperty
to register the property name that defined in CSS, then error might come and at the same time the property is being override.
Detection by getComputedStyle
Since every CSS properties are well defined with type and initial value, you can use getComputedStyle
API to check it.
window.getComputedStyle(document.documentElement).getPropertyValue('--my-color');
In your case, the result shall be "#c0ffee"
.
If it is not defined, the result will be ""
.
Combined Coding Demo for Reference
const resultByJs = window.getComputedStyle(document.documentElement).getPropertyValue('--my-color');
document.getElementById('result-js').textContent = resultByJs === '' ? 'Not Supported' : 'Supported'
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: #c0ffee;
}
@property --num {
syntax: "<integer>";
initial-value: 3;
inherits: false;
}
@counter-style my-style-fallback {
system: cyclic;
symbols: 'Not Supported''Not Supported';
}
@counter-style my-style {
system: cyclic;
symbols: 'Supported''Supported';
range: 2 4;
fallback: my-style-fallback;
}
#result-css {
counter-set: num var(--num);
}
#result-css::after {
content: 'Not Supported';
content: counter(num, my-style);
}
<html>
<div>
<h3>`@property` checking by CSS</h3>
Result: <span id="result-css"></span>
</div>
<div>
<h3>`@property` checking by JS</h3>
Result: <span id="result-js"></span>
</div>
</html>
Remarks added on 2023/12/15
It has been tested that, Firefox 120 (Stable) can enable CSS Houdini using layout.css.properties-and-values.enabled = true
However, it is still not yet supported with Animation API.
Further Remarks: The support starts from Firefox Nightly 123.0a1 (2023-12-30) (64-bit)
Further Remarks: The stable support starts from Firefox 123.0 since 2024.03.02
const resultByJs = window.getComputedStyle(document.documentElement).getPropertyValue('--my-color');
document.getElementById('result-js').textContent = resultByJs === '' ? 'Not Supported' : 'Supported'
document.documentElement.animate(
[
{ '--num': '100' },
{ '--num': '0' }
],
{
fill: "forwards",
duration: 1000*30,
easing: 'linear'
}
);
let resultByJsA = window.getComputedStyle(document.documentElement).getPropertyValue('--num');
document.getElementById('result-jsa').textContent = `${resultByJsA}`.length > 1 ? 'Supported' : 'Not Supported';
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: #c0ffee;
}
@property --num {
syntax: "<integer>";
initial-value: 3;
inherits: false;
}
@counter-style my-style-fallback {
system: cyclic;
symbols: 'Not Supported''Not Supported';
}
@counter-style my-style {
system: cyclic;
symbols: 'Supported''Supported';
range: 2 4;
fallback: my-style-fallback;
}
#result-css {
counter-set: num var(--num);
}
#result-css::after {
content: 'Not Supported';
content: counter(num, my-style);
}
h3 {
display: inline-block; width: 18em;
}
<html>
<div>
<h3>`@property` checking by CSS</h3>
Result: <span id="result-css"></span>
</div>
<div>
<h3>`@property` checking by JS</h3>
Result: <span id="result-js"></span>
</div>
<div>
<h3> Animating `@property` checking by JS</h3>
Result: <span id="result-jsa"></span>
</div>
</html>