# How to set up Sage with postcss custom properties?

**URL:** https://discourse.roots.io/t/how-to-set-up-sage-with-postcss-custom-properties/17611
**Category:** sage
**Tags:** webpack
**Created:** 2020-02-10T14:34:03Z
**Posts:** 12

## Post 1 by @djmtype — 2020-02-10T14:34:03Z

How do you set up Sage to use both SCSS and PostCSS’ custom properites?

I’ve already added the postcss custom properties using yarn. Now what? I’m not using any frameworks BTW.

My post.config.js file (which is not working):

```
/* eslint-disable */

const postcssCustomProperties = require('postcss-custom-properties');

const cssnanoConfig = {
  preset: ['default', { discardComments: { removeAll: true } }]
};

module.exports = ({ file, options }) => {
  return {
    parser: options.enabled.optimize ? 'postcss-safe-parser' : undefined,
    plugins: {
      autoprefixer: true,
      postcssCustomProperties: true,
      cssnano: options.enabled.optimize ? cssnanoConfig : false,
      
    },
  };
};
```

---

## Post 2 by @djmtype — 2020-02-19T15:53:32Z

Doy!

Inside postcss.config.js add **preserve: false** to compile css variables.

`'postcss-custom-properties': { preserve: false, },`

---

## Post 3 by @dangelion — 2020-10-08T08:43:50Z

Hi @djmtype  
could you help me to get it to works?

I installed [postcss-custom-properties](https://www.npmjs.com/package/postcss-custom-properties):  
`yarn add postcss-custom-properties --dev --ignore-engines`

Then, my **postcss.config.js** file. I tried all the below solutions but none of them worked

```
/* eslint-disable */

const postcssCustomProperties = require('postcss-custom-properties');

const cssnanoConfig = {
  preset: ['default', { discardComments: { removeAll: true } }]
};

module.exports = ({ file, options }) => {
  return {
    parser: options.enabled.optimize ? 'postcss-safe-parser' : undefined,
    plugins: {
      autoprefixer: true,
      // postcssCustomProperties: true,
      // 'postcss-custom-properties': { preserve: false, },
      postcssCustomProperties: {
        preserve: false,
      },
      cssnano: options.enabled.optimize ? cssnanoConfig : false,
    },
  };
};
```

I get errors like

```
ERROR Failed to compile with 1 errors 10:36:17

 error in ./resources/assets/styles/main.scss

Syntax Error: /Users/xxx/xxx/xxx/wp-content/themes/xxx/node_modules/is-url-superb/index.js:11
        } catch {
                ^

SyntaxError: Unexpected token {

 @ ./resources/assets/styles/main.scss
```

Thanks

---

## Post 4 by @djmtype — 2020-10-08T11:03:52Z

@dangelion Seems like you might have a general css error – a syntax error more specifically.

What happens if you comment out: `postcssCustomProperties: { preserve: false, },`?

What does your `main.scss` file look like?

---

## Post 5 by @dangelion — 2020-10-08T12:12:37Z

Hi @djmtype  
commenting that line I’ve that error posted above.  
Only commenting the  
`const postcssCustomProperties = require('postcss-custom-properties');`  
the errors gone away. It seems that line causing error :thinking:

My **main.scss** , but don’t think the problem comes from here

```
@import "utils/mixins";
@import "common/fonts"; // @font-face have to be first in compiled CSS
@import "common/variables";
// Normalize.css
// @import "~normalize.css/normalize.css";
@import "common/typography";
@import "common/global";
@import "components/buttons";
//@import "components/comments";
@import "components/forms";
// @import "components/wp-classes";
@import "layouts/header";
@import "layouts/sidebar";
@import "layouts/footer";
@import "layouts/pages";
@import "layouts/posts";
@import "common/grid";
@import "common/animations";
@import "common/editor-styles";
@import "components/menu";
@import "components/section";
@import "components/hero";
@import "components/card";
@import "components/modal";
@import "components/carousel";
@import "layouts/tinymce";
```

---

## Post 6 by @djmtype — 2020-10-08T12:36:44Z

I assume you’ve tried the process of elimination? If you comment out all of your scss imports except the first, then run `yarn build` does it error out?

BTW, here’s my entire `postcss.config.js` config that’s working with Sage 9:

```
/* eslint-disable */

const cssnanoConfig = {
  preset: ['default', { discardComments: { removeAll: true } }]
};

module.exports = ({ file, options }) => {
  return {
    parser: options.enabled.optimize ? 'postcss-safe-parser' : undefined,
    plugins: {
      autoprefixer: true,
      cssnano: options.enabled.optimize ? cssnanoConfig : false,
      'postcss-inline-svg' : { removeFill: false },
    },
  };
};
```

My `package.json` for versions:

```
"devDependencies": {
    "autoprefixer": "~8.2.0",
    "browser-sync": "2.26.3",
    "browsersync-webpack-plugin": "^0.6.0",
    "bs-html-injector": "~3.0",
    "buble-loader": "^0.4.1",
    "cache-loader": "~1.2.5",
    "clean-webpack-plugin": "^0.1.18",
    "copy-globs-webpack-plugin": "^0.2.0",
    "css-loader": "^0.28.9",
    "cssnano": "~4.0.5",
    "eslint": "~4.19.1",
    "eslint-loader": "~1.9",
    "eslint-plugin-import": "~2.14.0",
    "extract-text-webpack-plugin": "~3.0.2",
    "file-loader": "^1.1.6",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "imagemin-mozjpeg": "~7.0.0",
    "imagemin-webpack-plugin": "~2.2.0",
    "import-glob": "~1.5",
    "node-sass": "~4.9.4",
    "postcss-loader": "~2.1.0",
    "postcss-safe-parser": "~3.0",
    "resolve-url-loader": "~2.3.1",
    "rimraf": "~2.6",
    "sass-loader": "~6.0",
    "style-loader": "^0.22.1",
    "stylelint": "^8.4.0",
    "stylelint-config-standard": "~18.2.0",
    "stylelint-webpack-plugin": "^0.10.5",
    "uglifyjs-webpack-plugin": "^1.3.0",
    "url-loader": "^0.6.2",
    "webpack": "~3.10.0",
    "webpack-assets-manifest": "^1.0.0",
    "webpack-dev-middleware": "~2.0.4",
    "webpack-hot-middleware": "~2.22.3",
    "webpack-merge": "~4.1.4",
    "yargs": "~11.0.0"
  },
  "dependencies": {
    "jquery": "^3.3.1",
    "postcss-custom-properties": "^9.1.1",
    "postcss-inline-svg": "^4.1.0",
  }
```

---

## Post 7 by @dangelion — 2020-10-08T13:27:28Z

I tried to commenting all `@imports` except the first `@import "utils/mixins";` and also commenting all the main.scss but I’ve the same error.

I checked your `postcss.config.js` but it’s the Sage default with the add of ‘`postcss-inline-svg`’. No trace of `postcss-custom-properties`… I’m confused, where you set it?

My `package.json`

```
"devDependencies": {
    "autoprefixer": "~8.2.0",
    "browser-sync": "~2.24.7",
    "browsersync-webpack-plugin": "^0.6.0",
    "bs-html-injector": "~3.0",
    "buble-loader": "^0.4.1",
    "cache-loader": "~1.2.5",
    "clean-webpack-plugin": "^0.1.18",
    "copy-globs-webpack-plugin": "^0.2.0",
    "css-loader": "^0.28.9",
    "cssnano": "~4.0.5",
    "eslint": "~4.19.1",
    "eslint-loader": "~1.9",
    "eslint-plugin-import": "~2.14.0",
    "extract-text-webpack-plugin": "~3.0.2",
    "file-loader": "^1.1.6",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "imagemin-mozjpeg": "~7.0.0",
    "imagemin-webpack-plugin": "~2.2.0",
    "import-glob": "~1.5",
    "node-sass": "~4.9.4",
    "postcss-custom-properties": "^10.0.0",
    "postcss-loader": "~2.1.0",
    "postcss-safe-parser": "~3.0",
    "resolve-url-loader": "^3.1.1",
    "rimraf": "~2.6",
    "sass-loader": "~6.0",
    "style-loader": "^0.22.1",
    "stylelint": "^8.4.0",
    "stylelint-config-standard": "~18.2.0",
    "stylelint-webpack-plugin": "^0.10.5",
    "uglifyjs-webpack-plugin": "^1.3.0",
    "url-loader": "^0.6.2",
    "webpack": "~3.10.0",
    "webpack-assets-manifest": "^1.0.0",
    "webpack-dev-middleware": "~2.0.4",
    "webpack-hot-middleware": "~2.22.3",
    "webpack-merge": "~4.1.4",
    "yargs": "~11.0.0"
  },
  "dependencies": {
    "bootstrap": "^4.5.2",
    "custom-event-polyfill": "^1.0.7",
    "jquery": "^3.3.1",
    "normalize.css": "^8.0.1",
    "popper.js": "^1.16.1",
    "rfs": "^9.0.3",
    "swiper": "^6.3.2"
  }
```

---

## Post 8 by @djmtype — 2020-10-08T15:49:40Z

I’m utilizing css custom properties and therefore don’t want postcss to pre-process them which is why I haven’t defined it.

With that said, when setting, `'postcss-custom-properties': { preserve: false, }` on `yarn start`, this will work, but naturally break any styles where variables (css custom properties) have been re-defined.

However, running with`'postcss-custom-properties': { preserve: false, }` on `yarn build:production` will absolutely fail and should fail if you have variables being re-defined.

You’ll end up getting a similar error:

```
error in ./resources/assets/styles/main.scss

Module build failed: ModuleBuildError: Module build failed: Syntax Error 

(1:1) Unknown word

> 1 | var(--s0)*var(--ratio)
    | ^
```

**Check you scss files for something like the following:**

```
// Example: 

:root {
--size: 20rem;
)

.some-selector {
--size: 12rem;
max-width: var(--size);
}
```

@dangelion You’re also using a different version for postcss-custom-properties among other modules, which is why I posted my package.json. They are not the same.

[https://www.diffchecker.com/9vDIuffh](https://www.diffchecker.com/9vDIuffh)

So if you’re still getting errors, try rolling back postcss-custom-properties to version 9.1.1 and see if that works.

---

## Post 9 by @dangelion — 2020-10-10T11:08:48Z

Yes, that was the version! From postcss-custom-properties v10 is required node 10 that I have not. Installed the v9.2.0 and worked!

Interesting what you’re saying before. Then if I understand you’re not actually using postcss-custom-properties but native custom properties. They’re not supported by IE, how you handle that?

I was thinking to use postcss-custom-properties with `{ preserve: true }` so it will keep custom properties but add a standard css fallback readable from IE. Am I right?

However trying so, I see the compiled fallbacks with nested calc() are invalid again on IE…

Anyway, I realized that this technique doesn’t handle a redraw via media query (ie. reassigning a variable).  
I mean:

```
:root {
  --color: red;
}

@media screen and (min-width: 992px) {
  :root {
    --color: blue;
  }
}

body { background: var(--color) }
```

And for many reason I can’t re-write the rule `body` inside the media query.  
What’s your advice on this?

---

## Post 10 by @djmtype — 2020-10-10T15:52:25Z

I’m mainly using postcss in my project so I can easily assign `fill` colors to my background SVG icons.

Progressive enhancement and accessibility are very valid points. If your site needs IE11 and older support, using custom properties or feature queries (`@supports`) won’t work. In our specific use case, fortunately, my project didn’t require it.

In the past I’ve also used a Sass mixin library ([https://github.com/malyw/css-vars](https://github.com/malyw/css-vars)) to address custom properties when/if my project was ready to drop support on older browsers. **So, this library did not automatically produce fallbacks to variables.**

But, it was possible to reassign your variables so long as you weren’t reassigning variables to other variables.

Instead of declaring your variables in the `:root`, you’d define them inside an `@include css-vars` statement. But, I haven’ tested this lately with Sage.

I thought I’d add a helpful Chromium plugin for checking appearance and behavior when modern features are not supported.

> **[keithclark/css-feature-toggle-devtools-extension](https://github.com/keithclark/css-feature-toggle-devtools-extension)**
>
> A devtools extension for toggling CSS features allowing developers to see how pages/apps render in browsers that don't support modern CSS features - keithclark/css-feature-toggle-devtools-exten...

---

## Post 11 by @djmtype — 2020-10-10T16:29:37Z

@dangelion ALSO, if you happen to set: `'postcss-custom-properties': { preserve: true, }`, it will also error out in production because it doesn’t know how to handle calculating variables with other variables.

For example, for handling vertical rhythm I had used the following approach. This was time-saving when testing because I only needed to concern myself with the ratio value. However, this will not compile when needing fallback values:

```
--ratio: 1.25;

	--s0: 1.0rem;
	--s1: calc(var(--s0) * var(--ratio));
	--s2: calc(var(--s1) * var(--ratio));
	--s3: calc(var(--s2) * var(--ratio));
	--s4: calc(var(--s3) * var(--ratio));
	--s5: calc(var(--s4) * var(--ratio));
	--s6: calc(var(--s5) * var(--ratio));
	--s-1: calc(var(--s0) / var(--ratio));
	--s-2: calc(var(--s-1) / var(--ratio));
	--s-3: calc(var(--s-2) / var(--ratio));
	--s-4: calc(var(--s-3) / var(--ratio));
	--s-5: calc(var(--s-4) / var(--ratio));
	--s-6: calc(var(--s-5) / var(--ratio));
```

---

## Post 12 by @dangelion — 2020-10-10T16:50:26Z

Thanks for your answers. Don’t know if css-vars is what I’m searching for…

Very useful this one! css-feature-toggle-devtools-extension

About the `{ preserve: true }`: strange, because I just tried it today (`yarn build:production`) and it worked perfectly. No errors. I use your same approach for typography and spacings.  
The only thing didn’t worked was the reassigning of variables inside media queries, as posted before. I was just thinking to keep this solution with just this compromise.
