How to Inject a Style with an "!Important" Rule

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 override !important?

Overriding the !important modifier

  1. Simply add another CSS rule with !important, and give the selector a higher specificity (adding an additional tag, id or class to the selector)
  2. add a CSS rule with the same selector at a later point than the existing one (in a tie, the last one defined wins).

Some examples with a higher specificity (first is highest/overrides, third is lowest):

table td    {height: 50px !important;}
.myTable td {height: 50px !important;}
#myTable td {height: 50px !important;}

Or add the same selector after the existing one:

td {height: 50px !important;}

Disclaimer:

It's almost never a good idea to use !important. This is bad engineering by the creators of the WordPress template. In viral fashion, it forces users of the template to add their own !important modifiers to override it, and it limits the options for overriding it via JavaScript.

But, it's useful to know how to override it, if you sometimes have to.

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.

Can I override an element's inline style in my stylesheet?

Inline styles rule supreme.

You can do this, but you'll need to do it using JavaScript. The code would have to basically remove all of the inline style statements from the pasted code. This is a good idea anyway, you never know what people will paste-in.

Using jQuery:

$('.wrapper *').removeAttr('style'); 

...where your content is within a div with a class of "wrapper"

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");
}

Inject css rule for specific element children

Give the specific container an additional, generated class name and add a style element (here's how) with the relevant rule, e.g.:

.array-container.width-28 > span { width : 28px }

...if the width you want is 28px.

You'd change this line:

container.setAttribute('class','array-container');

to

container.className = 'array-container width-' + width;

Keep track of the style elements you add so that if you need a value twice, you don't have to add a second style element for the same value.

Here's a really quick and dirty example: Live Copy

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Dynamic Style Example</title>
<style>
.array-container span {
display: inline-block;
border: 1px solid #08f;
height: 1em;
}
</style>
</head>
<body>
<label>Add elements with width:
<input type="number" value="10" min="10" max="10000" id="width-to-use">
</label>
<input type="button" value="Add" id="btn-add">
<script>
(function() {
document.getElementById("btn-add").onclick = function() {
var width, div, css, style;

width = parseInt(document.getElementById("width-to-use").value, 10);
if (isNaN(width)) {
return;
}

div = document.createElement('div');
div.innerHTML =
"<span></span>" +
"<span></span>" +
"<span></span>";
div.className = "array-container width-" + width;

if (document.getElementById("style-width-" + width) === null) {
css = ".array-container.width-" + width + " span { " +
"width: " + width + "px; " +
"}";
style = document.createElement('style');
style.id = "style-width-" + width;
style.type = "text/css";
if (style.styleSheet){
style.styleSheet.cssText = css;
}
else {
style.appendChild(document.createTextNode(css));
}
document.getElementsByTagName("head")[0].appendChild(style);
}

document.body.appendChild(div);
};
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
</script>
</body>
</html>

Webpack style-loader vs css-loader

The CSS loader takes a CSS file and returns the CSS with imports and url(...) resolved via webpack's require functionality:

var css = require("css!./file.css");
// => returns css code from file.css, resolves imports and url(...)

It doesn't actually do anything with the returned CSS.

The style loader takes CSS and actually inserts it into the page so that the styles are active on the page.

They perform different operations, but it's often useful to chain them together, like Unix pipes. For example, if you were using the Less CSS preprocessor, you could use

require("style!css!less!./file.less")

to

  1. Turn file.less into plain CSS with the Less loader
  2. Resolve all the imports and url(...)s in the CSS with the CSS loader
  3. Insert those styles into the page with the style loader


Related Topics



Leave a reply



Submit