Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending support outside of :root #26

Closed
brettdusek opened this issue Sep 28, 2018 · 1 comment
Closed

Extending support outside of :root #26

brettdusek opened this issue Sep 28, 2018 · 1 comment

Comments

@brettdusek
Copy link

brettdusek commented Sep 28, 2018

Great ponyfill here. It's allowed us to deliver some of these features for IE11, with theming being handled by CSS variables.

I know there are some challenges around supporting values being set anywhere else besides :root, but I wanted to show a good example of why that might be valuable.

Scenario:
A button exists in a card component and the theme calls for those buttons to be a different color from all others.

:root {
--button-background: royalblue;
--button-color: white;
--card-background: royalblue;
--card-color: white;
}
.card {
background: var(--card-background);
color: var(--card-color);
}
.button {
background: var(--button-background);
color: var(--card-color);
}

<div class="card">
<p>Some random text</p>
<div class="button">I'm a button</div>
</div>

Obviously, we could add a new class to the button and create all new variables for this scenario. However, this defeats the value of CSS variables to some degree. In modern browsers, we'd just set --button-background to be different in .card and avoid a lot of extra work:

.card {
--button-background: white;
--button-color: royalblue;
}

This would leave all other buttons alone, while dealing with the special case in .card and avoids needing the new class or context. Unfortunately, the lack of support to do this causes a really elegant solution to become one needing a lot of bloat.. and we are back to square one. If this ponyfill handled the setting of variables in any other selector.. this would be a substantial improvement.

I'd be more than happy to help in any way I can, but I'm not sure what limitations you're dealing with for this particular issue. Anything you might be able to add about it?

@jhildenbiddle
Copy link
Owner

jhildenbiddle commented Sep 29, 2018

Happy to hear the ponyfill has been useful!

As for extending the ponyfill to handle custom properties outside of :root, you'll get no argument from me that it would be valuable.

The idea of handling custom properties outside of :root was discussed in #5 and #12. In my replies I stated that creating a spec-compliant poly/ponyfill simply wasn't possible and shared the following links to help explain:

After replying I realized that my "not possible" statement is not necessarily true and that css-vars-ponyfill may be uniquely positioned to do so (more on that below). There are two major hurdles: complexity and performance.

The issue others have run into while trying to do what you are asking is that generating legacy-compatible CSS cannot be done by analyzing the CSS alone. Respecting the cascade with scoped custom properties requires access to the DOM which is something CSS pre-processors (like PostCSS) obviously do not have. This ponyfill does have access to the DOM since it runs on the client, so in theory it should be possible.

Back to the hurdles...

Supporting scoped custom property values and generating legacy-compatible CSS that respects the cascade would significantly increase the complexity of the ponyfill and would be very expensive computationally. That expensive computation isn't a one-time hit, either. It needs to be done every time certain mutations occur (node insert, node remove, class change, ID change, etc.) because DOM changes could potentially change the CSS generated by the ponyfill. Even if a spec-compliant poly/ponyfill was possible (which would be a significant amount of work to develop and test), it's a safe bet that performance would not be suitable for production. @kaelig summed it up nicely in a thread related to the same topic for a different project: reworkcss/rework-vars#15 (comment)

... I know you know it already, but re-working complex low-level language constructs on top of the same syntax is a tricky game to play and you'll have this type of problem again and again along the way.

All that being said, if someone wanted to take a crack at a spec-compliant ponyfill I'd be happy to help however I can. At this point, it's just not something I'm interested in driving based to the concerns outlined above.

Thanks for the feedback, @brettdusek. Very much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants