Giter VIP home page Giter VIP logo

css-vars-ponyfill's Introduction

css-vars-ponyfill

NPM GitHub Workflow Status (master) Codacy code quality Codacy branch coverage License: MIT jsDelivr Sponsor this project

A ponyfill that provides client-side support for CSS custom properties (aka "CSS variables") in legacy and modern browsers.

Features

  • Client-side transformation of CSS custom properties to static values
  • Live updates of runtime values in both modern and legacy browsers
  • Transforms <link>, <style>, and @import CSS
  • Transforms relative url() paths to absolute URLs
  • Supports chained and nested var() functions
  • Supports var() function fallback values
  • Supports web components / shadow DOM CSS
  • Watch mode auto-updates on <link> and <style> changes
  • UMD and ES6 module available
  • TypeScript definitions included
  • Lightweight (6k min+gzip) and dependency-free

Limitations

  • Custom property declaration support is limited to :root and :host rulesets
  • The use of var() is limited to property values (per W3C specification)
  • CSS changes made using CSSOM APIs are not supported (see #19, #23, #77, #154).

Browser Support

Chrome 19+
Edge 12+
Firefox 6+
IE 9+
Safari 6+

Usage & Options

See the documentation site for details.

Sponsorship

A sponsorship is more than just a way to show appreciation for the open-source authors and projects we rely on; it can be the spark that ignites the next big idea, the inspiration to create something new, and the motivation to share so that others may benefit.

If you benefit from this project, please consider lending your support and encouraging future efforts by becoming a sponsor.

Thank you! ๐Ÿ™๐Ÿป

Contact & Support

  • Follow ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป @jhildenbiddle on Twitter and GitHub for announcements
  • Create a ๐Ÿ’ฌ GitHub issue for bug reports, feature requests, or questions
  • Add a โญ๏ธ star on GitHub and ๐Ÿฆ tweet to promote the project
  • Become a ๐Ÿ’– sponsor to support the project and future efforts

License

This project is licensed under the MIT License. See the MIT LICENSE for details.

Copyright (c) John Hildenbiddle (@jhildenbiddle)

css-vars-ponyfill's People

Contributors

djaler avatar jhildenbiddle avatar nightgrey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

css-vars-ponyfill's Issues

IE11: Read/Update single variable

Hey!
I'm searching for a way on how to read/edit a single css-variable with JS.
I can't just reuse the cssVars function, as this would overwrite my other variables:
cssVars({ variables: { '--backgroundColor': value } });

Is there a way to make single updates or getting all current variables?
Thanks in advance :)

Speed issue with IE11 - suggested fix

Hi John,

When running on IE11 (11.492.16299.0) testers started seeing a "long running script" error on one of our Angular apps. On investigation, I found that Ponyfill was taking 60+ seconds to run on this app. After further investigation, I found the Ponyfill was taking seconds (from 10 to 60) on all our apps (in most cases unnoticed). All our apps use the same Angular core where almost all of our css is generated.

Reason:
Angular likes to group css where the properties are the same. In my case, I had over 1900 selectors for "margin-left:-2px;", for another app it was 1200. Ponyfill was struggling to cope with this amount of data and there was a noticeable lag when it hit these lines.

My solution:
I am not suggesting this is the best approach. But the speed increase was very noticeable (from 60 to under 1 second)

I pushed the "onlyVars" setting to the "rule" function. If this is true, then I also check the "declarations" to see if they have a 'var(--XX' defined. If yes, I go on as normal. Other wise i return an empty node object.

below is my added function which is called at the start of the rule function

function hasVars() {
        // Get declaration block in line
        // same as match but does not remove from cssText
        var nextDeclarations = matchPreserve(/{([^}]*)}/);
       
        // if we have a var then allow to continue
        if (nextDeclarations != undefined && nextDeclarations.indexOf('var(--') !== -1) {
            return true;
        } else {
            // else remove the string from the css file and return false to go to next line
            match(/([^}]*)}/);
            return false;
        }
    }

Problems together with angular6

Hi,

I want to use the ponyfill together with angular. Because it seems to be the only way, for using css variables together with the IE 11.

But sadly, it did not work and I'm not finding the problem.

We have the requirnment, to make our application themeable during runtime. So, we put a variable in our styles.css file.
:root { --headerBackgroundColor: '#444444' }

In the header component css file, we have something like

.mat-toolbar.mat-primary { background-color: var(--headerBackgroundColor); }

During init of the angular app, we call cssvars({..}) method.

But nothing hapens in the IE. On Chrome, Firefox and all modern browsers it worked. But on IE not. In the debug mode of IE I can see, that still background-color: var(--headerBackgroundColor); is set.

Have you any advice, what went wrong?

Best regards
Jochen

Ponyfill doesn't work with CSSStylesheet.insertRule

Hi,

I'm working on a project that use emotion-css library + CSS vars. Because we had to support IE11, I tried to use this ponyfill. All things were great until we did a production build and the ponyfill didn't work.

After some research I discovered that emotion library use insertRule API, which means that <style> tag is empty and the ponyfill has nothing to parse and replace.

There's someone with this issue? Any ideas?

Extra closing parenthesis when using RGBa(), HSLa() as fallback value

Hi,

This is how my vars look like:

--color-background-transparent-9: hsla(200, 20%, 25%, 0.9);
--color-background-tint: hsla(200, 15%, 90%, 1);

This is how I use them on an element:

background: var(--color-background-transparent-9, rgba(51, 68, 77, 0.9));
color: var(--color-background-tint, #e2e7e9);

This is how css-vars-ponyfill converts them:

background: hsla(200, 20%, 25%, 0.9));
color: hsla(197, 14%, 90%, 1);

Notice the extra closing parenthesis in the background property.

After a bit of investigation, it seems that the issue is the fallback value.
If I replace the rgba(51, 68, 77, 0.9) with #e2e7e9 it works.

Does anyone have this issue before? Do you may know any workaround?

Thanks in advance!
George

SCRIPT5: Access is Denied on IE10 and 11 when using file protocol

Hi,
I was testing your ponyfill on VirtualBox with IE10 and 11 and I've noticed, that if a website is opened using file protocol, the script won't work because of the "SCRIPT5: Access is denied" error.

My HTML has a very simple structure, the <head> tag content is:

<link rel="stylesheet" href="main.css">
<script src="css-vars-ponyfill/dist/css-vars-ponyfill.js"></script>
<script>cssVars()</script>

The script then creates XMLHttpRequest and tries to fetch it in line 68: xhr.open("GET" url), which in this case is xhr.open("GET", "main.css") and fails with the error above.

It seems that the problem concerns only file protocol. When I've served the same page via HTTP from my host, everything worked when opened with IE11 on the guest machine.

Extending support outside of :root

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?

cssVars not displaying on IE11 within embedded iframe

I have a react-application that loads a .NET controlled form.

The react application is a form for collecting user information, selecting of products, and making donations. This data is sent to the .NET form which is loaded within an iframe controlled by React.

Both the React Form and the .Net Form utilize CSS variables and this ponyfill. However, on IE11, the variables load perfectly only on the React application. They fail to load on the iframed-app.

I include css-vars-ponyfill on both applications. I know the ponyfill runs on the iframe because I added an onComplete function that writes a message to the iframe DOM, but the styles are not updated within the iframe.

Cannot read property 'length' of undefined

Trying to use it but only getting this error. Caused by: return r.declarations.length ;

Fixed it with

 if(r.declarations) {
     return r.declarations.length > 0 ;
} else {
     return false
}

Use of :root inside media queries

Does this ponyfill support the changing of a property declared on :root if it is changed with a media query?

E.g.

:root {
  --h1-color: green;
}
@media (max-width: 1024px) {
  :root {
    --h1-color: red;
  }
}

h1 {
  color: var(--h1-color);
}

I'd expect to see both values transformed so that the media query is applied to the h1 but with the new fixed value such as:

h1 {
  color: green;
}

@media (max-width: 1024px) {
  h1{
    color: red;
  }
}

Is this currently possible? I'd assume not, since ensuring the media queries are only applied to the correct elements is the tough part.

Typings for TypeScript

Hi John.

I have used your ponyfill with TypeScript and Angular. Works like charm although I had to add typing definitions to have it work. I know it is possible to include the definition file with the JS package somehow with package.json, would you consider adding it to the next release? Here's the file that I've made with all the proper types:
css-vars-ponyfill.d.ts

declare module 'css-vars-ponyfill' {
    export default function cssVars(css?: {
        include?: string;
        exclude?: string;
        fixNestedCalc?: boolean;
        onlyLegacy?: boolean;
        onlyVars?: boolean;
        preserve?: boolean;
        silent?: boolean;
        updateDOM?: boolean;
        updateURLs?: boolean;
        variables?: {[key: string]: string};
        onBeforeSend?(xhr: XMLHttpRequest, node: Node, url: string): void;
        onSuccess?(cssText: string, node: Node, url: string): void;
        onError?(message: string, node: Node, xhr: XMLHttpRequest, url: string): void;
        onWarning?(message: string): void;
        onComplete?(cssText: string, styleNode: HTMLStyleElement): void;
    }): void;
}

I'm not sure about how to add it so it would work, so I figured I could at least send you the file.

Stop watch job

Hey,

is it possible to stop the watch task once it has been started? In my app the user can apply new themes as he likes and we use the watch job to allow view encapsulation / component styles (the component styles are added on the fly as a style tag to the head when the component is rendered for the first time). So when we change the theme i currently have the problem that i can't change the variables or start a new task because the old one is still running.

Use in calc() ?

Can this polyfill also inject the variable values into a property with
a value that uses these properties with calc?

Example:

flex: calc(var(--img-width) / var(--img-height));

I also want to read CSS file and use variables in IE10.

Nice to meet you, Mr. jhildenbiddle
My name is Fujii Tsutomi.
Thank you for exposing a wonderful system.

May I ask a question?
โ— I also want to read CSS file and use variables in IE10.

โ–  Tested with the development tool of IE11.
ย I tested it with "Internet Explorer 10" and "Internet Explorer 11".

โ–  When reading an ICSS file , in "Internet Explorer 10"
'Access - Control - Allow - Origin ~~~~' will cause an error.

2018y05m19d_225917595

โ–  I This is my sample page. If you do not mind, can you confirm? (F 12)
https://testtesttest21.sakura.ne.jp/sample/testtest/

โ–  I The following is the log displayed on the console.

SEC 7120: The original https://testtesttest21.sakura.ne.jp is not found in the Access-Control-Allow-Origin header.
testtest
CSS XHR error: "undefined" undefined
ย [object HTMLLinkElement]
ย ย ย "CSS XHR error:" undefined "undefined
"
ย ย ย  </ link>
"

โ— If you have a good method, would you please tell me?

Above, thank you.

Override a css variable with the css-vars-ponyfill

Hi there, we're loving the ponyfill so far and are finding it super useful thus far. We're just running into one scenario, which is most likely an edge case, but one we'd like to account for and are hoping you might be able to advise on what might be possible.

Right now we're using the ponyfill as directed, defining our css variables in the :root selector, i.e.

:root {
  --button-bg-color: red;
}

We know trying to set the value of a css var anywhere else will be ignored by the polyfill ( but correctly processed by all browsers supporting css vars: anything but IE), i.e:

.my-special-button {
   --button-bg-color: blue
}

Given the two definitions above the goal would be to be able to do something along those lines:

<button></button> // this button is red on any browser
<button class="my-special-button"></button> // this button should be blue on any browser but right now will be red on IE because the value definition will be ignored

Would you have any recommendations on how we could manually set a var value on a specific HTML element through the ponyfill API?

Nested Calc Inside a Media Query

Similar to the issue "root: inside a media query", the fixNestedCalc option seems not working when a varible is used inside a media query.

:root {
	--calc3: calc(100vh * 0.01);
	--calc2: calc(2px + var(--calc3));
	--calc1: calc(var(--calc2) * 2);
}

@media (min-width: 0px) {
	h1 {
	  color: var(--h1-color);
	  margin-bottom: var(--calc1);
}

This will result in "margin-bottom: calc(calc(2px + calc(100vh * 0.01)) * 2);" even when fixNestedCalc is set to true. When you take out the media query enclosure, it wlll work as expected as you get "margin-bottom: calc((2px + (100vh * 0.01)) * 2);".

variable scanning

pls be more robust when it comes to variable detection. I had some declarations like
var( --myvariable)
and the space in fron was taken seriously (an appropriate warning was shown).

Thx!

A performance question

Hi, thank you for your code. in your docs you state:

The ponyfill will:

Get the <link>, <style>, and @import CSS
Parse the CSS and convert it to an abstract syntax tree
Transform CSS custom properties to static values
Transforms relative url() paths to absolute URLs
Convert the AST back to CSS
Append legacy-compatible CSS to the DOM

Question: will it do all those tasks even in modern browsers or, will it stop before?

issue on IE10

Got issue on IE10
ponyfill not working, but on IE11 work fine

PS after investigating, found that if load cssVars after 1 sec (in setTimeout) all work fine
therefore, i guess it related to onLoad event, that not fired may be in IE10 and sometimes in IE11
so, I simple wrap my invoke cssVars(..) into
document.addEventListener("DOMContentLoaded", function() { ... });
and now work perfectly

Transform CSS without applying/rendering it to the DOM at all

Is it possible to transform some CSS which I only have in memory without applying it to a style element in the DOM first?

Something like this:

const css = `
  :root {
    --main-color: blue;
  }

  .some-class {
    color: var(--main-color);
  }
`;

cssVars({
  include: css, // I guess, this is not working. Is there some alternate way?
  onlyLegacy: false,
  onComplete(cssText, styleNode, cssVariables) {
    // Apply the transformed cssText on my own...
  }
});

This is not happening on the server but on the client.

IE9 CORS check includes port In getURLS() -> urlArray.forEach()

First thanks for this wonderful piece of software. Please remove this if it isn't an issue or I am misunderstanding something.

When using IE11 in IE9 mode it compares the parse.host and location.host to determine if it is a CORS request. For some reason on IE9 the location.host includes the port number.

For example:

            var parser = document.createElement("a");
            parser.setAttribute("href", url);
            parser.href = String(parser.href);
            console.log("url:" + url);
            console.log("Parser.host: " + parser.host + " location.host: " + location.host);
            var isCrossDomain = parser.host !== location.host;
            var isIElte9 = document.all && !window.atob;
            console.log("parser.protocol: " + parser.protocol + " location.protocol: " + location.protocol);
            console.log("IsIElte9: " + isIElte9);
            isCrossDomain = false;

That will produce:
url:css/fonts.css
Parser.host: localhost:80 location.host: localhost
parser.protocol: http: location.protocol: http:
IsIElte9: true
url:js/2d_sim_case/EMR/VitalsDisplay/vitalsdisplay.css
Parser.host: localhost:80 location.host: localhost
parser.protocol: http: location.protocol: http:
IsIElte9: true

So they are on the same host but the inclusion of the port number is throwing off the IE9/CORS check and causing it to error out. I've manually changed the isCrossDomain to false afterwards and it runs my website/app perfectly. The difference in Port number occurs in IE 10,11 as well but not in Edge. I don't have firefox or chrome forced to doing the conversion so I don't know.

I think either filtering out that port number when IE9 would fix this.

Just a couple of Updates to make it clearer: Testing on a website, not just on a local xampp server it does the same thing, comparing a hostname with port number to one without.

Relative background URLs not adjusted

relative background-urls are not adjusted correctly when styles are inserted from css files inside subdirectories (urls are relative to the css files location).

Question - Support for CSS Keyframe Animations?

First, thanks for the ponyfill! We appreciate the effort put into this and has given us some hope of using modern CSS features in older browsers.

We are attempting to use this for a CSS keyframe animation, but it does not seem like the generated keyframe is being applied properly. It does look like css-vars-ponyfill is inserting the new values for variables as expected, but it seems as if it does not replace the keyframe with the updated values.

Our question is if there is something special we need to do for animations, or should this work as we would like?

Here is an example. This is the CSS we start with:

:root {
  --red: 123;
  --blue: 9;
  --green: 255;
}

@keyframes test {
  0% {
    box-shadow:0 -2.6em 0 0 rgba(var(--red), var(--green), var(--blue), 1);
  }

  100% {
    box-shadow:0 -2.6em 0 0 rgba(var(--green), var(--red), var(--blue), 1);
  }

When we run css-vars-ponyfill, we get the following style tag inserted:

<style id="css-vars-ponyfill">
/*__CSSVARSPONYFILL-1__*//*__CSSVARSPONYFILL-3__*//*__CSSVARSPONYFILL-5__*//*__CSSVARSPONYFILL-7__*//*__CSSVARSPONYFILL-9__*//*__CSSVARSPONYFILL-11__*//*__CSSVARSPONYFILL-13__*/@keyframes test{0%{box-shadow:0 -2.6em 0 0 rgba(27, 117, 187, 1);}100%{box-shadow:0 -2.6em 0 0 rgba(117, 27, 187, 1);}}
/*__CSSVARSPONYFILL-17__*//*__CSSVARSPONYFILL-19__*//*__CSSVARSPONYFILL-21__*//*__CSSVARSPONYFILL-23__*//*__CSSVARSPONYFILL-25__*//*__CSSVARSPONYFILL-27__*/
</style>

And when we perform an update on our code (--red is 123 and --green is 0 say) we get the following output:

<style id="css-vars-ponyfill">
/*__CSSVARSPONYFILL-1__*//*__CSSVARSPONYFILL-3__*//*__CSSVARSPONYFILL-5__*//*__CSSVARSPONYFILL-7__*//*__CSSVARSPONYFILL-9__*//*__CSSVARSPONYFILL-11__*//*__CSSVARSPONYFILL-13__*/@keyframes test{0%{box-shadow:0 -2.6em 0 0 rgba(123, 0, 0, 1);}100%{box-shadow:0 -2.6em 0 0 rgba(0, 123, 0, 1);}}
/*__CSSVARSPONYFILL-17__*//*__CSSVARSPONYFILL-19__*//*__CSSVARSPONYFILL-21__*//*__CSSVARSPONYFILL-23__*//*__CSSVARSPONYFILL-25__*//*__CSSVARSPONYFILL-27__*/
</style>

That seems correct to us, but it does not apply to the existing component as expected.

Getting started with css-vars-ponyfill

Hi there

I am working on an app that uses Custom CSS Properties and it needs to work in IE 11. I have had a look at this library but I can't really discern how to configure it properly.

Can you please give me some guidance? I have an Angular app and we are switching themes by using class selectors on :root body. The themes contain the variables. The code is working perfectly in Chrome et al, but doesn't work in IE 11. What are the steps to get the library to do its magic and fix my CSS? I know there is a lot of documentation around the cssVars() method, and I have looked at all the dependant projects; but I still can't get it working!

Please help a drowning developer!

I am using the following format for my variables:

$variables: (
  --box-shadow-color: var(--box-shadow-color),
  --page-background-color: var(--page-background-color),
}

and giving them these default values:

:root body {
  --box-shadow-color: rgba(0, 0, 0, 0.03);
  --page-background-color: #{$light-grey};
}

and then swapping them in and out by using classes:

:root body.theme-johnlewis {
  --box-shadow-color: rgba(0, 0, 0, 0.03);
  --page-background-color: #{$color-red};
}

Is this the right format to be using?

"Custom properties fallback values" support

Hi guys,

I have a user case where I need to use "Custom properties fallback values" on this way:

background-color: var(--my-var, var(--my-background)); /* --my-background if my-var is not defined */

On modern browsers is working fine but on IE11 does not work using this library.

Does someone know if the css-vars-ponyfill supports this feature? If doesn't, do you know some workaround?

HasNativeSupport not working in SSR

Hi!

I am using this lib in a project with SSR and when I run the app in the SSR I get the error that:

window is not defined

.
I would change the hasNativeSupport varibale in:

    const isBrowser = typeof window !== 'undefined';
    var hasNativeSupport = isBrowser && window && window.CSS && window.CSS.supports && window.CSS.supports("(--a: 0)");

What do you think?
Thanks!

Which latest stable version ?

Hello,

Thanks a lot for your work.
I was wondering wich latest version should I use, since 1.15.3 build is failing ?

Another thing, is there a way to polyfill variables declared and scoped to a class (so far it seems to work only inside :root if I got it) ?

Thank you!

Server side rendering support

Edit: Summarized everything in one message

Hi there.

I just began learning server side rendering and I tried to set up css-vars-ponyfill to do everything on the back before HTML is visible to user. I've managed to get it to work by passing a document DOM imitation as rootElement:

cssVars({
    rootElement: documentRef,
    onlyLegacy: false,
    include: `link[rel=stylesheet], style[${POLYFILL_MARK}], style[${THEME}]`,
    onlyVars: true,
    updateDOM: false,
    onComplete: cssText => {
        this.onPolyfillComplete(cssText);
    },
});

Where documentRef is like document, but in Node emulation. I use onlyLegacy: false because I check browser myself โ€” old Edge pretends to support CSS vars but does it very poorly so I ponyfill for it too. Also on the back CSS object does not exist so cssVars internal check would fail even on Chrome (in Server side rendering you have to determine browser from the user-agent sent in the HTTP request). POLYFILL_MARK and THEME are attributes that I mark <style> tags with if I need to process them, never mind that, just my particular implementation.

So I was getting an error: ERROR RangeError: Maximum call stack size exceeded.

Since documentRef is not really document but rather an imitation it is considered an Object by mergeDeep function inside css-vars-ponyfill. So it goes over everything inside it :) I've added early return to that function which solved the issue for me:

    if (Object.assign) {
        var args = new Array(arguments.length);
        for(var i = 0; i < args.length; ++i) {
            args[i] = arguments[i];
        }
        args.unshift({});

        return Object.assign.apply(this, args);
    }

Also had to make that document dummy pretend it's loaded, Domino (DOM in Node) sets readyState to "loading" by default.

With that I've managed to get it to work. Everything is ponyfilled before user gets it, so no flickering on IE, looks awesome. I know Object.assign is a shallow copy but from the options of the ponyfill it doesn't look like you need a deep merge, the only object is variables map which is a map and is only read and never written to. If you could make the change above to your ponyfill or maybe come up with another way to allow for DOM imitation to take place โ€” you could add Angular Universal / Server Side Rendering / Domino support to you library :)

You could also make a change to this line:
if (document.readyState !== "loading") {
to something like this:

// if document is an object โ€” we're in a backend DOM 
// imitation and we do not need to wait for page load
if (document.constructor === Object || document.readyState !== "loading") {

It would eliminate the need to pretend to be loaded.

What needs to be ponyfied ?

Hello,

I got one css file that contains all my variables on the :root scope (1575-257888.css).
I got only 1 other css (app.css) file that make use of those variables.

So If I want the best performance possible, do I need to include only the .css that contains the declaration of those variables ? Or only those 2 files listed above ?

Thanks you

Lifecycle methods (onSuccess, onComplete, onError) are not executed when modern browser is used

While working on #13 I stumbled upon the fact that the lifecycle method are not triggered. I sort of understand why this might be expected, because you won't have cssText available for example on completion, but I also found it somewhat confusing that it did not trigger anything and took me a while to realize what was happening.

I can think of three changes for this:

  • Trigger the actions in both cases. This gets complex quickly because css-vars-ponyfill won't have access to the DOM node modified or the parsed CSS in that case.
  • Log a message when a lifecycle method is specified in these cases. This will let the developer know that these will only be used in legacy browser mode and they should handle it.
  • Add a different lifecycle method for this case (onPropertiesSet) perhaps. This might be confusing to differentiate between onSuccess/onComplete, but it would be a more explicit hook that both modes can share.

Can't get ponyfill to work with app that loads theme

Hey!

Thanks for writing this - it's much, much appreciated.

We have an Angular app that loads a theme that looks like this:

typography: {
        body: {
            color: '#333',
            fontSize: '18px',
            fontWeight: 400,
            letterSpacing: '0',
            lineHeight: '1.5',

            margin: '0 0 10px 0',
            padding: '0',

            desktopLarge: {},
            desktop: {},
            tablet: {},
            mobile: {
            }
        },
        ...

Those nested objects are then translated to var strings such as --typography-body-font-weight and we use setStyle to assign their values. This is working for modern browsers but does not (obviously) work in IE.

The code we're using to do this stuff looks like this:

private setStyles(styles, variables: any) {
        Object.keys(styles)
            .forEach((key: string) => {
                const value = this.parseValue(styles[key], variables);

                this.themeWrapper
                    .style
                    .setProperty(this.parseKeyName(key), value);
            });

            cssVars({
                shadowDOM: true,
                onlyLegacy: false
            });
    }

And styles looks like:

--elements-accordion-content-padding: "20px"
--elements-accordion-group-margin-after-accordions: "20px"
--elements-accordion-icon-padding-top: "20px"

Thanks for your help @jhildenbiddle!

Parse error - missing "}" on IE11 and vue/vuetify

HI,

Am trying to use the ponyfill with vue/vuetify for IE11.

The code that im using is:
cssVars({ silent: false, // default, watch: true, onSuccess(cssText, node, url) { console.log("onSuccess1",arguments); }, onComplete(cssText, node, url) { console.log("onComplete",arguments); }, onWarning(message) { console.log("onWarning",arguments); // 1 }, onError(message, node, xhr, url) { console.log("onError", arguments); // 1 } });

and its been called on mount of my app. The app uses a url based css and also :root {...} which is created/injected by vuetify once it's been loaded.

What im getting (IE11) are the following events:

  • onSuccess - for the url based css
  • onError - missing "}" - it seems that here, the node that produced the err is the link with the very same href of the css.
  • onComplete - this one seems to have transformed css...

After that no transformed style is adding to the body, IE still displays incorrect styles.

Any suggestion?
thanks!

IE11 fails to render if I don't delay a certain amount before processing

Hey!

So I ran into a new thing, and I'm wondering if you have any ideas. I was seeing most elements completely unstyled, but a few were, so the lib was working as expected. I added a setTimeout with a delay of 2,500 ms and everything worked perfectly. Can you think of any reason why adding the delay would cause all elements to be styled? Does it potentially relate to the browser not having rendered the entire DOM yet?

Thank you!
Matt

Add the library only if the browser doens't support css-vars

Do you see any objection, in order to avoid loading the script, in doing this ?

<body>
    ....

    <script>
      <!-- Add ponyfill for css variables on legacy browsers -->
      function browserCanUseCssVariables() {
        return window.CSS && window.CSS.supports && window.CSS.supports('--fake-var', 0);
      }

      if (!browserCanUseCssVariables()) {
        var imported = document.createElement('script');
        imported.src = 'js/css-vars-ponyfill.min.js';
        document.head.appendChild(imported);
        cssVars();
      }
    </script>
</body>

Comments of the form /*__CSSVARSPONYFILL-XY__*/ are written into style tags

When working on Issue #13 it was noted that strange comment was left behind within the style tag. They look like this:

/*__CSSVARSPONYFILL-01__*//*__CSSVARSPONYFILL-03__*//*__CSSVARSPONYFILL-05__*/...
:root {
  --font: 25px;
}
...
/*__CSSVARSPONYFILL-07__*//*__CSSVARSPONYFILL-09__*//*__CSSVARSPONYFILL-11__*/

In other words, the strange comments are left within the style tag and wrap around the actual styles to be controlled via the ponyfill.

How to use css variable from CDN file in angular 6?

Hi @jhildenbiddle ,

I am trying to use this library in one of my angular 6 project, which is using CSS variable from a file coming from CDN (due to theme implementation, I can switch theme/files dynamically).

But I am getting CORS issue on IE, and warning on chrome/other browsers regarding undefined variable (I will set onlyLegacy to true though).

Can you please help me, in loading file from CDN on angular 6 project.

Please see attached snapshot.
image

Thanks.

Usage with React and/or CSS in JS

Very cool work here @jhildenbiddle thanks for this project.

I would like to open the conversation about using the ponyfill on a React app with CSS-in-JS, to see if people have any suggestions on the best approach to apply it globally.

So far I've tried it at the root of my App, but it's not picking up children updates. Then I tried to run the ponyfill after listening for changes with the MutationObserver but that seems to be very expensive, to the point of freezing the DOM.

Supporting CSSOM APIs?

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.

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.