Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all css root variables in array using javascript and change the values

I am using css root variables in my project for dynamically changing the colors of all elements anytime.

My css looks like

:root{
  --primaryColor:aliceblue;
  --secondaryColor:blue;
  --errorColor:#cc2511;
}

used in css

.contentCss {
  background-color: var(--primaryColor);
} 

I can access variable in javascript as follows to change value dynamically

document.documentElement.style.setProperty('--primaryColor', 'green');

It works fine. I want to get all variables inside an array and according to that change the values of each variable dynamically.

like image 913
Nadeem Mohammed Avatar asked Feb 13 '18 05:02

Nadeem Mohammed


2 Answers

this script will return an array of root variables in all stylesheets, served from the domain. Out of domain stylesheets are not accessible due to CORS policies.

Array.from(document.styleSheets)
  .filter(
    sheet =>
      sheet.href === null || sheet.href.startsWith(window.location.origin)
  )
  .reduce(
    (acc, sheet) =>
      (acc = [
        ...acc,
        ...Array.from(sheet.cssRules).reduce(
          (def, rule) =>
            (def =
              rule.selectorText === ":root"
                ? [
                    ...def,
                    ...Array.from(rule.style).filter(name =>
                      name.startsWith("--")
                    )
                  ]
                : def),
          []
        )
      ]),
    []
  );

Note: a root: rule in a lower order stylesheet will override a parent root rule.

like image 125
tnt-rox Avatar answered Oct 05 '22 13:10

tnt-rox


I needed a similar solution today. Here's a quick one on codepen.

// could pass in an array of specific stylesheets for optimization
function getAllCSSVariableNames(styleSheets = document.styleSheets){
   var cssVars = [];
   // loop each stylesheet
   for(var i = 0; i < styleSheets.length; i++){
      // loop stylesheet's cssRules
      try{ // try/catch used because 'hasOwnProperty' doesn't work
         for( var j = 0; j < styleSheets[i].cssRules.length; j++){
            try{
               // loop stylesheet's cssRules' style (property names)
               for(var k = 0; k < styleSheets[i].cssRules[j].style.length; k++){
                  let name = styleSheets[i].cssRules[j].style[k];
                  // test name for css variable signiture and uniqueness
                  if(name.startsWith('--') && cssVars.indexOf(name) == -1){
                     cssVars.push(name);
                  }
               }
            } catch (error) {}
         }
      } catch (error) {}
   }
   return cssVars;
}

function getElementCSSVariables (allCSSVars, element = document.body, pseudo){
   var elStyles = window.getComputedStyle(element, pseudo);
   var cssVars = {};
   for(var i = 0; i < allCSSVars.length; i++){
      let key = allCSSVars[i];
      let value = elStyles.getPropertyValue(key)
      if(value){cssVars[key] = value;}
   }
   return cssVars;
}

var cssVars = getAllCSSVariableNames();
console.log(':root variables', getElementCSSVariables(cssVars, document.documentElement));
like image 36
taysim Avatar answered Oct 05 '22 14:10

taysim