18

I have an element which should have a background image, but it's been given the following style in a stylesheet that I'm not able to access/modify:

#an-element li {
  background: none !important;
}

Is it possible to undo that style with jQuery? I've tried to add background: inhert!important with jQuery in two ways: by adding an inline style, and by removing an applied style. Neither work.

Here is a Fiddle illustrating the problem: http://jsfiddle.net/9bJzk/1/

UPDATE: I had the wrong fiddle link, please look again.

UPDATE 2: I cannot edit the stylesheet. I've changed the title to be more clear now. I have to do this with jQuery as I can't control the loading order of the CSS files, but can run jQuery onload.

UPDATE 3: I can't explicitly set the 'kitten' pic (see the fiddle) with a more accurate CSS selector like selector like #an-element .image-list li as some are suggesting as those images are being written out on the fly. The jsFiddle was just an example. To make it clearer still: Can the effects of the background: none be undone with PURE jQuery and NOT editing of any stylesheets. Thanks for sticking with this!

Mere Development
  • 2,439
  • 5
  • 32
  • 63
  • 1
    There's no CSS in your jsFiddle, can you add that? Hopefully you tried `inherit` instead of `inhert`? – Pieter Jul 24 '13 at 15:10
  • Your jsfiddle is just html, it doesn't illustrate anything except a simple list – taylorc93 Jul 24 '13 at 15:10
  • 2
    `background: inherit` doesn’t make any sense, `background` isn’t an inherited property. Do you mean you want to set it to what it would normally be if that rule weren’t in place? – Ry- Jul 24 '13 at 15:12
  • @Pieter apologies, I posted the wrong link. Please look again. – Mere Development Jul 24 '13 at 15:15
  • @minitech: `background` doesn't have to be an inherited property for `background: inherit` to work. `inherit` *makes* the element inherit its background from its parent. See http://jsfiddle.net/6MKNE/ – Paul D. Waite Jul 24 '13 at 15:15
  • @minitech ok, yes I want to remove the effects of the background:none style. – Mere Development Jul 24 '13 at 15:16
  • @PaulD.Waite: Yes, but I got the feeling that the OP actually wants to set it to what it would have been if the `!important` rule weren’t there. – Ry- Jul 24 '13 at 15:17
  • @MereDevelopment can you change css or not ? (add parameters) – artSx Jul 24 '13 at 15:17
  • @minitech: ah yes, you're entirely correct that `background:inherit` doesn't have the effect that the OP wants. – Paul D. Waite Jul 24 '13 at 15:19
  • Is the stylesheet you can’t change an external stylesheet? Is it from another domain? – Ry- Jul 24 '13 at 15:21
  • @minitech It's from a 3rd-party plugin, so I could change it manually but the change would be overwritten in a few weeks next time the plugin is updated. – Mere Development Jul 24 '13 at 15:22
  • So `background-image: url("http://placekitten.com/150/50") !important;` and `#an-element li, .image-list li {` as the selector, then? – Ry- Jul 24 '13 at 15:23
  • @minitech Sorry no, see my 'update 3' above. – Mere Development Jul 24 '13 at 15:30
  • @MereDevelopment: If the IDs are generated dynamically, how does the plugin know how to style them? But more importantly: ``, or ` – Ry- Jul 24 '13 at 15:31
  • @minitech It's hard to explain without uploading the whole thing. The list items are being given a background based on their id from a – Mere Development Jul 24 '13 at 15:42
  • @MereDevelopment: Is it possible to add a ` – Ry- Jul 24 '13 at 15:43
  • @minitech It should be yes, I think I can append a script element below the last style element in the head, that should work. Do you have some jQuery in mind that will remove the style? – Mere Development Jul 24 '13 at 16:06
  • @MereDevelopment: Yes. Well, not jQuery. Be back in a bit. :) – Ry- Jul 24 '13 at 16:12
  • PS ... don't add stuff like this to you open source modules! – Toni Leigh Dec 30 '16 at 11:13

6 Answers6

25
div { background: none !important }
div { background: red; }

Is transparent.

div { background: none !important }
div { background: red !important; }

Is red.

An !important can override another !important.

If you can't edit the CSS file you can still add another one, or a style tag in the head tag.

Virus721
  • 8,061
  • 12
  • 67
  • 123
  • I cannot edit the stylesheet. I've changed the title to be more clear, I have to do this with jQuery as I can't control the loading order of the CSS files, but can run jQuery onload. – Mere Development Jul 24 '13 at 15:19
  • As far as i know CSS is applyed in the right order, but in case it is not, have you tried `.css('background', 'what_you_want');` or then `.css('background', 'what_you_want !important');` ? – Virus721 Jul 24 '13 at 15:23
  • 1
    I don't think it's possible to apply the `!important` with jQuery @Virus721 – iConnor Jul 24 '13 at 15:25
  • Unless you use css text – iConnor Jul 24 '13 at 15:26
  • like this `element.css('cssText', 'something:value !important');` – iConnor Jul 24 '13 at 15:28
  • It is not simple to apply !important CSS style using jQuery, see http://stackoverflow.com/questions/2655925/apply-important-css-style-using-jquery – They call me Trinity Jul 24 '13 at 15:42
  • There is also the option of declaring a new css class to which you add an important style `($(document.head).append(''))`, and then add this class to the element. – Virus721 Jul 24 '13 at 15:45
  • @Virus721 i wouldn't advise using `document.head` in there, one because it wont make the slightest difference in performance really, and 2 because it's not cross browser so it's just as easy to do `$('head');` – iConnor Jul 24 '13 at 18:11
7

Several problems arise in this question.

Problem #1 - css Specificity (how to override important rule).

According to specification - to override this selector your selector should be 'stronger' which mean it should be!important and have at least 1 id, 1 class and something else - according to you creating this selector is impossible(as you can't alter page content). So the only possible option is to put something into element style which (could be done with js). Note: style rule should also have !important to override.

Problem #2 - background is not a single property - it is a set of properties (see specification)

So you really need to know what are exact names of properties you want to change (in your case it would be background-image)

Problem #3 - How to remove rule already applied (to get previous value)?

Unfortunately css have no mechanism to dismiss rule which qualify for an element - only to override with "stronger" rule. So you won't be able to solve this task with just setting value to something like 'inherit' or 'default' cause value you want to see is neither inherit from parent nor default. To solve this problem you have couple of options.

1) You may already know what is the value you want to apply. For example you can find out this value based on selector used. So in this case you may know that for selector ".image-list li" you need background-image: url("http://placekitten.com/150/50"). If so - just you this script:

jQuery(".image-list li").attr('style', 'background-image: url("http://placekitten.com/150/50") !important; ');

2) If you don't know the value then you can try to alter page content in such a way, that rule you want to dismiss is no longer qualify for element, whereas rule you want to be shown - still qualify. In this case you may temporary remove id from container element. Here is the code:

jQuery("#an-element").attr('id', '');
var backgroundImage = jQuery(".image-list li").css('background-image');
jQuery("#an-element").attr('id', 'an-element');
jQuery(".image-list li").attr('style', 'background-image: ' + backgroundImage + ' !important; ');

Here is link to fiddle http://jsfiddle.net/o3jn9mzo/

3) As third solution - you may generate element which will qualify for desired selection to find out property value - something like this:

var backgroundImage = jQuery("<div class='image-list'><li></li></div>").find('li').css('background-image');
jQuery(".image-list li").attr('style', 'background-image: ' + backgroundImage + ' !important; ');

P.S.: Sorry for really late response.

CupawnTae
  • 14,192
  • 3
  • 29
  • 60
Dmitry
  • 1,263
  • 11
  • 15
4

Why does not it work? Because the background CSS with background:none!important has one #ID

A CSS selector file that contains an #id will always have a higher value than one .class

If you want to work, you need add #id on your .image-list li like this:

#an-element .image-list li {
    display: inline-block;
    background-image: url("http://placekitten.com/150/50")!important;
    padding: 1em;
    border: 1px solid blue;
}

result here

Ry-
  • 218,210
  • 55
  • 464
  • 476
artSx
  • 1,560
  • 1
  • 12
  • 19
2

Yes it is possible depending on what css you have, you simply just declare the same thing with a different background like this

ul li {
    background: none !important;
}

ul li{
    background: blue !important;
}

But you have to make sure the declaration comes after the first one seeing as it is cascading.

Demo

You can also create a style tag in jQuery like this

$('head').append('<style> #an-element li { background: inherit !important;} </style>');

Demo

You cannot see any changes because it's not inheriting any background but it is overwriting the background: none;

iConnor
  • 19,997
  • 14
  • 62
  • 97
  • I cannot edit the stylesheet. I've changed the title to be more clear, I have to do this with jQuery as I can't control the loading order of the CSS files, but can run jQuery onload. – Mere Development Jul 24 '13 at 15:19
  • Edited answer... you need to make sure that is it actually inheriting something – iConnor Jul 24 '13 at 15:23
0

Any !important can be overridden by another !important, the normal CSS precedence rules still apply.

Example:

#an-element{
    background: #F00 !important;
}
#an-element{
    background: #0F0 !important; //Makes #an-element green
}

Then you could add a style attribute (using JavaScript/jQuery) to override the CSS

$(function () {  
    $("#an-element").attr('style', 'background: #00F !important;');
    //Makes #an-element blue
});

See the result here

0

With a <script> right after the <style> that applies the !important things, you should be able to do something like this:

var lastStylesheet = document.styleSheets[document.styleSheets.length - 1];
lastStylesheet.disabled = true;

document.write('<style type="text/css">');
// Call fixBackground for each element that needs fixing
document.write('</style>');

lastStylesheet.disabled = false;

function fixBackground(el) {
    document.write('html #' + el.id + ' { background-image: ' +
        document.defaultView.getComputedStyle(el).backgroundImage +
        ' !important; }');
}

This probably depends on what kind of browser compatibility you need, though.

Ry-
  • 218,210
  • 55
  • 464
  • 476