-
Notifications
You must be signed in to change notification settings - Fork 77
Output preprocessed variables option #22
Comments
Also while testing this option, the |
After thinking about it again, I think the solution really shouldn't be preprocessing the passed variables option, but outputting the final computed custom properties, no matter if a variables option is passed or not. In other words: :root {
color: #aaa;
}
body {
color: var(--color);
} Preprocessing this should output the final css along with the computed custom properties, if an option is passed:
props.json {
"color": "#aaa"
} Not sure if it's doable with postcss? |
The plugin cannot return anything but just edit the CSS AST. For the optional --, just check this commit that have a test in it 0691784 |
I'm sorry but not quite sure what do you mean by this. Could you elaborate a bit?
I was running an older version of this plugin. Now it's working. Thanks for the heads up. |
I mean resolve var() in JS variables. Should be pretty easy.
|
OK, do you mean we should resolve the passed in variables option directly without looking at the actual css source code? This can fail if users do: variables option { "border-color": "var(color)" } css :root {
"color": "#aaa";
}
div {
border: 1px solid var(--border-color);
} Without the css source code, the passed variables option might be incomplete. I think the mutable option is a viable approach. What if we modify the var opts = {};
postcss()
.use(customProperties(opts))
.process(css);
opts.variables // computed values and then cssnext could use this property to output the result. I can starting working on a PR if you think this approach is good. |
This plugin works with 2 passes on the complete AST. If we try to resolve JS variables between the first resolution and the variables replacement, I think we should be good. Just here postcss-custom-properties/index.js Line 85 in 0691784
I am not a fan of mutability :) |
So after the JS variables are resolved, how do we output them? Are you saying we let cssnext operate directly on json files? variables.json { "--border-color": "var(--color)" } style.css :root {
"--color": "#aaa";
}
div {
border: 1px solid var(--border-color);
}
|
We are not in cssnext. This plugin will never handle file. I just pushed a modification that should make you happy ;) |
Closed by a5aa2bf |
OK. I see where our misunderstanding lies. The bug you fixed actually doesn't exist. {
"--border-color": "#aaa",
"--background-color": "var(--border-color)"
} Using this variables option works fine before your fix. Because at the second resolution, the js variable will be recursively resolved. My feature request was to output the resolved values of all custom properties. I created a commit at my branch. It currently only works with custom properties specified directly in the source code and whose values don't contain Let me know if you want such feature in cssnext. (And if I'm not wrong, this fix should be reverted.) |
I will see if what I did was stupid. var color = "#aaa"
var props = {
"--border-color": color,
"--background-color": "color(" + color + " alpha(0.2))"
} FYI Qix-/color#55 |
I need to use these variables in my app, for doing UI animations with web-animations for example: var startColor = variables["start-color"];
var endColor = variables["end-color"];
elem.animate([{
color: startColor
}, {
color: endColor
}], 3000); {
"--start-color": "#aaa",
"--end-color" : "color(var(--start-color) alpha(0.2))"
} a {
color: var(--start-color);
}
a:hover {
color: var(--end-color);
} The same custom properties will be used both in css and js. So I need the resolved value in order to make it work in most browsers. |
So what do you think? Could cssnext offer a list of resolved custom properties? |
As I said before, for me you can do that in JS first, without adding an extra step. In your case you could do var color = require("color")
var mainColor = color("#aaa")
module.exports = {
"start-color": mainColor.rgbString(),
"end-color" : mainColor.alpha(0.2).rgbString()
} cssnext is in javascript so everything that is implemented come from JS. You can use JS directly. |
Note: that what me and other people are doing. |
Thanks for showing me the tip. Didn't realize this. However, not super excited about this procedural approach. I'm worried the amount of boilerplate code it entails: var color = require("color")
var mainColor = color("#aaa")
var pageWidth = 960
var sidebarWidth = pageWidth / 2
module.exports = {
"start-color": mainColor.rgbString(),
"end-color" : mainColor.alpha(0.2).rgbString(),
"page-width": pageWidth + "px",
"sidebar-width": sidebarWidth + "px",
"search-width": sidebarWidth * 0.8 + "px"
} Comparing it with {
"start-color": "#aaa",
"end-color" : "color(var(--start-color) alpha(0.2))",
"page-width": "960px",
"sidebar-width": "calc(var(--page-width) / 2)",
"search-width": "calc(var(--sidebar-width) * 0.8)"
} I personally find the later less painful to write. But I understand if you don't want the extraction feature in cssnext, and I'm thinking about writing an separate project to provide this feature, but I'd still like to leverage this project to resolve variables. Will you accept an extra option where custom-properties are preserved but their values are replaced with resolved ones? |
If you do a correct PR with tests & docs, why not. This es6 code looks better to me, and more flexible: var color = require("color")
const mainColor = color("#aaa")
const pageWidth = 960
exports default {
"start-color": mainColor.rgbString(),
"end-color" : mainColor.alpha(0.2).rgbString(),
"page-width": `${pageWidth}px`,
"sidebar-width": `${pageWidth / 2}px`,
"search-width": `${pageWidth * 0.8}px`
} It's explicit. |
Will send a PR soon. |
Ideally this extra option should extends the existing
Since the feature I'm looking overlaps with the existing |
I think we can't accept such an option in this plugin since it's beyond its responsibility. |
That's the reason I implement the extraction feature in cssnext. From cssnext point of view, relying on plugins being chained is not hack, and the separate project will mostly copy cssnext, but using only postcss plugins that can affect css properties values. The feature I'm proposing to this plugin is that, comparing to the current preserve behavior: :root {
--width: 100px;
--height: var(--width);
}
/* compiles to */
:root {
--width: 100px;
--height: 100px;
--height: var(--width);
} It will do: :root {
--width: 100px;
--height: var(--width);
}
/* compiles to */
:root {
--width: 100px;
--height: 100px;
} That is, it will not leave the specified value. Instead, it replaces it with the resolved value. So at cssnext level, I can retrieve all custom properties without getting duplicate values. I don't think this proposal is a hack. It doesn't rely on other plugins. It simply removes the specified declaration without the conditional as the code base currently does. Hope that can change your mind. |
So what about a simple other option |
I'm incline towards the later, otherwise we need to make a decision if I was going to suggest "original", but in css spec, they use "specified". So I thought it might be nice to follow suit. Let me know if you insist. |
if specs say specified go for this preserve: true || "all" (current behavior) |
Cool. Glad we have an agreement. :) |
Should I start working from the 3.2.0 commit? |
Please just remove useless lines in the module BUT keep the tests to ensure we are not going back :) |
Writing it makes me realize what Are you ok with this option value? |
I think a better option name would be computed: "add" // add the computed value before the specified value |
The thing is you think about declaration. |
source :root {
--color: #aaa;
--bg-color: var(--color);
}
body {
background: var(--bg-color);
}
:root {
--color: #aaa;
--bg-color: #aaa;
--bg-color: var(--color);
}
body {
background: #aaa;
background: var(--bg-color);
}
:root {
--color: #aaa;
--bg-color: #aaa;
}
body {
background: #aaa;
}
body {
background: #aaa;
background: var(--bg-color);
}
body {
background: #aaa;
} I think What about we default |
I was thinking |
If we introduce an option only affects custom props definition:
:root {
--color: #aaa;
--bg-color: #aaa;
--bg-color: var(--color);
}
body {
background: #aaa;
background: var(--bg-color);
}
:root {
--color: #aaa;
--bg-color: #aaa;
}
body {
background: #aaa;
background: var(--bg-color);
}
OK. I was drunk. Do need a better name though. |
What about |
I just realized that at cssnext level, i'm actually able to dedup the custom properties definitions (when there are multiple custom properties definitions with the same name, use the last one doesn't contain But I also realized I need the same preserve feature from the custom media plugin (want to extract custom media queries also.) Will write a doc to clearly explain the problem and my plan of solving it. Sorry for all the noises I generated. |
Please check this out when you got the time. https://gist.github.com/hgl/77f0141eea04817ee0af I realized a problem the current Let me know what you think. :) |
With this variables option:
It would be great if cssnext could give back a variables option that have all values preprocessed:
Otherwise it's very hard to consume the values for other js code.
I wonder what might be the best way to output this option? Should it be handled at cssnext level or this plugin here?
The text was updated successfully, but these errors were encountered: