7

In my application, I've got some parameters that I wanted to put in CSS variables using jQuery. And I wanted to read them too.

I was having trouble to read the values back of the CSS variables and tried many things… before I found a solution in the “Questions that may already have your answer” while I was typing my question.

Anyway, I attached a snippet, because I need to know:
⋅⋅⋅ Why the method 1 isn't working ?
⋅⋅⋅ Is there a way to get the CSS var value using jQuery ?

I feel like it lacks an easy solution to handle CSS vars… Am I wrong ?
Of course I'll use the javascript solution if there isn't any way. But I'd like to be sure about it.
Thanks in advance for any answer.

// This method doesn't work for writing CSS var.
$(":root").css("--color1", "red");
console.log(".css method on “:root”      :", $(":root").css("--color1"));

// This methods works for writing CSS var:
$(":root")[0].style.setProperty("--color2", "lime");
console.log("[0].style method on “:root” :", $(":root")[0].style.getPropertyValue('--color2'));
#p1 {
  background-color: var(--color1);
}

#p2 {
  background-color: var(--color2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>

<body id="bodyID">
  <p id="p1">p with background --color1</p>
  <p id="p2">p with background --color2</p>
</body>

<html>
Takit Isy
  • 9,688
  • 3
  • 23
  • 47
  • `setProperty` must create the property if she doesn't exist. Which seems to be the case – Greggz Mar 01 '18 at 11:08
  • good to see you are considering them from you last question, unfortunately i cam late :) you already have the answer ;) – Temani Afif Mar 01 '18 at 11:29
  • Anyway, @TemaniAfif, it's your "fault" if I came with another question ( kiddin' :) ). I thank you again for your answer to my other question, introducing me with CSS variables, it's really worth it. – Takit Isy Mar 01 '18 at 15:05
  • welcome ;) i did this with everyone :) i throw new features and then questions start raining which is good for everyone as these ressources will be helful for future comers ;) – Temani Afif Mar 01 '18 at 15:09

3 Answers3

12

jQuery only supports CSS custom properties in version 3.2.0 and later. There is no support for them in 2.x or earlier, so accessing them with .css() will not work in those versions. If upgrading jQuery is not an option, you will need to use the built-in style object to access them.

$(":root").css("--color1", "red");
console.log(".css method on “:root”      :", $(":root").css("--color1"));

$(":root")[0].style.setProperty("--color2", "lime");
console.log("[0].style method on “:root” :", $(":root")[0].style.getPropertyValue('--color2'));
#p1 {
  background-color: var(--color1);
}

#p2 {
  background-color: var(--color2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<p id="p1">p with background --color1</p>
<p id="p2">p with background --color2</p>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Thanks you BoltClock, that was my problem. I verified the version of jQuery in my application, and it was 3.1.1… – Takit Isy Mar 01 '18 at 12:28
  • @TemaniAfif : If the snippet was up-to-date, my code would have worked and I may have noticed what was the problem by myself ! So, yea, could be nice to update it. :) – Takit Isy Mar 01 '18 at 12:34
1

As BoltClock mentions in their answer, jQuery added support for CSS variables starting from version 3.2.0.

But if you can't upgrade to the higher version for some reason, you could still extend jQuery's $.fn.css method to work with the custom properties.

So here's my attempt at implementing a simple extension that checks if the property being modified is a Custom property or not (by checking that it begins with two hyphens). If it does, the custom property is modified using plain JS, else it calls the original implementation of $.fn.css.

(function() {
  var originalFnCss = $.fn.css;
  $.fn.css = function(prop, val) {

    // Check if the property being set is a CSS Variable.
    if (prop.indexOf("--") === 0) {
      if(val) {

        // Set the value if it is provided.
        for(var idx = 0; idx < this.length; idx++) {
          this[idx].style.setProperty(prop, val);
        }
      } else {

        // Get the computed value of the property.
        return window.getComputedStyle(this[0]).getPropertyValue(prop);
      }
    } else {
      return originalFnCss.apply(this, arguments);
    }
  };
}()); 

Note: At the moment I have tested this extension with jQuery 1.11.1, 2.2.4 and 3.1.1, but do let me know if you find any bugs, or if you have any suggestions.


Now you just need to add the extension just after importing jQuery, or at any point before $.fn.css is invoked. Here's the working snippet:

(function() {
  var originalFnCss = $.fn.css;
  $.fn.css = function(prop, val) {

    // Check if the property being set is a CSS Variable.
    if (prop.indexOf("--") === 0) {
      if(val) {

        // Set the value if it is provided.
        for(var idx = 0; idx < this.length; idx++) {
          this[idx].style.setProperty(prop, val);
        }
      } else {

        // Get the computed value of the property.
        return window.getComputedStyle(this[0]).getPropertyValue(prop);
      }
    } else {
      return originalFnCss.apply(this, arguments);
    }
  };
}()); 

// This method doesn't work for writing CSS var.
$(":root").css("--color1", "red");
console.log(".css method on “:root”      :", $(":root").css("--color1"));

// This methods works for writing CSS var:
$(":root")[0].style.setProperty("--color2", "lime");
console.log("[0].style method on “:root” :", $(":root")[0].style.getPropertyValue('--color2'));
#p1 {
  background-color: var(--color1);
}

#p2 {
  background-color: var(--color2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>

<body id="bodyID">
  <p id="p1">p with background --color1</p>
  <p id="p2">p with background --color2</p>
</body>

<html>
Nisarg Shah
  • 14,151
  • 6
  • 34
  • 55
0

Here is my version with a live demo -

// array with colors

var colConfig = [
  "default-bg",
  "hoverbg",
  "activebg",
  "maintxt",
  "subtxt",
  "listtxt"
];

let col_1 = ["#ffffff", "#f5f5f5", "#0065ff",'rgba(20, 20, 200, 1)', 'rgba(20, 20, 20, 1)', 'rgba(100, 100, 100, 0.5)'];
let col_2 = ["#000000", "#5f5f5f", "#6500ff", "#1f1f1f", "#f1f1f1", "#000088"];

$("#default").click(function () {
  changeTh(col_1);
});

$("#new").click(function () {
  changeTh(col_2);
});

function changeTh(col) {
  for (let tag in colConfig) { 
    $(":root").css("--" + colConfig[tag], col[tag]);
  }
} 
B L Λ C K
  • 600
  • 1
  • 8
  • 24