Closed hteumeuleu closed 9 years ago
This issue has already been discussed on rework-vars and (for now) limitation is explained here https://github.com/reworkcss/rework-vars#what-to-expect
Ah, ok, merci. Maybe the main site "marketing" speech should be changed then. Because this is clearly not like a CSS polyfill then, and it's quite misleading.
Bummer, variable inheritance was one of the things I was personally really looking forward to after having read the W3 spec :confused:
We are using dynamic variables syntax to create a classic (preprocessed) variable implementation but we can't handle that since we can't guess the dom tree, so we can make relevant results. That's why rework-vars is limited to :root definition.
That being said, I guess we can make this clear. I'll try to make this clear on the doc & on the website.
The best we can probably do is to handle https://github.com/segmentio/myth/issues/58
@MoOx I'm trying to understand your explanation by constructing cases:
Change css file provided by @hteumeuleu to:
:root {
--large:10px;
}
.sidebar {
--large:20px;
}
div .block {
padding:var(--large);
}
According to the specification, the output should be (all cases should be covered since we cannot guess the dom):
.block {
padding:10px;
}
div.sidebar .block {
padding:20px;
}
.sidebar div .block {
padding:20px;
}
div .sidebar .block {
padding:20px;
}
Since rules in real world css are much more complex, the generated css file will be quickly bloated.
However,
scoped variables are really nice... So, how about partial support? For example, we can interpret the scope as the topmost selector, which means the output of the changed example will be:
.block {
padding:10px;
}
.sidebar div .block {
padding:20px;
}
This still doesn't work for the original html (the original css works, though), but at least we can hack it:
<div class="block">
Root Block
</div>
<div class="sidebar">
<div>
<div class="block">
Sidebar Block
</div>
</div>
</div>
It may seem confusing at first, but it may not be that bad since the working scenario is a subset of the working scenario promised by the specification. (So after the specifications being implemented in browsers what worked will still work)
Partial support is too dangerous. Any serious project won't do that. You can also checkout https://github.com/postcss/postcss-custom-properties/issues/1 & https://github.com/postcss/postcss-custom-properties/issues/9 to understand why it should not be done. I've tried to do that for cssnext (in the postcss plugin linked above) but it's not a game I want to play anymore.
This issue should be closed but since I'm involved in another project I'll let the owners do that :)
@MoOx Thanks for your links. Now I found what's wrong with my suggestion... The key problem is, when resolving scoped variables distances between DOM elements are critical, but it's totally unexpressible due to it's not a criteria of cascading rules.
It brings some critical problems. Suppose we have a variable x with two scoped assignments:
.a {
--x: 0;
}
.b {
--x: 1;
}
Then our luck depends on the rule which uses the variable, if it’s something biased like
p.a {
<any property>: val(--x);
}
then we are lucky since it can be interpreted as a single rule:
p.a {
<any property>: 0;
}
However, if there’s something more general, like this simple input rule:
p {
<any property>: val(--x);
}
then we are in trouble. Following will proved that we cannot use finite output rules to cover all the DOM cases:
We can find DOM hierarchy which match R as well match S, also due to symmetry. we sign the DOMs without the last element p as D and E. So we get:
R(Dp) = 0, S(Ep) = 1
According to 1, we know that Dp ~ 0, Ep ~ 1
, where ~
means “scoped evaluate to”.
EDp
*, then R(EDp) = 0
and S(EDp) = 1
. According to 1, R and S are strongest and have the same strength, so here we cannot determine whether x in EDp should be evaluated to 0 or 1, while, though, it’s obvious that EDp ~ 0
!Seems a more formal proof is possible, but it’s already sufficient to say it’s impossible to implement such a functionality (even partially as I suggested). Really a pity… Maybe the approach taken by uncss is the only real way to go as you suggested before. The only possible “partial” implementation seems to restrict the scope to 0 or 1 levels, but that seems a bit too rough.
* Strictly speaking, EDp is not always legal, but at least it's legal for a DOM consist of only div.
Closing since it's out of scope for Myth for now.
Current version 1.0.3 doesn't support CSS variables inheritance. So if we take the following HTML and CSS code :
The expected output should be something like this :
This way we respect CSS inheritance, but this may create other issues as it creates more specificity.