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

Supporting CSSOM APIs? #23

Closed
madeleineostoja opened this issue Sep 11, 2018 · 3 comments
Closed

Supporting CSSOM APIs? #23

madeleineostoja opened this issue Sep 11, 2018 · 3 comments

Comments

@madeleineostoja
Copy link
Contributor

This is a long shot, but any ideas on how we could support shimming CSS vars for rules inserted via the CSSOM APIs?

I'm using styled-jsx which uses CSSOM to optimise runtime style updates, which vars-ponyfill obviously can't pick up on.

If you had a ref to the CSSStyleSheet object suppose it'd be doable enough, but don't know of any way to iterate over all CSSStyleSheet objects efficiently.

@jhildenbiddle
Copy link
Owner

Won't work. See #19:

Legacy browsers don't understand CSS custom properties. When a rule is inserted that contains either a custom property declaration or var() function, that declaration or function is dropped from the CSSRule.cssText value. For example:

// Insert two rules into an empty stylesheet (like emotions.js)
styleElm.sheet.insertRule(':root { --color: red; }', 0); // 1
styleElm.sheet.insertRule('p { color: var(--color); }', 0); // 2

// Modern browser CSSRuleList
// 1: ':root { --color: red; }'
// 2: 'p { color: var(--color); }'

// Legacy browser CSSRuleList (e.g. IE)
// 1: ':root {  }'
// 2: 'p {  }'

All is not lost, however. As I mentioned in #19, a solution may already exist or could be added to the the library responsible for injecting CSS.

  • I'm not familiar with styled-jsx, but it looks CSSOM APIs are only used when optimizeForSpeed is true (which is the default setting in production mode). Try setting this option to false and see if the ponyfill works as expected.
  • Based on CSSOM throws an error when a rule is not supported vercel/styled-jsx#295 it appears that styled-jsx already falls back to inserting CSS using <style> tags instead of CSSOM APIs when certain CSS rules are detected. This logic could be extended to include CSS custom property declarations (e.g. --mycolor: red;) and var() function values.

If either of the two options above work as expected, the ponyfill should work without modification.

@madeleineostoja
Copy link
Contributor Author

Bah humbug. Figured as much.

Yeah for my particular use-case disabling the CSSOM APIs fixes the bug, but comes with with unpalatable perf consequences for every other browser that does support custom props. Looks like I'm dropping styled-jsx.

Aside: maybe could add a note about this to the 'Limitations' section of the Readme?

@jhildenbiddle
Copy link
Owner

That's a bummer.

It may be worth creating an issue in the styled-jsx repo. The current behavior will break any lib that needs to parse CSS unsupported by the current browser because the unsupported CSS will be dropped when added via insertRule().

Perhaps a client-side switch could be added (or exposed, if it already exists) that determines which insertion method is used for each style block. For example, an attribute could be added to the <style jsx> tag that determines whether that block is inserted using a <style> tag or via CSSOM APIs:

// Global style via appended <style> node
<style jsx global optimizeForSpeed=false>{`
  :root { 
    --mycolor: red;
  }
`}</style>

// Scoped style via appended <style> node
<style jsx optimizeForSpeed=false>{`
  p { 
    color: var(--mycolor);
  }
`}</style>

The attribute could also accept a regular expression or function reference used to evaluate the style block content and set the value based on the result.

Good luck!

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