Cause
The problem is that an id-style is more important (has more 'weight') than a class style, so #sample
has higher precedence than .green
and the div remains red. There are many rules that dictate which CSS rules have precedence over others. Make sure to read about CSS rule Precedence, so whichever solution you choose, you know why you chose it and what are the consequences.
Fix
There are many ways to fix this, but they all boil down to making sure that the green rule overrules (is equally or more important than) the default red rule.
Solution (Best): Style on classes, not on IDs.
Add a class to the div that indicates what kind of box it is:
<div id="sample" class="samplecontainer"></div>
Now, in the CSS you can easily apply a default style to such elements, and overrule them too:
.samplecontainer {
background-color: red;
}
.samplecontainer.valid,
/* Or just */
.valid
{
background-color: green;
}
Now the CSS doesn't rely on specific elements, but on element definitions. You can say that containers are by default red, and are made green when they become 'valid' (whatever that may mean in this example). This way, you don't rely on ids in the CSS, which prevents very bulky CSS and the undesirable overrule you bumped into.
Note I renamed 'green' to 'valid' to make it more semantic. What if you want to change the border too, or make them blue instead of green? Then you would still need to dig into the JavaScript code, and also change the class names in CSS and possibly fixed style names in HTML and PHP. Or you can just leave the class name 'green' for the blue element, which is very confusing too. So a name describing the type or state (like valid, active, or whatever suits you best) is easier to read and to maintain.
Solution (Sub-optimal): Add Id to the green rule too
Try do change the css like this, so indicate that an element that has id 'sample' and class 'valid' should be green. I think this is quick fix and less optimal compared to the previous one, and your CSS may become bulky if you have many elements that can become green.
#sample.valid{
background-color: green;
}
Solution (Poor): Adding inline style though JavaScript
Instead of adding a class through JavaScript, you can also add inline style. Inline styles (the style
attribute), has higher precedence, so adding style="background-color: green"
will overrule the color defined in CSS.
$('#sample').css('background-color', 'green');
I wouldn't much prefer this method, since you would have to dig in your JavaScript to change the styling, end it will get really clunkcy when you want to change other properties as well. Each of the solutions above are preferable over this one.
Solution (Poor and risky): Add !important
From CSSTricks: When Using !important is The Right Choice
The unfortunate typical use case goes like this:
- WHY IS MY FRAGGLE ROCKING CSS NOT WORKING INTERROBANG
- (use !important rule)
- OK, now it's working
Then the next guy comes along and tries to
make new changes. He tries to alter some existing CSS rules, but now
his changes aren't behaving how they should....
There are some cases when !important
might be the right choice, but it should never be the quick fix for a problem like this, because in the end you'll and up with a CSS that is very hard to maintain, and various !important
s will bite each other. Only use it when you have really thought it through.