Closed jednano closed 9 years ago
Let’s collect opinions. Anyway I have no free time until September 18.
@jonathantneal what do you think as owner of PreCSS?
I would be more than happy to do the work. I'm just formalizing the issue here.
In one case I afraid for more complexity.
But in other your logic seems like more clear, because it is common variables behaviour.
{}
creating closure, e.g. you can reference and modify ancestor variables, but new variables are scoped. This might be paired well with a !global
flag, similar to !default
(not sure if you have that one either).In postcss-advanced-variables, the getter/setter does a lookup
I did this in a generic way.
@jonathantneal !global
is too complicated (you know my vision of preprocessing). At least, JS developers live without it.
Maybe we should be closer to JS and looks where var was defined?
$a: 1;
a {
$a: 2;
$b: 3;
}
// $a is 2, $b throws undefined error
@ai the difference between JS and CSS here is that there is no var
statement; thus, no way to differentiate between whether the user wants to change the value of the global var or define a new, local var. Consider the following JS:
var x = 5;
function foo() {
var x = 7;
return x;
}
foo(); // returns 7
x; // 5
Notice that the global var, x
, is unchanged. Also, in CSS, there's no way to pass-in args with the same name, like JS does:
var x = 5;
function foo(x) {
return x;
}
foo(7); // returns 7
x; // 5
Nonetheless, in both cases, JS preserves the value of the global var. As such, I think we would be more wise to assume every $x: [someValue]
statement in CSS is a new var
statement of sorts and NOT assume that the user wants to modify the global var unless they are in global scope. This could prevent some nasty bugs from happening in the future, where a new file is introduced that changes the global var, unintentially, and breaks other pages that relied on that global var to be constant.
This is the default behavior I'm requesting. If we want to allow people to modify global values inside nested container scopes, perhaps that should be a separate option. Personally, I would never enable that option, but others might.
Also, it's much easier to implement if we just look in the current container and bubble up to find a value. If we do it the other way, it becomes much more complex.
@jedmao I thought about Ruby, Python and any other languages without var
too.
@ai are you confirming that Python works exactly the same as the JS examples I posted above? Because it does (just tested it). Not sure about Ruby though.
Python example 1:
>>> x = 5
>>> def foo(x):
... return x
...
>>> x
5
>>> foo(7)
7
>>> x
5
Python example 2:
>>> x = 5
>>> def foo():
... x = 7
... return x
...
>>> foo()
7
>>> x
5
But it do not work so in if
and for
?
I don't understand how a CSS rule would at all be compared to a control statement (e.g., if
and for
). I see each container as more of a function scope.
Do you think it would make sense to introduce $root.foo: 7
or $global.foo: 7
in the case that the user intends to change the root value? It seems this would be easier for a user to specify than some sort of weird $local.foo
variable.
This also ensures the most stable and reliable way is the default way and if you really want to modify the global var, you can do so explicitly.
It seems the functionality I was looking for is too major a change and perhaps out of scope to this plugin; thus, I created a new plugin for this purpose, postcss-nested-vars
.
As I understand it, this plugin sets global vars, but what if I wanted to limit the scope of vars to the container in which they were defined and only up the stack from there? I'm imagining an option like
scoped: true
that would work like so: