[javascript] Overriding !important style

Title pretty much sums it up.

The external style sheet has the following code:

td.EvenRow a {
  display: none !important;
}

I have tried using:

element.style.display = "inline";

and

element.style.display = "inline !important";

but neither works. Is it possible to override an !important style using javascript.

This is for a greasemonkey extension, if that makes a difference.

This question is related to javascript css

The answer is


https://jsfiddle.net/xk6Ut/256/

One option to override CSS class in JavaScript is using an ID for the style element so that we can update the CSS class

function writeStyles(styleName, cssText) {
    var styleElement = document.getElementById(styleName);
    if (styleElement) document.getElementsByTagName('head')[0].removeChild(
        styleElement);
    styleElement = document.createElement('style');
    styleElement.type = 'text/css';
    styleElement.id = styleName;
    styleElement.innerHTML = cssText;
    document.getElementsByTagName('head')[0].appendChild(styleElement);
}

..

   var cssText = '.testDIV{ height:' + height + 'px !important; }';
    writeStyles('styles_js', cssText)

If you want to update / add single style in DOM Element style attribute you can use this function:

function setCssTextStyle(el, style, value) {
  var result = el.style.cssText.match(new RegExp("(?:[;\\s]|^)(" +
      style.replace("-", "\\-") + "\\s*:(.*?)(;|$))")),
    idx;
  if (result) {
    idx = result.index + result[0].indexOf(result[1]);
    el.style.cssText = el.style.cssText.substring(0, idx) +
      style + ": " + value + ";" +
      el.style.cssText.substring(idx + result[1].length);
  } else {
    el.style.cssText += " " + style + ": " + value + ";";
  }
}

style.cssText is supported for all major browsers.

Use case example:

var elem = document.getElementById("elementId");
setCssTextStyle(elem, "margin-top", "10px !important");

Here is link to demo


element.style has a setProperty method that can take the priority as a third parameter:

element.style.setProperty("display", "inline", "important")

It didn't work in old IEs but it should be fine in current browsers.


If you want to update / add single style in DOM Element style attribute you can use this function:

function setCssTextStyle(el, style, value) {
  var result = el.style.cssText.match(new RegExp("(?:[;\\s]|^)(" +
      style.replace("-", "\\-") + "\\s*:(.*?)(;|$))")),
    idx;
  if (result) {
    idx = result.index + result[0].indexOf(result[1]);
    el.style.cssText = el.style.cssText.substring(0, idx) +
      style + ": " + value + ";" +
      el.style.cssText.substring(idx + result[1].length);
  } else {
    el.style.cssText += " " + style + ": " + value + ";";
  }
}

style.cssText is supported for all major browsers.

Use case example:

var elem = document.getElementById("elementId");
setCssTextStyle(elem, "margin-top", "10px !important");

Here is link to demo


Rather than injecting style, if you inject a class(for eg: 'show') through java script, it will work. But here you need css like below. the added class css rule should be below your original rule.

td.EvenRow a{
  display: none !important;
}

td.EvenRow a.show{
  display: block !important;
}

https://developer.mozilla.org/en-US/docs/Web/CSS/initial

use initial property in css3

 <p style="color:red!important"> 
    this text is red 
       <em style="color:initial"> 
          this text is in the initial color (e.g. black)
       </em>
    this is red again
 </p>

There are a couple of simple one-liners you can use to do this.

1) Set a "style" attribute on the element:

element.setAttribute('style', 'display:inline !important');

or...

2) Modify the cssText property of the style object:

element.style.cssText = 'display:inline !important';

Either will do the job.

===

BTW - if you want a useful tool to manipulate !important rules in elements, I've written a jQuery plugin called "important": http://github.com/premasagar/important


Below is a snippet of code to set the important parameter for the style attribute using jquery.

$.fn.setFixedStyle = function(styles){
    var s = $(this).attr("style");
    s = "{"+s.replace(/;/g,",").replace(/'|"/g,"");
    s = s.substring(0,s.length-1)+"}";
    s = s.replace(/,/g,"\",\"").replace(/{/g,"{\"").replace(/}/g,"\"}").replace(/:/g,"\":\"");
    var stOb = JSON.parse(s),st;
    if(!styles){
     $.each(stOb,function(k,v){
      stOb[k] +=" !important";
     });
    }
    else{
     $.each(styles,function(k,v){
      if(v.length>0){
        stOb[k] = v+" !important";
      }else{
        stOb[k] += " !important";  
      }
     });
    }
    var ns = JSON.stringify(stOb);
    $(this).attr("style",ns.replace(/"|{|}/g,"").replace(/,/g,";"));
};

Usage is pretty simple.Just pass an object containing all the attributes you want to set as important.

$("#i1").setFixedStyle({"width":"50px","height":""});

There are two additional options.

1.To just add important parameter to already present style attribute pass empty string.

2.To add important param for all attributes present dont pass anything. It will set all attributes as important.

Here is it live in action. http://codepen.io/agaase/pen/nkvjr


If all you are doing is adding css to the page, then I would suggest you use the Stylish addon, and write a user style instead of a user script, because a user style is more efficient and appropriate.

See this page with information on how to create a user style


Building on @Premasagar's excellent answer; if you don't want to remove all the other inline styles use this

//accepts the hyphenated versions (i.e. not 'cssFloat')
addStyle(element, property, value, important) {
    //remove previously defined property
    if (element.style.setProperty)
        element.style.setProperty(property, '');
    else
        element.style.setAttribute(property, '');

    //insert the new style with all the old rules
    element.setAttribute('style', element.style.cssText +
        property + ':' + value + ((important) ? ' !important' : '') + ';');
}

Can't use removeProperty() because it wont remove !important rules in Chrome.
Can't use element.style[property] = '' because it only accepts camelCase in FireFox.


There we have another possibility to remove a property value from the CSS.

Like using the replace method in js. But you have to know exactly the ID of the style, or you can write a for loop to detecting that by (count styles on the page, then check if any of those 'includes' or 'match' an !important value. & you can count also - how much contains them, or just simply write a global [regexp: /str/gi] replacing method)

Mine is very simple, but I attach a jsBin, for example:

https://jsbin.com/geqodeg/edit?html,css,js,output

First I set the body background in CSS for yellow !important, then I overrided by JS for darkPink.


There we have another possibility to remove a property value from the CSS.

Like using the replace method in js. But you have to know exactly the ID of the style, or you can write a for loop to detecting that by (count styles on the page, then check if any of those 'includes' or 'match' an !important value. & you can count also - how much contains them, or just simply write a global [regexp: /str/gi] replacing method)

Mine is very simple, but I attach a jsBin, for example:

https://jsbin.com/geqodeg/edit?html,css,js,output

First I set the body background in CSS for yellow !important, then I overrided by JS for darkPink.


element.style has a setProperty method that can take the priority as a third parameter:

element.style.setProperty("display", "inline", "important")

It didn't work in old IEs but it should be fine in current browsers.


Below is a snippet of code to set the important parameter for the style attribute using jquery.

$.fn.setFixedStyle = function(styles){
    var s = $(this).attr("style");
    s = "{"+s.replace(/;/g,",").replace(/'|"/g,"");
    s = s.substring(0,s.length-1)+"}";
    s = s.replace(/,/g,"\",\"").replace(/{/g,"{\"").replace(/}/g,"\"}").replace(/:/g,"\":\"");
    var stOb = JSON.parse(s),st;
    if(!styles){
     $.each(stOb,function(k,v){
      stOb[k] +=" !important";
     });
    }
    else{
     $.each(styles,function(k,v){
      if(v.length>0){
        stOb[k] = v+" !important";
      }else{
        stOb[k] += " !important";  
      }
     });
    }
    var ns = JSON.stringify(stOb);
    $(this).attr("style",ns.replace(/"|{|}/g,"").replace(/,/g,";"));
};

Usage is pretty simple.Just pass an object containing all the attributes you want to set as important.

$("#i1").setFixedStyle({"width":"50px","height":""});

There are two additional options.

1.To just add important parameter to already present style attribute pass empty string.

2.To add important param for all attributes present dont pass anything. It will set all attributes as important.

Here is it live in action. http://codepen.io/agaase/pen/nkvjr


element.style has a setProperty method that can take the priority as a third parameter:

element.style.setProperty("display", "inline", "important")

It didn't work in old IEs but it should be fine in current browsers.


There are a couple of simple one-liners you can use to do this.

1) Set a "style" attribute on the element:

element.setAttribute('style', 'display:inline !important');

or...

2) Modify the cssText property of the style object:

element.style.cssText = 'display:inline !important';

Either will do the job.

===

BTW - if you want a useful tool to manipulate !important rules in elements, I've written a jQuery plugin called "important": http://github.com/premasagar/important


element.style has a setProperty method that can take the priority as a third parameter:

element.style.setProperty("display", "inline", "important")

It didn't work in old IEs but it should be fine in current browsers.


Building on @Premasagar's excellent answer; if you don't want to remove all the other inline styles use this

//accepts the hyphenated versions (i.e. not 'cssFloat')
addStyle(element, property, value, important) {
    //remove previously defined property
    if (element.style.setProperty)
        element.style.setProperty(property, '');
    else
        element.style.setAttribute(property, '');

    //insert the new style with all the old rules
    element.setAttribute('style', element.style.cssText +
        property + ':' + value + ((important) ? ' !important' : '') + ';');
}

Can't use removeProperty() because it wont remove !important rules in Chrome.
Can't use element.style[property] = '' because it only accepts camelCase in FireFox.


Rather than injecting style, if you inject a class(for eg: 'show') through java script, it will work. But here you need css like below. the added class css rule should be below your original rule.

td.EvenRow a{
  display: none !important;
}

td.EvenRow a.show{
  display: block !important;
}