Installations
npm install postcss-calc-css-variables
Developer Guide
Typescript
No
Module System
N/A
Node Version
18.14.2
NPM Version
9.5.0
Score
72.2
Supply Chain
98.5
Quality
74.9
Maintenance
100
Vulnerability
100
License
Releases
postcss-css-variables-v0.14.0
Published on 25 Nov 2019
postcss-css-variables-v0.13.0
Published on 17 Jun 2019
postcss-css-variables-v0.12.0
Published on 21 Feb 2019
postcss-css-variables-v0.11.0
Published on 09 Oct 2018
postcss-css-variables-v0.10.0
Published on 09 Oct 2018
postcss-css-variables-v0.9.0
Published on 26 Jun 2018
Contributors
Unable to fetch Contributors
Languages
JavaScript (99.43%)
CSS (0.5%)
HTML (0.07%)
Developer
Download Statistics
Total Downloads
259
Last Day
1
Last Week
4
Last Month
14
Last Year
62
GitHub Statistics
543 Stars
157 Commits
61 Forks
15 Watching
10 Branches
22 Contributors
Bundle Size
10.24 kB
Minified
3.93 kB
Minified + Gzipped
Package Meta Information
Latest Version
0.20.1
Package Id
postcss-calc-css-variables@0.20.1
Unpacked Size
61.79 kB
Size
18.57 kB
File Count
19
NPM Version
9.5.0
Node Version
18.14.2
Publised On
31 Jul 2023
Total Downloads
Cumulative downloads
Total Downloads
259
Last day
-66.7%
1
Compared to previous day
Last week
-33.3%
4
Compared to previous week
Last month
250%
14
Compared to previous month
Last year
-68.5%
62
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
3
Peer Dependencies
1
PostCSS CSS Variables
PostCSS plugin to transform CSS Custom Properties (CSS variables)
syntax into a static representation. This plugin provides a future-proof way of using most of CSS variables features, including selector cascading with some caveats, because this can only see the CSS, not the potentially dynamic HTML and DOM the CSS is applied to.
Install
npm install postcss postcss-css-variables --save-dev
Table of Contents
- Code Playground
- Usage
- Syntax - Defining Custom Properties with
--*
- Using Variables/Custom Properties withvar()
- Features - At-rules like
@media
,@support
, etc. - Pseudo-classes and Elements - Nested Rules - Why? - Interoperability - Differences from
postcss-custom-properties
- Caveats
- Options
- Quick Reference/Notes
- Testing
- Changelog
Code Playground
Try it in the playground and see what you think! Just add some CSS and see to see the final transformed/compiled CSS. You can try anything here in the playground, too.
Usage
For more general PostCSS usage, look here.
1var postcss = require("postcss"); 2var cssvariables = require("postcss-css-variables"); 3 4var fs = require("fs"); 5 6var mycss = fs.readFileSync("input.css", "utf8"); 7 8// Process your CSS with postcss-css-variables 9var output = postcss([cssvariables(/*options*/)]).process(mycss).css; 10 11console.log(output);
Syntax
Defining Custom Properties with --*
A custom property is any property whose name starts with two dashes --
. A property must be in a rule.
Note: :root
is nothing more than the selector for the root DOM node. Any other selector like .class
, #id
, or even #foo ~ .bar > span.baz
works.
1:root { 2 --foo-width: 100px; 3 --foo-bg-color: rgba(255, 0, 0, 0.85); 4} 5 6.foo { 7 --foo-width: 100px; 8 --foo-bg-color: rgba(255, 0, 0, 0.85); 9}
Custom properties can be declared multiple times, but like variable scope in other languages, only the most specific one takes precedence.
1:root { 2 --some-color: red; 3} 4 5.foo { 6 /* red */ 7 color: var(--some-color); 8} 9 10.bar { 11 --some-color: blue; 12 /* blue */ 13 color: var(--some-color); 14} 15 16.bar:hover { 17 --some-color: green; 18 /* Automatically gets a `color: green;` declaration because we `--some-color` used within scope elsewhere */ 19}
W3C Draft: CSS Custom Properties for Cascading Variables, section 2
Using Variables/Custom Properties with var()
1.foo { 2 width: var(--foo-width); 3 /* You can even provide a fallback */ 4 background: var(--foo-bg-color, #ff0000); 5}
W3C Draft: CSS Custom Properties for Cascading Variables, section 3
Features
At-rules like @media
, @support
, etc.
It's perfectly okay to declare CSS variables inside media queries and the like. It'll work just as you would expect.
1:root { 2 --width: 100px; 3} 4 5@media (max-width: 1000px) { 6 :root { 7 --width: 200px; 8 } 9} 10 11.box { 12 width: var(--width); 13}
Will be transformed to:
1.box { 2 width: 100px; 3} 4 5@media (max-width: 1000px) { 6 .box { 7 width: 200px; 8 } 9}
Pseudo-classes and Elements
Psuedo-classes are also dealt with correctly, because it's easy to statically determine.
1.foo { 2 --foo-color: red; 3 color: var(--foo-color); 4} 5 6.foo:hover { 7 --foo-color: green; 8}
Will be transformed to:
1.foo { 2 color: red; 3} 4 5.foo:hover { 6 color: green; 7}
Nested Rules
This pairs very well with postcss-nested
or postcss-nesting
, adding support for nested rules. For either, you must put the plugin before postcss-css-variables
in the plugin stack so that the &
references are expanded first (postcss-css-variables
doesn't understand them). For example, with postcss-nested
, your PostCSS setup would look like this:
1var postcss = require("postcss"); 2var cssvariables = require("postcss-css-variables"); 3var nested = require("postcss-nested"); 4 5var fs = require("fs"); 6 7var mycss = fs.readFileSync("input.css", "utf8"); 8 9var output = postcss([ 10 // Flatten/unnest rules 11 nested, 12 // Then process any CSS variables 13 cssvariables(/*options*/) 14]).process(mycss).css; 15 16console.log(output);
For a simple example with nesting:
1.box-foo { 2 --some-width: 150px; 3 width: var(--some-width); 4 5 .box-bar { 6 width: var(--some-width); 7 } 8}
With also postcss-nesting
, this will be transformed to:
1.box-foo { 2 width: 150px; 3} 4 5.box-foo .box-bar { 6 width: 150px; 7}
For a more complex example with a media query:
1:root { 2 --some-width: 150px; 3} 4 5.box-foo { 6 width: var(--some-width); 7 8 .box-bar { 9 width: var(--some-width); 10 } 11} 12 13@media (max-width: 800px) { 14 .box-foo { 15 --some-width: 300px; 16 } 17}
Will be transformed to:
1.box-foo { 2 width: 150px; 3} 4 5.box-foo .box-bar { 6 width: 150px; 7} 8 9@media (max-width: 800px) { 10 .box-foo { 11 width: 300px; 12 } 13 14 .box-foo .box-bar { 15 width: 300px; 16 } 17}
Why?
This plugin was spawned out of a discussion on the cssnext
repo and a personal need.
There is another similar plugin available, postcss-custom-properties
, although it restricts itself much more than this plugin, preferring partial spec conformance. This plugin has the same capabilities but also adds imperfect feature support which stem from not being able to know what the DOM will look like when you compile your CSS. We instead look at the explicit structure of your CSS selectors.
Interoperability and differences from postcss-custom-properties
Putting postcss-css-variables
in place of postcss-custom-properties
should work out of the box.
In postcss-custom-properties
, CSS variable declarations are specifically restricted to the :root
selector.
In postcss-css-variables
, this is not the case and they may be declared inside any rule with whatever selector. The variables are substituted based on statically known CSS selector inheritance.
Here's a quick overview of the differences:
- CSS variables may be declared in any selector like
.foo
or.foo .bar:hover
, and is not limited to just:root
- CSS variables may be declared in
@media
,@support
, and other at-rules. - CSS variables may be declared in
:hover
and other psuedo-classes, which get expanded properly. - Variables in nested rules can be deduced with the help of
postcss-nested
orpostcss-nesting
.
Continue to the next section to see where some of these might be unsafe to do. There are reasons behind the ethos of why the other plugin, postcss-custom-properties
, is very limited in what it supports, due to differing opinions on what is okay to support.
Caveats
When you declare a CSS variable inside one selector, but consume it in another, this does make an unsafe assumption about it which can be non-conforming in certain edge cases. Here is an example where these limitations result in non-conforming behavior.
Note the nested markup below. We only know about the DOM's inheritance from your CSS selectors. If you want nest multiple times, you need to be explicit about it in your CSS which isn't necessary with browser that natively support CSS variables. See the innermost <div class="title">
1<div class="component"> 2 Black 3 4 <div class="title"> 5 Blue 6 7 <div class="decoration"> 8 Green 9 10 <div class="title">Blue with this plugin, but green per spec</div> 11 </div> 12 </div> 13</div>
1.component { 2 --text-color: blue; 3} 4 5.component .title { 6 color: var(--text-color); 7} 8 9.component .decoration { 10 --text-color: green; 11 color: var(--text-color); 12}
postcss-custom-properties
avoids this problem entirely by restricting itself to just the :root
selector. This is because the developers there would prefer to not support a feature instead of something almost-spec-compliant like what postcss-css-variables
does.
Options
preserve
(default: false
)
Allows you to preserve custom properties & var() usage in output.
Possible values:
false
: Removes--var
declarations and replacesvar()
with their resolved/computed values.true
: Keepsvar()
declarations in the output and has the computed value as a fallback declaration. Also keeps computed--var
declarations.'computed'
: Keeps computed--var
declarations in the output. Handy to make them available to your JavaScript.(declaration) => boolean|'computed'
: function/callback to programmatically return whether preserve the respective declaration
variables
(default: {}
)
Define an object map of variables in JavaScript that will be declared at the :root
scope.
Can be a simple key-value pair or an object with a value
property and an optional isImportant
bool property.
The object keys are automatically prefixed with --
(according to CSS custom property syntax) if you do not provide it.
preserveInjectedVariables
(default: true
)
Whether to preserve the custom property declarations inserted via the variables
option from final output.
A typical use case is CSS Modules, where you would want to avoid
repeating custom property definitions in every module passed through this plugin. Setting this option to false
prevents JS-injected variables from appearing in output CSS.
1var postcss = require("postcss"); 2var cssvariables = require("postcss-css-variables"); 3 4postcss([ 5 cssvariables({ 6 variables: { 7 "--some-var": "100px", 8 "--other-var": { 9 value: "#00ff00" 10 }, 11 "--important-var": { 12 value: "#ff0000", 13 isImportant: true 14 } 15 } 16 }) 17]).process(css, opts);
preserveAtRulesOrder
(default: false
)
Keeps your at-rules like media queries in the order to defined them.
Ideally, this would be defaulted to true
and it will be in the next major version. All of the tests expecations need to be updated and probably just drop support for preserveAtRulesOrder: false
Quick Reference/Notes
- This plugin was spawned out of a discussion on the
cssnext
repo. - We provide a larger CSS variable feature subset than
postcss-custom-properties
. - Related links and issues: - var declared in media query should pull in properties that use/reference that var on
cssnext/cssnext
- Investigate support for media-query scoped properties onpostcss/postcss-custom-properties
- remove:root
limitation by injecting rules with new declarations that just contains modified properties. onpostcss/postcss-custom-properties
Testing
We have a suite of Mocha tests. If you see something that doesn't have coverage, make an issue or pull request.
Run once:
npm install
Run whenever you want to test:
npm run test
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Warn: project license file does not contain an FSF or OSI license.
Reason
Found 6/24 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 14 are checked with a SAST tool
Score
3.3
/10
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More