postcss / postcss-custom-properties

Use Custom Properties in CSS
https://postcss.github.io/postcss-custom-properties
MIT License
597 stars 77 forks source link

root variables not updated #148

Closed 2beers closed 5 years ago

2beers commented 5 years ago

"postcss": "7.0.5", "postcss-custom-properties": "8.0.8"

This used to work. I have the following css

:root {
    --first-color: red;
}
#box {
    background-color: var(--first-color);
    border-radius: 5px;
    width: 100%;
    height: 40px;
    cursor: pointer;
}
customProperties({
                    importFrom: [
                        {
                            customProperties: {
                               "--first-color": "green"
                           }
                        }
                    ],
                    preserve: false
                })

returns #box{background-color:red; the color is not changed to green as expected.

However if I remove

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

from css file, the color is changed as expected (green). Did something changed and I need to add some option or is this a bug?

pascalduez commented 5 years ago

Personally I would expect the CSS defined custom properties to take precedence over the JS defined ones (current behavior).

2beers commented 5 years ago

Thanks @pascalduez . Is there an option to overwrite css defined with js defined? We have a system where designer builds the css with some predefined colors (in css) and users can change those colors from some input fields.

jonathantneal commented 5 years ago

The current behavior would match the real css cascade.

@2beers, in your case, could you do something like this?

:root {
  --system-primary-color: blue;
  --primary-color: var(--user-primary-color, var(--system-primary-color));
}

body {
  background-color: var(--primary-color);
}

That is valid CSS that would work without any JS. With your system in place targeting --user-primary-color, the user color would win.

2beers commented 5 years ago

@jonathantneal thanks for the example. Just tested. If the user doesn't set any color(no variable input from js) the returned css is #box{background-color:var(--system-primary-color)} I expected #box{background-color:blue} since blue is --system-primary-color: blue;

If user sets a color then your example is working accordingly.

that1matt commented 5 years ago

I am having a similar issue with global theming in a library like react-toolbox. Supplying the same variable names through importFrom doesn't override the library colors.

I have tried to find a way to pass in the variables, even disabling custom-properties and chaining in another css-variables plugin without success.

I would think that supplying a file at the end of the importFrom would take precedent over the colors defined above.

I looked and wasn't able to find a solution with either passing a flag to make the variables supplied to custom-properties in preset-env to use the new defined variables. Or passing in a variables key as in a prior version.

Any thoughts or solutions?

that1matt commented 5 years ago

I think there is a better way to solve this, but I was thinking maybe something like this that would follow the old variables key. You can see my attempt here.

jonathantneal commented 5 years ago

At this time, I’d like to not consider building this feature myself, but I would consider a PR that I could test and see the implementation of.