Giter VIP home page Giter VIP logo

Comments (15)

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

Hi @snakevalley.

Sounds like cssVars() is being called before styles have been injected.

I put together a quick demo showing the ponyfill working with Angular:

The CSS generated by the ponyfill is displayed in the console.

Note that I've set include: 'style' to reduce the noise (otherwise the ponyfill will process <link> CSS as well). I have also set onlyLegacy: false to force the ponyfill to work in modern browsers for the purpose of the demo.

Hope this helps. If not, let me know and we'll continue to troubleshoot.

from css-vars-ponyfill.

snakevalley avatar snakevalley commented on May 18, 2024

Hi,

Yep... that was the problem. Thanks for the advice.

We try to ensure, that cssVars() is called after all css stuff is injected.

We use code-splitting to speed up the initial load of the whole application. That means, that we have to call cssVars() again, after another junk was loaded.

Is there a way, that the ponyfill will notice changes to the style attributes in the header?

Btw: Great ponyfill! It helps us a lot for supporting the microsoft hell. Thanks a lot for this!

Regards
Jochen

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

See options.watch.

Good to hear the ponyfill is working well for you!

from css-vars-ponyfill.

snakevalley avatar snakevalley commented on May 18, 2024

we tried this already and it seems to work in Chrome and Firefox. But on IE11, the results are not deterministic.

On our root component we do this in ngOnInt

private applyDefaultTheme() { cssVars({ variables: new DefaultTheme(), watch: true }); this.backend.loadTheme().subscribe(theme => { cssVars({ variables: theme, watch: true }); }); }

There we set the default theme and we start loading a dynamic theme from the server. The server theme must not be complete. So it can overwrite just a part of the default theme.

With watch enabled, the default theme is present and the dynamic loading has no effect at the end. But only on IE 11.

Regards
Jochen

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

Interesting.

I'm not familiar with Angular so I can't comment on the specifics, but the implementation above does not look like it is aligned with how the watch option is currently implemented in the ponyfill.

The watch implementation is intended to be set once, observe the DOM for <style> and <link> mutations, then call the ponyfill automatically when an appropriate <style> and <link> mutation is detected. There's no need to call cssVar() with watch multiple times (the option is ignored if watch was previously set) and the only time custom variables can be passed to the ponyfill using options.variables is the first time it is called with the watch option.

Assuming Angular is just injecting <style> and/or <link> elements, you should be able to call cssVars({ watch: true }) even before ngOnInt to create the MutationObserver, then just let the ponyfill handle the injected <style> and/or <link> elements mutations automatically.

I've updated the demo with the changes described above:

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

Hey @snakevalley.

Let me know if the above works for you. If so, I'll close the issue. Thx!

from css-vars-ponyfill.

snakevalley avatar snakevalley commented on May 18, 2024

Hi,

sorry, we have a deadline today. Because of that, I had not the time in the last 2 days.

Tomorrow I planned to do the test for it. I hope it is ok, to let the issue open until tomorrow.

Regards
Jochen

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

Of course! No rush. 😃

from css-vars-ponyfill.

snakevalley avatar snakevalley commented on May 18, 2024

Hi,

yep, seems to work. The trick is, to call it only once. So we have to change a little bit the process. Currently, we set the default thema at the beginning and load a partial theme and inject that later.

So, if the theme just overwrites one property, only that is changed and the rest stays default. That works in modern browsers very well. But in IE it seems to be a problem. But we can change the backend, that always a full theme is generated.

Thanks for the adivce.

Regards
Jochen

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

@snakevalley

FWIW, the ponyfill remembers all previous variables passed to it when updateDOM is true. This means you can call the ponyfil once with lots of variables, then again with just a single variable to update. You don't have to pass all variables every time the ponyfill is called.

For example:

// 1st call
cssVars({
  updateDOM: true, // default
  variables: {
    'my-color1': 'red',
    'my-color2': 'green',
    'my-color3': 'blue'
  }
});

// 2nd call
cssVars({
  updateDOM: true, // default
  variables: {
    'my-color3': 'purple',
    'my-color4': 'orange'
  }
});

This would result in the following CSS custom properties values being applied:

--my-color1: red;
--my-color2: green;
--my-color3: purple;
--my-color4: orange;

Doing this may be preferable given how you've described your system works, but it means manually calling the ponyfill at the appropriate time instead of using the watch option.

from css-vars-ponyfill.

waterplea avatar waterplea commented on May 18, 2024

Hey @snakevalley, this is how I use polyfill with my Angular app and it seems to work great:

  1. I have created an abstract class for theme switching and it marks its STYLE tag with an attribute, so I could later target it specifically with cssVars.
  2. I have set up my own MutationObserver to monitor styles, in its callback I mark STYLE tags that contain css vars usage with an attribute.
  3. Then I call cssVars for those new STYLE tags with variables and for my theme STYLE tag.
  4. Whenever a new theme STYLE tag appears or old one gets removed — I rerun cssVars for every STYLE tag that had variables usage, not just the new ones, so it could recalculate everything.

This way it works fine in IE and allows all sorts of dynamic theme switching and components generation. At that time cssVars didn't have watch option, but since this works fine for me and looks optimized I left it like that. Might want to switch to watch of course since less logic in my app is better.

@jhildenbiddle does watch option ignore old STYLE tags it already went through if no new variable declarations appeared in mutation/no old variable declarations were removed? I'm pretty sure it skips tags without variables so this optimization is the only one I really hold on to in my method. My themes can be switched off which removes STYLE tag from HEAD so app falls back to original theme/previously enabled theme.

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

@waterplea --

The ponyfill does not presume it is safe to skip any previously processed <link> or <style> nodes because the CSS content of those elements may have changed.

You are correct about the internal optimization that allows the ponyfill to skip processing of blocks of CSS that do not contain CSS custom property declarations (e.g. --color: red;) or functions (e.g. var(--color)) but, to be clear, the content of these blocks will still be included in the final output when onlyVars is false (which is the default). In other words, it's an internal optimization to avoid doing unnecessary work, not a "feature" that affects the ponyfill-generated CSS output.

from css-vars-ponyfill.

waterplea avatar waterplea commented on May 18, 2024

I know, I use onlyVars and try to organize my styles in a way it wouldn't matter :)

How about adding a flag immutable to enable ponyfill skipping previously processed nodes? It would mean that style can only be added or removed in whole nodes so ponyfill would process:

  1. only new nodes if just variable usage was added and all nodes that had declarations before
  2. if any node with declarations was added/removed — it would redo all nodes with vars

Maybe I'm too used to Angular mindset but it sounds strange for me to alter contents of STYLE tags in runtime :)

from css-vars-ponyfill.

sheikalthaf avatar sheikalthaf commented on May 18, 2024

@waterplea Hi,

will you please create a small demo in stackblitz which will help the angular develpers how to use this ponyfill in proper way. i tried this ponyfill but it seems i have not understood correctly.

@jhildenbiddle if i enable the watch.true IE browser hangs.

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on May 18, 2024

@sheikalthaf -- see this comment.

from css-vars-ponyfill.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.