Changing CSS Rule Set from Javascript

Is it possible to make changes to the CSS rule set dynamically (i.e. some JS that will change the CSS rule set when the user clicks on the widget)

This particular set of CSS rules applies to many elements (via the class selector) on the page, and I want to change it when the user clicks on the widget, so that all elements that have the class change.

+48
javascript css
Sep 11 '09 at 6:06
source share
7 answers

You can, but it's rather cumbersome. The best link for how to do this is the following article: Completely Pwn CSS with Javascript ( link to web archive ).

I managed to get it to work with Firefox and IE - I could not in Chrome, although it seems that it supports DOM methods. ricosrealm reports that it also works in Chrome.

+31
Sep 11 '09 at 6:13
source share

This is a modern version based on Totally Pwn CSS with Javascript. This is ES6. I hope not against it.

function getCSSRule(ruleName) { ruleName = ruleName.toLowerCase(); var result = null; var find = Array.prototype.find; find.call(document.styleSheets, styleSheet => { result = find.call(styleSheet.cssRules, cssRule => { return cssRule instanceof CSSStyleRule && cssRule.selectorText.toLowerCase() == ruleName; }); return result != null; }); return result; } 

This function returns a CSSStyleRule, which you can use as follows:

 var header = getCSSRule('#header'); header.style.backgroundColor = 'red'; 

Also document.styleSheets reference a list of CSSStylesSheets objects. Another way to access a specific sytleSheet file on a page is to assign an id element to a style or link element in the html code and get it in javascript using document.getElementById ('my-style'). sheet . These are some useful methods:

Major browsers and IE9 +: insertRule (), deleteRule (), removeProperty ().

Major browsers, Firefox? and IE9 +: setProperty ().

 <stye id="my-style" ... .... var myStyle = document.getElementById('my-style').sheet myStyle.insertRule('#header { background: red; }', 0); 

It is also possible to dynamically create a new style element to store dynamically created styles, I think this should be a way to avoid conflicts.

+5
Apr 23 '16 at 3:45
source share

The APIs for editing stylesheets with JS are unfortunately not compatible between browsers. The YUI Stylesheet Utility tries to smooth out these differences so you can just use it. You can also look at the source code to find out how it works if you don't want to use YUI itself.

+4
Sep 11 '09 at 6:49
source share

I tried the code from the link from the @ alex-gyoshev comment, but it doesn’t work

  • it does not work in CSS rules using Google fonts in Chrome
  • it does not cope with FireFox security checks.

So, I changed it a bit, but deleted the delete functionality, since I don't need it. Tested in IE 11, FireFox 32, Chrome 37, and Opera 26.

 function getCSSRule(ruleName) { // Return requested style object ruleName = ruleName.toLowerCase(); // Convert test string to lower case. var styleSheet; var i, ii; var cssRule = false; // Initialize cssRule. var cssRules; if (document.styleSheets) { // If browser can play with stylesheets for (i = 0; i < document.styleSheets.length; i++) { // For each stylesheet styleSheet = document.styleSheets[i]; if (!styleSheet.href) { if (styleSheet.cssRules) { // Browser uses cssRules? cssRules = styleSheet.cssRules; // Yes --Mozilla Style } else { // Browser usses rules? cssRules = styleSheet.rules; // Yes IE style. } // End IE check. if (cssRules) { for (ii = 0; ii < cssRules.length; ii++) { cssRule = cssRules[ii]; if (cssRule) { // If we found a rule... // console.log(cssRule); if (cssRule.selectorText) { console.log(cssRule.selectorText); if (cssRule.selectorText.toLowerCase() == ruleName) { // match ruleName? return cssRule; // return the style object. } } } } } } } } return false; // we found NOTHING! } 
+4
07 Oct '14 at 8:30
source share

Depending on what you are trying to achieve, the best solution might be to change / add a class to the containing element (the body will do!) And define classes accordingly.

 .yourclass { color: black } #wrapper.foo .yourclass { color: red } #waraper.bar .yourclass { color: blue } 

then you can just use

 document.getElementById('wrapper').className='foo'; 

(or your chosen js framework for the same) to change everything using the class yourclass inside any of your wrapper elements.

((in brackets) is there a way to stop SO formatting from assuming that material starting with # is a comment?)

+2
Sep 11 '09 at 6:29
source share

specify your id style tag, for example <style id="ssID"> if someonelse does your styles for you tell this person to give an id style tag - this way you can access it directly without scrambling around, wondering what it is index

 // create a hash table var cssHash = {}; // loop through and populate the hash table for (let i in (r = ss0.sheet.rules)) { // selectorText is the name of the rule - set the value equal to the rule cssHash[r[i].selectorText] = r[i]; } 

now you have a hash table for everything contained in the stylesheet - note that some values ​​will be undefined, but not for any of the things you care about

if you have, for example, a class named #menuItem and you want to change your color to black, do this

 cssHash['#menuItem'].style.color = #000; 

this line sets the color of the rule style whose index was viewed in the hash table (cssHash) named "#menuItem"

more importantly, you probably have several different classes that you want to change right away, sort of like when you changed majors in college

let's say you have four different classes and you want to set all background colors to the same value as some user selected from input

the color selector tag <input id="bColor" type="color"> and the class rules you want to change are called #menuItem. homeAddr span and #vacuum: hover

 // create a listener for that color selector bColor.addEventListener('input', function (e) { // loop through a split list of the four class names '#menuItem .homeAddr span #vacuum:hover'.split(' ').forEach(function (obj) { // use the hash table to look up the index of each name // and set the background color equal to the color input value cssHash[obj].style.backgroundColor = bColor.value; }); }, false); // false added here for the sake of non-brevity 
+1
Apr 22 '17 at 3:53 on
source share

While setAttribute nice, most browsers have a standard way:

 htmlElement.className = 'someClass'; 

To do this in many ways, you will need a cross-browser solution:

 function getElementsByClassName( className, context, tagName ) { context = context || document; if ( typeof context.getElementsByClassName === 'function' ) return context.getElementsByClassName( className ); if ( typeof context.getElementsByTagName !== 'function' ) return []; var elements = typeof tagName === 'string' ? context.getElementsByTagName( tagName ) : context.getElementsByTagName('*'), ret = []; for ( var i = 0, il = elements.length; i < il; i++ ) if ( elements[ i ].className.match( className ) ) ret.push( elements[ i ] ); return ret; } var elements = getElementsByClassName('someClass'); for ( var i = 0, il = elements.length; i < il; i++ ) elements[ i ].className = 'newClass'; 

You can replace the line:

 if ( elements[ i ].className.match( className ) ) 

With some regex, but you have to avoid special characters in this case.

0
Sep 11 '09 at 6:22
source share



All Articles