csstools / postcss-advanced-variables Goto Github PK
View Code? Open in Web Editor NEWUse Sass-like variables, conditionals, and iterators in CSS
License: Creative Commons Zero v1.0 Universal
Use Sass-like variables, conditionals, and iterators in CSS
License: Creative Commons Zero v1.0 Universal
The sass-import-resolve
has a bug that resolves its promise with undefined
, which causes a destructuring error:
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'file' of undefined
at node_modules/postcss-advanced-variables/index.bundle.js:400:21
I'm having some trouble with outputting variable as encapsulated strings - it may just be confusion on my part, but let me give you some examples:
If I add a string as a variable, eg:
$font-custom-name: "Custom Font";
In Sass I would use:
font-family: "#{$font-custom-name}"
And end up with this:
font-family: "Custom Font";
Every way I try to output it ...
.example-1 {
font-family: $font-custom-name;
}
.example-2 {
font-family: "$font-custom-name";
}
.example-3 {
font-family: $(font-custom-name);
}
.example-4 {
font-family: "$(font-custom-name)";
}
.example-5 {
font-family: $font-custom-name;
}
.example-6 {
font-family: "#{$font-custom-name}";
}
.example-7 {
font-family: ""$font-custom-name"";
}
.example-8 {
font-family: '$font-custom-name';
}
... none of them seem to come out how I want them to.
.example-1 {
font-family: Custom Font;
}
.example-2 {
font-family: ,Custom Font;
}
.example-3 {
font-family: Custom Font;
}
.example-4 {
font-family: ,Custom Font;
}
.example-5 {
font-family: Custom Font;
}
.example-6 {
font-family: ,Custom Font;
}
.example-7 {
font-family: ,Custom Font;
}
.example-8 {
font-family: '"Custom Font"';
}
I ran into this crash while using this plugin to transform the styles inside of a Svelte component.
If no source file path is given, and @import
is used in the template, this TypeError is thrown:
TypeError: Cannot read property 'result' of undefined
at getImportOpts (/some-path/node_modules/postcss-advanced-variables/index.bundle.js:451:79)
at transformImportAtrule (/some-path/node_modules/postcss-advanced-variables/index.bundle.js:377:24)
at /some-path/node_modules/postcss-advanced-variables/index.bundle.js:683:5
at Array.forEach (<anonymous>)
at transformNode (/some-path/node_modules/postcss-advanced-variables/index.bundle.js:667:22)
at /some-path/node_modules/postcss-advanced-variables/index.bundle.js:739:3
at /some-path/node_modules/precss/index.bundle.js:31:12
at <anonymous>
Test case/fix coming momentarily.
Declare the variables in the options passed to post-css-advanced-varialbes.
var options = {
'variables': {
'bearColor': 'blue'
}
};
postcss([ require('postcss-advanced-variables')(options) ])
.bear {
color: $bearColor;
}
As you can see, we have declared the variable during the plugin initialization in options.variables
.
It's seem that recursive var currently not working:
$alpha-color: #111;
$beta-color: #222;
$gamma-color: #333;
@each $name in (alpha, beta, gamma){
view-content {
color: $($(name)-color);
}
}
Is there a workaround way?
It broke somewhere after version 1.2.2
...? Not sure if it was in 2.0.0.
or 2.1.0
. The following use to translate:
$poppins: 'Poppins', 'Helvetica Neue', Helvetica, Arial, sans-serif;
body {
font-family: $poppins;
}
[to]
body {
font-family: 'Poppins', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
but now it's outputting like so:
body {
font-family: ('Poppins','Helvetica Neue',Helvetica,Arial,sans-serif);
}
Any ideas? Might need to roll back until fixed.
I have a example
$selectPrefixCls: rc-select;
.search__field__wrap-$selectPrefixCls {
width: 100%;
}
can compile to
.search__field__wrap-rc-select {
width: 100%;
}
but when i wirte it like this
$selectPrefixCls: rc-select;
.$selectPrefixCls-search__field__wrap {
width: 100%;
}
it can not compile to
.rc-select-search__field__wrap {
width: 100%;
}
Hi Jonathan,
Is there a way to export the advanced variables such that they can be imported into a JS file? I see you have a separate repo https://github.com/jonathantneal/postcss-export-custom-variables but this is different syntax.
For example:
https://blog.bluematador.com/posts/how-to-share-variables-between-js-and-sass/
// styles/animation.scss
$animation-length: 250;
$animation-length-ms: $animation-length + 0ms;
:export {
animationMillis: $animation-length-ms;
}
.component-enter {
...
transition: all $animation-length-ms ease-in;
}
// js/animation.js
import styles from '../styles/animation.scss'
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'
const millis = parseInt(styles.animationMillis)
...
<CSSTransitionGroup
transitionName="component"
transitionEnterTimeout={millis}
transitionLeaveTimeout={millis}
/>
...
I have found https://github.com/nahody/postcss-export-vars, however if I have variables which are based on other variables it will not resolve them e.g.
$green-25: color($themeBaseColor04 tint(95%));
Thanks!
Scss can do this with variables -
$example: 'value' !default;
Whereby it will only set the value of $example if it doesn't already exist. This is an important function to allow cascading.
Could this be supported in postcss-advanced-variables ?
eg. precss offical demo
url(/icons/$name.png)
=> url(/icons/search.png);
but
url(/icons/$name-suffix.png)
=> url(/icons/$name-suffix.png);
How about supporting url(/icons/#{$name}-suffix.png)
like sass does.
Thanks for this awesome project!
I'm wondering if you'd be open to accepting contributions, and would be available to provide guidance, for the following new feature.
I'd like to be able to @import 'some-identifier'
, which contains syntax that is never emitted (specifically a @mixin
declaration), and still choose not to have the target file inlined. I can currently use the disable
option (or the importFilter
option) to turn off inlining, but when I do, the @include
cannot resolve references to mixins in the @import
ed files. I get an error like this:
CssSyntaxError: postcss-advanced-variables: /path/test.css:4:12: Could not resolve the mixin for "my-mixin"
Why? I'd like to centralize the definition of mixins and other declarations that have a particular concern. I also am choosing not to inline @import
s because my deliverable is a library, where I feel consumers of the library should choose if and how they want the individual files bundled. My goal is to emit standard CSS that is reusable across many projects, so the @mixin
/@include
should be processed out of the output.
Input:
/* spacing.css */
@mixin no-spacing {
margin: 0;
padding: 0;
}
:root {
--other-spacing-related-var: 30px;
}
/* typography.css */
@import './spacing.css';
.my-header {
@include no-spacing
font-size: 20px;
line-height: 1.6;
font-weight: 700;
}
Output (desired) when processing typography.css
:
@import './spacing.css';
.my-header {
margin: 0;
padding: 0;
font-size: 20px;
line-height: 1.6;
font-weight: 700;
}
Hi @jonathantneal. I'm using this plugin to avoid some postcss-easy-import bugs but i can't use the pcss
extension on imports. I really need it for syntax highlighting.
Variables with similar names to css properties are not interpreted.
/* Declaration */
$transition: all 0.24s ease-in-out;
$transitionProp: all 0.24s ease-in-out;
/* use */
.my-class {
transition: $transition;
transition: $transitionProp;
}
None of the above work correctly.
I think it would be helpful to add support for passing variables to start, end and increment properties.
example:
@for $i from $start to $end by $increment {}
Using postcss-advanced-variables 2.1.x, I'm not able to define a mixin or a variable in one file, and then import that file to use the mixin/variable in another file.
Failing tests coming momentarily.
Hi,
I was wondering, I have a project with lots of variables, and it seems that variable variables aren't supported ?
An example like this :
$var1: blue;
$var2: $var1;
body {
color: $var2;
}
If it actually isn't supported yet, is it planned for the future ?
Is it possible to have a variable imported from a different css file?
Hi!
Thanks a lot for this wonderful plugin. Could you please release the version that supports passing variables from options, we really need this feature to be on npm.
I came here via precss, so forgive me if this isn't the correct place to bring this up.
I don't see any mention of lists in the readme, aside from the @each
example. I'm not sure if this is a feature of postcss-advanced-variables or just luck or what, but this is what I've found:
// this works with @each
$list: foo, bar;
// this too
$list: (foo, bar);
// and so do these
$list:
foo,
bar;
$list: foo,
bar;
// but this results in looping though each character
$list: (
foo,
bar
);
The last way was the first I tried from intuition, but that's just me. In any case I would have benefited from some documentation, especially being that list support is totally a feature worth noting!
@for $i from 1 through 5 by 2 {
.width-#{$i} {
width: #{$i}0em;
}
}
@for $j from 1 to 5 by 2 {
.height-#{$j} {
height: #{$j}0em;
}
}
This example does not work.
CssSyntaxError: test.css:2:12: Unknown word
It seems that $(i)
and $(j)
must be used instead.
eachAtEachRule doesn't accept an iterator whereas postcss-each does.
If this isn't possible for some reason, let me know and I'll PR an iterator.
// works in postcss-each
@each $val, $i in foo, bar {
.icon-$(val) {
background: url("$(val)_$(i).png");
}
}
Hi! I'm having trouble doing the following. I've been skulking around, but found no solace.
@each $a in (2, 3, 4) {
@for $b from 1 to $a {
property: calc($a + $b);
}
}
This correctly returns property: 3
up until property: 8
.
This, however, has trouble working as expected.
@each $a, $b in (1, 2, 3), (4, 5, 6) {
@for $c from 1 to ($a + $b) {
property: $c;
}
}
it is even possible? calc($a + $b)
does not work either.
How this plugin is different from postcss-simple-vars?
Example here: https://runkit.com/sigorilla/wrong-if
Here is what I'm trying to accomplish. If I arbitrarily set the end to 30, it will work.
@define-mixin grid $size, $width, $columns {
@media only screen and (min-width: $(width)px) {
@for $i from 1 to $columns {
.col-$(size)-$(i) {
width: $i*$width;
}
}
}
}
@mixin grid xs, 320, 18;
precss:modules.css:19:23: Could not resolve the variable "$name" within "button $name, $color"
17 | }
18 |
> 19 | @define-mixin button $name, $color {
| ^
20 | .button-$name {
21 | @extend %button;
at Input.error (node_modules\postcss\lib\input.es6:90:22)
at AtRule.error (node_modules\postcss\lib\node.es6:86:38)
at manageUnresolved (node_modules\precss\node_modules\postcss-advanced-variables\index.bundle.js:52:14)
at node_modules\precss\node_modules\postcss-advanced-variables\index.bundle.js:73:4
at String.replace (<anonymous>)
at getReplacedString (node_modules\precss\node_modules\postcss-advanced-variables\index.bundle.js:59:30)
at transformAtrule (node_modules\precss\node_modules\postcss-advanced-variables\index.bundle.js:144:16)
at node_modules\precss\node_modules\postcss-advanced-variables\index.bundle.js:694:5
at Array.forEach (<anonymous>)
at transformNode (node_modules\precss\node_modules\postcss-advanced-variables\index.bundle.js:666:22)
Code:
@define-mixin button $name, $color {
.button-$name {
@extend %button;
background-color: $color;
color: #fff;
}
.button-$name:hover {
background-color: @background-color;
color: $color;
}
}
This throws:
@mixin foo() {
color: red;
}
TypeError: Cannot read property 'slice' of undefined
at node_modules\postcss-advanced-variables\index.bundle.js:608:27
at Array.map ()
at getMixinOpts (node_modules\postcss-advanced-variables\index.bundle.js:606:76)
at transformMixinAtrule (node_modules\postcss-advanced-variables\index.bundle.js:584:23)
at node_modules\postcss-advanced-variables\index.bundle.js:691:5
at Array.forEach ()
at transformNode (node_modules\postcss-advanced-variables\index.bundle.js:666:22)
at node_modules\postcss-advanced-variables\index.bundle.js:738:3
at LazyResult.run (node_modules\postcss\lib\lazy-result.js:277:20)
at LazyResult.asyncTick (node_modules\postcss\lib\lazy-result.js:192:32)
error Command failed with exit code 1.
While this works:
@mixin foo {
color: red;
}
๐ postcss-advanced-variables does not trim quotes (single or double) around variable values and it doesn't seem like there is any option to change this. This prevents empty strings from working (e.g. if I have a mixin where the default value of an argument is an empty string).
Input:
$suffix: "";
.invalid#{$suffix} {
color: red;
}
Output:
.invalid"" {
color: red;
}
Expected output (this is what sass would produce):
.invalid {
color: red;
}
You can reproduce this in the scss test case simply by wrapping green
in line 1 with single or double quotes. The expected output should be the same, but the test fails.
I'm converting my sass mixins library into postcss, but not possible yet:
@define-mixin center $horizontal: true, $vertical: true {
position: absolute;
@if $horizontal || $vertical {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
} @else if $horizontal {
left: 50%;
transform: translate(-50%, 0);
} @else if $vertical {
top: 50%;
transform: translate(0, -50%);
}
}
I have the following css using advanced variables:
/* style.css */
$brandColor: #8C50FF;
.common {
color: $brandColor;
text-decoration: none;
}
Now I want to replace the brandColor value in my webpack config, based on the docs I tried:
vars({
variables: {
brandColor: '#3e00b6'
}
})
The actual value remains #8C50FF. If I remove the $brandColor: #8C50FF; entry, then the value is set.
It would be great to not require the variables to be present always and set a default one instead. Can we provide this behavior with an option? Let the default behavior continue but invert the behavior to do this through configuration? what do you think?
Today I encountered interesting case. Took me quite some time to figure it out.
@for $i from 0 to 10 {
@if $i < 50 {
//true
}
@else {
//false
}
}
result was surprising when left operand equals 6, 7, 8 or 9:
$i == 1 => true
$i == 2 => true
$i == 3 => true
$i == 4 => true
$i == 5 => true
$i == 6 => false
$i == 7 => false
$i == 8 => false
$i == 9 => false
$i == 10 => true
turned out, it compares strings which are compared lexicographically
Interpolation of variables not separated with some character only replaces the first variable.
See my failing test case here: kommen@3a748e1
webpack 3.10
vue 2.5.13
.postcssrc.js:
module.exports = {
"plugins": {
...
"postcss-advanced-variables": {
variables: require('./src/assets/stylesheets/variables.json')
},
Produces:
name: 'CssSyntaxError',
reason: 'Could not resolve the variable "$gray-bg" within "$gray-bg"',
I'm trying to set up an each loop to render a list of layers as custom properties that we'll use for z-index values in our pattern library. However, I can't find a way to get the layer variable to render as a custom property name.
Here's a test case:
$layers: alpha, beta, gamma, delta;
:root {
@each $layer $i in $layers {
--#{$layer}: $i;
}
}
.beta {
z-index: var(--beta);
}
I'm use gulp run postcss task.I got this issue when I run the task.
All devDependencies's version are latest.What's wrong on earth?
Including empty params on a mixin include (when there are default params) causes an empty string to be assumed for the passed value, rather than indicating that nothing was passed. This creates invalid styles.
Example, using mixin defined in the README:
/* Start: From the README */
@mixin heading-text($color: #242424, $font-size: 4em) {
color: $color;
font-size: $font-size;
}
h1, h2, h3 {
@include heading-text;
}
.some-heading-component > :first-child {
@include heading-text(#111111, 6em);
}
/* End: From the README */
/* Empty parens results in corrupted data */
.empty-params {
@include heading-text();
}
Output:
/* Start: From the README */
h1, h2, h3 {
color: #242424;
font-size: 4em;
}
.some-heading-component > :first-child {
color: #111111;
font-size: 6em;
}
/* End: From the README */
/* Empty parens results in corrupted data */
.empty-params {
color: ; /* <= ERROR */
font-size: 4em;
}
I attempted to create a live code example on CodePen, as recommended, but I was unable to figure out how to tell CodePen to use PreCSS (or this plugin specifically) on top of PostCSS. However, my example compiles locally as described through PostCSS (version 7.0.16), which is using the PreCSS plugin (version 4.0.0, latest), which is using postcss-advanced-variables (version 3.0.0, latest). This is run via gulp-postcss (version 8.0.0, latest).
Unable to install https://github.com/jonathantneal/precss due to https://github.com/jonathantneal/postcss-advanced-variables and its dependency on @csstools/sass-import-resolve
. Getting @csstools/sass-import-resolve
is not in the npm registry.
Added @csstools/sass-import-resolve:registry = "http://registry.npmjs.org"
to my npm config to no avail.
Trying to upgrade from precss 2.0.0 to 3.1.0
https://github.com/jonathantneal/postcss-advanced-variables/blob/master/index.js#L2
This probably shouldn't be in the distributed bundle, because it Babel throws an error if it's already included, and it means this library can't be imported into in any projects that are already using babel-polyfill
.
Thanks!
if variable start by '--' ,can't be parsed
Example:
$foo: true
@if $foo == true {
// works fine
}
@if $foo {
// triggers exception
}
Hi, I found out the similar issue below.
#8
But it appears that @if and @else works fine, not @elseif.
Is there anyone to checkout this issue.
$theme-type: test1;
@if $theme-type == test1 {
background: #000000;
} @else if $theme-type == test2 {
background: #DDDDDD;
} @else {
background: #FAFAFA;
}
By the way, this plugin is so great.
Thanks for providing the great plugin!
In SASS I am able to do things like this:
$breakpointSm: 480px;
$breakpointMd: 600px;
$breakpointMdMin: $breakpointSm + 1;
This way, my $breakpointMdMin
var will be translated to 481px
in SASS, but to 480px + 1
with this package.
Similar to how in postcss-simple-vars you can have:
...
variables: function () {
return require('./config/colors');
}
...
This plugin should accept a file for variables instead of simply an object.
If this is allowed already, I couldn't manage to get it to work.
an undefined variable is silently copied through. Is there a way to fail or show warnings? Many times an undefined variable is a just a typo
With 2.3.2 my (large, complicated) Gatsby / Webpack project works fine.
If I upgrade to 3.0 I get (many) reports of
You did not set any plugins, parser, or stringifier. Right now, PostCSS does not
hing. Pick plugins for your case on https://www.postcss.parts/ and use them in p
ostcss.config.js.
Postcss still runs, still produces correct output. Any ideas?
It's a very large project but am trying to reduce to a reproducible example.
I am not getting this statement to work. Using your example:
@each $animal $i in (puma, sea-slug, egret, salamander) { .$(animal)-icon { background-image: url("images/icon-$(i).svg"); } }
The CSS that is returned when I include the counter($i) looks like this:
.$(animal)-icon { background-image: url("images/icon-$i.svg"); }
If I remove the counter, the statement proceeds as expected.
I would like to set default values of mixin parameters to the value of another variable, but postcss will output the variable name instead.
Ie the following code:
@mixin .container($max-width: $content-max-width, $gutter: global-gutter) {
width: calc(100% - $gutter);
max-width: $max-width;
margin: 0 auto;
}
#app > .container {
@include .container;
}
will output
#app > .container {
width: calc(100% - $global-gutter);
max-width: $content-max-width;
margin: 0 auto;
}
Are there any plans to support similar syntax?
Will be good to support it.
I'm got this warning: Node#removeSelfe is deprecated. Use Node#remove
when using the plugin. There weren't any problems with the results. But wanted to share.
This is how I'm running it.
var gulp = require('gulp'),
postcss = require('gulp-postcss'),
variables = require('postcss-advanced-variables');
gulp.task('test', function () {
var processors = [
variables
];
return gulp.src('toCompile/test.css')
.pipe( postcss(processors) )
.pipe(gulp.dest(''))
});
I hope this is useful!
EDIT: it might not be caused by this plugin but by PostCSS itself, but I only get the warning when I use the plugin.
When using @import
, the plugin is not able to correctly parse stylesheet contents in some scenarios.
An obvious example of this is when using SASS style inline comments (// comment
). Generally using any non-standard syntax will also cause the plugin to fail and leave the stylesheet contents unparsed.
Related issues: csstools/precss#112, csstools/precss#111, csstools/precss#110
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.