How to Add !Important to a Stylesheet Rule Using JavaScript

Using CSS !important with JavaScript

Try this code using CSSStyleDeclaration.setProperty():

function myFunction() {
var x = document.querySelectorAll("#testDiv p.example");
x[0].style.setProperty("background-color", "red", "important");
}

Overriding !important style

I believe the only way to do this it to add the style as a new CSS declaration with the '!important' suffix. The easiest way to do this is to append a new <style> element to the head of document:

function addNewStyle(newStyle) {
var styleElement = document.getElementById('styles_js');
if (!styleElement) {
styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.id = 'styles_js';
document.getElementsByTagName('head')[0].appendChild(styleElement);
}
styleElement.appendChild(document.createTextNode(newStyle));
}

addNewStyle('td.EvenRow a {display:inline !important;}')

The rules added with the above method will (if you use the !important suffix) override other previously set styling. If you're not using the suffix then make sure to take concepts like 'specificity' into account.

How to apply !important using .css()?

Most of these answers are now outdated, IE7 support is not an issue.

The best way to do this that supports IE11+ and all modern browsers is:

const $elem = $("#elem");
$elem[0].style.setProperty('width', '100px', 'important');

Or if you want, you can create a small jQuery plugin that does this.
This plugin closely matches jQuery's own css() method in the parameters it supports:

/**
* Sets a CSS style on the selected element(s) with !important priority.
* This supports camelCased CSS style property names and calling with an object
* like the jQuery `css()` method.
* Unlike jQuery's css() this does NOT work as a getter.
*
* @param {string|Object<string, string>} name
* @param {string|undefined} value
*/
jQuery.fn.cssImportant = function(name, value) {
const $this = this;
const applyStyles = (n, v) => {
// Convert style name from camelCase to dashed-case.
const dashedName = n.replace(/(.)([A-Z])(.)/g, (str, m1, upper, m2) => {
return m1 + "-" + upper.toLowerCase() + m2;
});
// Loop over each element in the selector and set the styles.
$this.each(function(){
this.style.setProperty(dashedName, v, 'important');
});
};
// If called with the first parameter that is an object,
// Loop over the entries in the object and apply those styles.
if(jQuery.isPlainObject(name)){
for(const [n, v] of Object.entries(name)){
applyStyles(n, v);
}
} else {
// Otherwise called with style name and value.
applyStyles(name, value);
}
// This is required for making jQuery plugin calls chainable.
return $this;
};
// Call the new plugin:
$('#elem').cssImportant('height', '100px');

// Call with an object and camelCased style names:
$('#another').cssImportant({backgroundColor: 'salmon', display: 'block'});

// Call on multiple items:
$('.item, #foo, #bar').cssImportant('color', 'red');

Example jsfiddle here.

Adding !important within a dynamically written stylesheet for Internet Explorer

I have spent some more time doing some testing, and have come to the conclusion that my rewrite of the cssText is working to add !important to some mysterious internal flag setting of IE, even though the shortened properties that itself rewrites for the cssText do not reflect that.

Apparently, neither the cssText property (if it is examined after my rewrite to add the !important) nor the Microsoft Developer Toolbar examination of the element are showing the fact that the property has an !important setting on it. The element is, however, displaying as if my rewrite worked. I tested this by placing an !important on the base style for an image border like so:

img {border: 3px solid green !important;}

Then with javascript I created my styleSheets object and added a rule that was both more specific (using the id of the image) and that had its cssText rewritten with !important after already having set the style of the styleSheets object by a javascript call for borderTopColor = red. I then set the inline style of the element to change the top color to yellow. The results were as I would expect with the !important flag. The red wins out, as it is a later (and more specific) call than the original green, and the inline style does not override it. If I remove the rewrite of the!important then the color reverts to green, and if I remove green's !important the color reverts to yellow.

I also tested this with the green having a higher selector specificity than my javascript written style for the red. That, too, behaved as expected, with green winning out since it now had the higher selector specificity with the competing !important of the red declaration.

This was tested on IE8, IE7, and IE6 (yes, it worked there too). While rewriting/setting the cssText of the styleSheets is not as easy as being able to set it with a straight javascript call on the property, at least it works. The real 'bug' is the fact that neither the cssText nor the Developer Toolbar were giving me correct information that an !important flag was set on those styles, so if someone were coming behind and examining the site, they may get confused as to why something is happening with the styles (why something that does not seem to be important is acting as if it is).

How do you add CSS with Javascript?

You can also do this using DOM Level 2 CSS interfaces (MDN):

var sheet = window.document.styleSheets[0];
sheet.insertRule('strong { color: red; }', sheet.cssRules.length);

...on all but (naturally) IE8 and prior, which uses its own marginally-different wording:

sheet.addRule('strong', 'color: red;', -1);

There is a theoretical advantage in this compared to the createElement-set-innerHTML method, in that you don't have to worry about putting special HTML characters in the innerHTML, but in practice style elements are CDATA in legacy HTML, and ‘<’ and ‘&’ are rarely used in stylesheets anyway.

You do need a stylesheet in place before you can started appending to it like this. That can be any existing active stylesheet: external, embedded or empty, it doesn't matter. If there isn't one, the only standard way to create it at the moment is with createElement.

Can !important rules be used in IE's CSS expressions?

The reason those CSS expressions don't work is because IE only evaluates the expression for the last property in the cascade.

E.g. if you have an HTML document with a link inside it and the following "CSS",

a {
color: expression(function(e){
alert('success');
e.runtimeStyle.color = 'blue';
}(this));
}
a { color: red; }

you will never see that alert (nevermind the style change), because the CSS expression is never evaluated. So no, you can't use an expression to set the !important flag.

That is to say, not when you try to set it on the same property. You can cheat. But that does make the expression a bit more complicated:

a {
filter: expression(function(e){
e.runtimeStyle.color = 'blue';
alert('success');
e.style.filter = '';
}(this));
}
a { color: red; }

There are a few things to note here.

If you simply use another CSS property, you can be sure that the expression will be evaluated. Or at least, a little more sure, because if there's another rule further down the cascade that uses the same property already, you're still out of luck.

Secondly, you have to use runtimeStyle instead of currentStyle. If you used currentStyle here, the second rule would still end up overwriting it. runtimeStyle overrides all other CSS (except !important declarations). So it's the JScript equivalent of !important.

Also note that I'm resetting the filter property itself as well. That prevents the expression from being continuously re-evaluated. But as much as that may reduce performance, I don't think it's super critical. The main reason I put it in here is because I added alert()s in those expressions, and you definitely don't want to have those pop up forever.

It is in fact also possible to use any other property you make up. This works too:

a {
bogus: expression(function(e){
e.runtimeStyle.color = 'blue';
}(this));
}

However, since the bogus property doesn't actually exist, you can't reset it using Javascript, so this will be re-evaluated continuously.

How do you read CSS rule values with JavaScript?

Adapted from here, building on scunliffe's answer:

function getStyle(className) {
var cssText = "";
var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
for (var x = 0; x < classes.length; x++) {
if (classes[x].selectorText == className) {
cssText += classes[x].cssText || classes[x].style.cssText;
}
}
return cssText;
}

alert(getStyle('.test'));


Related Topics



Leave a reply



Submit