Scrum / postcss-at-rules-variables

PostCss plugin to use CSS Custom Properties in at-rule @each, @for, @if, @else and more...

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

var() not resolving in at-rules when used along with postcss-css-variables or custom-properties

htshah opened this issue · comments

I am using this plugin with postcss v8 in gulp.

styles task in gulpfile.js:

const postcss = require("gulp-postcss");
const postcssPresetEnv = require("postcss-preset-env");
const postcssNormalize = require("postcss-normalize");
const atImport = require("postcss-import");
const atVariables = require('postcss-at-rules-variables');
const cssVariables = require('postcss-css-variables');
const cssnano = require("cssnano");
const combineMediaQueries = require("postcss-combine-media-query");
const postcssNested = require("postcss-nested");
const postcssSCSS = require("postcss-scss");
const postcssCriticalSplit = require('postcss-critical-split');
const postcssSortMediaQueries = require('postcss-sort-media-queries');
const postcssMixins = require('postcss-mixins');

const postcssOptions = {
    syntax: postcssSCSS,
    parse: postcssSCSS
};

function preprocessCss(){
    const postcssProcessors = [
        atVariables(),
        atImport(),
        postcssNormalize(),
        postcssMixins(),
        postcssNested(),
        cssVariables(),
        postcssPresetEnv({
            stage: 0,
            preserve: false,
            autoprefixer: Config.production,
            features: { 
                // Replaced with postcss-nested
                "nesting-rules": false,

                // Replaced with postcss-css-variables
                "custom-properties": false
            },
            fontFace: true
        }),
    ];

    return src(getFilesGlob('css'))
        .pipe(gulpIf(!Config.production, sourcemaps.init({loadMaps: true})))
        .pipe(
            postcss(postcssProcessors, postcssOptions)
        )
        .pipe(gulpIf(!Config.production, sourcemaps.write('.')))
        .pipe(dest("assets/css"))
    ;
}

Here is a small snippet from my actual code.

variables.css

:root{
    --gutters: 15px;
    --color: red;
}

common.css

@import "variables.css";

@define-mixin add-gutters $gutter {
    &{
          margin: 0 $gutter;
    }
}

/*Some other common code*/

index.css

@import "common.css";

.container{
    @mixin add-gutters var(--gutters);
    color: var(--color);
}

Expected output: index.css
I can achieve this output by explicitly declaring the css vars in the variables option of this plugin which I don't want to do.

.container{
    margin: 0 15px;
    color: red;
}

Actual output: index.css

.container{
    margin: 0 var(--gutters);
    color: red;

    /* If postcss-css-variables or custom-properties are disabled */
    margin: 0 15px;
    color: var(--color);
}

Because you need to initially import everything so that it can be resolved

    const postcssProcessors = [
        atImport(),
        atVariables(),
        postcssNormalize(),
        postcssMixins(),
        postcssNested(),
        cssVariables(),
        postcssPresetEnv({
            stage: 0,
            preserve: false,
            autoprefixer: Config.production,
            features: { 
                // Replaced with postcss-nested
                "nesting-rules": false,

                // Replaced with postcss-css-variables
                "custom-properties": false
            },
            fontFace: true
        }),
    ];

Hi,
Thanks for a prompt reply. I've even tried doing that but with no luck.

But if I set the preserve flag to true for the cssVariables then this plugin works as expected. But this leads to unwanted duplication of css rules.

const postcssProcessors = [
        atImport(),
        atVariables(),                           // Moved after atImport and it still does not work.
        postcssNormalize(),
        postcssMixins(),
        postcssNested(),
        cssVariables({
             preserve: true,                     // If this option is true, then this plugin works as expected.
        }),
        postcssPresetEnv({
            stage: 0,
            preserve: false,
            autoprefixer: Config.production,
            features: { 
                // Replaced with postcss-nested
                "nesting-rules": false,

                // Replaced with postcss-css-variables
                "custom-properties": false
            },
            fontFace: true
        }),
    ];

Expected: The output should not have any css variables in it.

Output: After setting preserve flag to true in cssVariables plugin.

/* Not needed in output. */
:root{
    --gutters: 15px;
    --color: red;
}

.container{
    margin: 0 15px;
    color: red;
    
    /* Not needed in output. */
    color: var(--color);
}

@htshah use options declarationByWalk: true

demo

Thanks a lot! It now working as expected.