question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Grab value of CSS Variable in IE10

See original GitHub issue

I’m working on a light/dark theme and am trying to grab the background color to decide whether to set font color black or white. The following “getPropertyValue” (to grab the background color) isn’t working on IE10 because of the CSS Variable.

getComputedStyle(document.documentElement).getPropertyValue('--primary-color')

After I get that, would the “onSuccess” callback function be the correct place to run functions and update the color?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
jhildenbiddlecommented, Sep 30, 2019

@randyrandy123

If you are setting a CSS property using a variable (e.g. --testing-color), then you must use the ponyfill to transform that variable to a static value to 1) have that value applied in legacy browsers, which will allow you to 2) detect the value using getPropertyValue().

For example:

:root {
  --testing-color: green;
}
        
.testing {
  background-color: red;
  background-color: var(--testing-color);
}
var testElm = document.querySelector('.testing');
var bgColor = window.getComputedStyle(testElm).getPropertyValue('background-color');

console.log(bgColor); // rgb(255, 0, 0)

When the above code is executed in IE without the ponyfill, bgColor will be rgb(255, 0, 0). This is because 1) browsers return color values as their RGB equivalent, and 2) IE doesn’t understand CSS custom properties so it ignores the background-color: var(--testing-color); declaration.

When the ponyfill is used, the CSS custom property declaration is transformed to a static value which IE understands:

.testing {
  background-color: red;
  background-color: green; /* Transformed by ponyfill */
}

The value of bgColor is now rgb(0, 128, 0) as expected:

cssVars({
  onComplete: function(cssText, styleElms, cssVariables, benchmark) {
    var testElm = document.querySelector('.testing');
    var bgColor = window.getComputedStyle(testElm).getPropertyValue('background-color');

    console.log(bgColor); // rgb(0, 128, 0)    
  }
});

Note that the color test is done within the onComplete callback. This is because the ponyfill works asynchronously when processing <link> and @import stylesheets. Using the callback ensures your code is executed after the ponyfill has completed.

A few other things to keep in mind:

  1. You can update custom property values for both modern and legacy browsers using options.variables. This works regardless of the options.onlyLegacy setting. In legacy browsers, values will be applied during the transformation process outlined above. In modern browsers, values are applied instantly and synchronously using the native setProperty() method.
  2. Ponyfill callbacks only execute in legacy browsers by default (when options.onlyLegacy is true). You can force callbacks to fire in modern browsers as well by setting options.onlyLegacy to false, but doing so will introduce the same processing delay you’re seeing in IE in modern browsers because the ponyfill is treating all browsers like a legacy browser.

In order to update a CSS custom property value using the ponyfill then execute some code based on the new value in both legacy and modern browsers you would do something like this:

var hasCSSVarSupport = typeof window !== 'undefined' && window.CSS && window.CSS.supports && window.CSS.supports('(--a: 0)');
var testColor = 'green';

function doSomething(color) {
  console.log(bgColor);
}

cssVars({
  onlyLegacy: true,
  variables: {
    'test-color': testColor
  },
  // Legacy browsers
  onComplete: function(cssText, styleElms, cssVariables, benchmark) {
    doSomething(testColor);
  }
});

// Modern browsers
if (hasCSSVarSupport) {
  doSomething(testColor);
}

Regarding the ponyfill speed, keep in mind that the less CSS the ponyfill has to process the faster it will be. The ponyfill’s CSS transformation happens quickly, but the delay you’re seeing is caused by two things: 1) the amount of time it takes to retrieve external stylesheets (<link> and @import) via AJAX so they can be parsed, and 2) the time it takes for the browser to apply newly transformed styles to DOM elements. This often happens when apps load large frameworks (Bootstrap, Foundation, etc.) via CDN. You can avoid processing stylesheets using either options.include and/or options.exclude, and doing so can have a significant impact on performance.

Hope this helps!

1reaction
randyrandy123commented, Sep 30, 2019

Thanks for your detailed reply! I’m using the onComplete callback to dynamically change the value of the CSS and it’s working fine.

I was able to lower the 10 second delay down to <1 second by moving the CSS variables outside of the huge CSS file into a separate one. Below is what I did in case anyone is curious.

Previously I had 2 stylesheets – • 1. Compiled CSS for the whole app (this also held CSS Variables for themeing). 32k+ lines. • 2. “Theme stylesheet” – This pulled the CSS Variables declarations/styles from the stylesheet above.

I tried using those 2 stylesheets and added exclude: [data-exclude] on the 1st stylesheet to force the plugin to avoid looking at it, but I didn’t have any success. So instead of that, I just deleted all the CSS Variables from the 1st stylesheet and everything worked instantly.

In case anyone is wondering, I originally kept the CSS Variables in the 1st stylesheet since I was I was hoping to just have one huge stylesheet for modern browsers and have the 2nd “Theme” stylesheet only for legacy browsers.

Thanks once again!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Workaround for CSS variables in IE? - Stack Overflow
Yes there is a way, the same way you make any css compatible: use a specific css fallback that is supported by the...
Read more >
How to use CSS custom properties (a.k.a. variables)
CSS variables allow an author to assign arbitrary values to a property with an author-chosen name. This custom property must start with --...
Read more >
A Strategy Guide To CSS Custom Properties
In this example, each custom property is determined using calc() , by taking the value of the previous custom property and multiplying this...
Read more >
Browser comparison | Can I use... Support tables for HTML5 ...
Select browser versions to compare. Categories. All. CSS ... IE 6, IE 7, IE 8, IE 9, IE 10, IE 11. autocomplete attribute:...
Read more >
Why doesn't Internet Explorer support CSS variables? - Quora
I think you are totally on the wrong track here, if you are referring to the names of the css properties as well...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found