Workaround for CSS variables in IE?

CssInternet ExplorerOutsystems

Css Problem Overview


I'm currently developing a web application in Outsystems in which I have the need to customize the CSS, in which I'm using variables. I need to guarantee the app works cross-browser, including in Internet Explorer. IE doesn't support CSS variables, as you can see in the picture below from this source.

Since I have to use CSS variables, is there any workaround for the usage of variables in IE?

Css Solutions


Solution 1 - Css

Yes there is a way, the same way you make any css compatible: use a specific css fallback that is supported by the browser.

body {
  --text-color: red;
}

body {
  color: red; /* default supported fallback style */
  color: var(--text-color); /* will not be used by any browser that doesn't support it, and will default to the previous fallback */
}

This solution is incredibly redundant and 'almost' defeats the purpose of css variables....BUT it is necessary for browser compatibility. Doing this would essentially make the css variables useless but I implore you to still use them because it will serve as an important reminder to the fact that these values are referenced elsewhere and need to be updated in all cases, otherwise you forget to update every related occurrence of 'color' and then you have inconsistent styling because relevant css values are out of sync. The variable will serve more as a comment but a very important one.

Solution 2 - Css

There is a polyfill, which enables almost complete support for CSS variables in IE11:
https://github.com/nuxodin/ie11CustomProperties
(i am the author)

The script makes use of the fact that IE has minimal custom properties support where properties can be defined and read out with the cascade in mind.
.myEl {-ie-test:'aaa'} // only one dash allowed! "-"
then read it in javascript:
getComputedStyle( querySelector('.myEl') )['-ie-test']

From the README:

> Features
>

  • handles dynamic added html-content
  • handles dynamic added

Solution 3 - Css

In case someone comes across this, has a similar issue where I had it set like this.

a {
  background: var(--new-color);
  border-radius: 50%;
}

I added the background colour before the variable so if that didn't load it fell back on the hex.

a {
  background: #3279B8;
  background: var(--new-color);
  border-radius: 50%;
}

Solution 4 - Css

Yes, so long as you're processing root-level custom properties (IE9+).

From the README:

> 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 support is limited to :root and :host declarations > - The use of var() is limited to property values (per W3C specification)

Here are a few examples of what the library can handle:

Root-level custom properties

:root {
    --a: red;
}

p {
    color: var(--a);
}

Chained custom properties

:root {
    --a: var(--b);
    --b: var(--c);
    --c: red;
}

p {
    color: var(--a);
}

Nested custom properties

:root {
    --a: 1em;
    --b: 2;
}

p {
    font-size: calc(var(--a) * var(--b));
}

Fallback values

p {
    font-size: var(--a, 1rem);
    color: var(--b, var(--c, var(--d, red))); 
}

Transforms <link>, <style>, and @import CSS

<link rel="stylesheet" href="/absolute/path/to/style.css">
<link rel="stylesheet" href="../relative/path/to/style.css">

<style>
    @import "/absolute/path/to/style.css";
    @import "../relative/path/to/style.css";
</style>

Transforms web components / shadow DOM

<custom-element>
  #shadow-root
    <style>
      .my-custom-element {
        color: var(--test-color);
      }
    </style>
    <div class="my-custom-element">Hello.</div>
</custom-element>

For the sake of completeness: w3c specs

Hope this helps.

(Shameless self-promotion: Check)

Solution 5 - Css

Make a seperate .css file for your variables. Copy/paste the contents of the variable.css file to the end of your main.css file. Find and replace all the variable names in the main.css file to the hex code for those variables. For example: ctrl-h to find var(--myWhiteVariable) and replace with #111111.

Side note: if you keep the :root{ } in the main.css file and just comment it out, you can use that to track those hex codes later if you want to update your fallback colors.

Solution 6 - Css

Another way to do it is declaring colors in a JS file (in my case I'm using react) and then just use the variable you defined in the JS file.

For example:

  • in globals.js
export const COLORS = {
  yellow: '#F4B400',
  yellowLight: '#F4C849',
  purple: '#7237CC',
  purple1: '#A374EB',
}
  • in your file
import { COLORS } from 'globals'

and then just use COLORS.yellow, COLORS.purple, etc.

Solution 7 - Css

body {
  --text-color : red; /* --text-color 정의 */
}    

body {
   color: var(--text-color, red); /* --text-color 정의되지 않으면 red로 대체됨 */
}

body {
   color: var(--text-color, var(--text-color-other, blue));
   /* --text-color, --text-color-other 가 정의되지 않으면 blue로 대체됨 */
}

Solution 8 - Css

There is no way yet in "normal" css but take a look at sass/scss or less.

here is a scss example

$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

Solution 9 - Css

I recommend setting your css variables as sass variables, then using sass interpolation to render the color in your elements.

:root {    
    --text-color: #123456;
}

$text-color: var(--text-color);

body {
    color: #{$text-color};
}

Solution 10 - Css

If im not wrong there is a workaround, the CSS #ID Selector. Which should work for IE > 6 I guess.. So you can

.one { };
<div class="one">

should work as

#one {};
<div id="one">

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRafael ValenteView Question on Stackoverflow
Solution 1 - CssMohammed SiddeeqView Answer on Stackoverflow
Solution 2 - CssTobias BuschorView Answer on Stackoverflow
Solution 3 - CssDerek MCView Answer on Stackoverflow
Solution 4 - CssjhildenbiddleView Answer on Stackoverflow
Solution 5 - CssWalter InghamView Answer on Stackoverflow
Solution 6 - CssSata SuarezView Answer on Stackoverflow
Solution 7 - Css이다빈View Answer on Stackoverflow
Solution 8 - CssAndré SchmidView Answer on Stackoverflow
Solution 9 - CssChrisView Answer on Stackoverflow
Solution 10 - CssphaenView Answer on Stackoverflow