I can't foresee !important
impeding performance, not inherently anyway. If, however, your CSS is riddled with !important
, that indicates that you've been over qualifying selectors and being too specific and you've run out of parents, or qualifiers to add specificity. Consequently, your CSS will have become bloated (which will impede performance) and difficult to maintain.
If you want to write efficient CSS then you want to be only as specific as you need to be and write modular CSS. It's advisable to refrain from using IDs (with hashes), chaining selectors, or qualifying selectors.
IDs prefixed with #
in CSS are viciously specific, to the point where 255 classes won't override an id (fiddle by: @Faust). ID's have a deeper routed problem too though, they have to be unique, this means you can't re-use them for duplicate styles, so you end up writing linear css with repeating styles. The repercussion of doing this will vary project to project, depending on scale, but maintainability will suffer immensely and in edge cases, performance too.
How can you add specificity without !important
, chaining, qualifying, or IDs (namely #
)
HTML
<div class="eg1-foo">
<p class="eg1-bar">foobar</p>
</div>
<div id="eg2-foo">
<p id="eg2-bar">foobar</p>
</div>
<div class="eg3-foo">
<p class="eg3-foo">foobar</p>
</div>
CSS
.eg1-foo {
color: blue;
}
.eg1-bar {
color: red;
}
[id='eg2-foo'] {
color: blue;
}
[id='eg2-bar'] {
color: red;
}
.eg3-foo {
color: blue;
}
.eg3-foo.eg3-foo {
color: red;
}
JSFiddle
Okay, so how does that work?
The first and second examples work the same, the first is literally a class, and the second is the attribute selector. Classes and Attribute selectors have identical specificity. .eg1/2-bar
doesn't inherit its color from .eg1/2-foo
because it has its own rule.
The third example looks like qualifying or chaining selectors, but it's neither. Chaining is when you prefix selectors with parents, ancestors, and so on; this adds specificity. Qualifying is similar, but you define the element the selector's applying to. qualifying: ul.class
and chaining: ul .class
I'm not sure what you'd call this technique, but the behavior is intentional and is documented by W3C
Repeated occurrances of the same simple selector are allowed and
do increase specificity.
What happens when the specificity between two rules is identical?
As @BoltClock pointed out, If there's multiple !important declarations then
spec dictates that the most specific one should take precedence.
In the example below, both .foo
and .bar
have identical specificity, so the behavior fallsback to the cascading nature of CSS, whereby the last rule declared in CSS claims precedence i.e. .foo
.
HTML
<div>
<p class="foo bar">foobar</p>
</div>
CSS
.bar {
color: blue !important;
}
.foo {
color: red !important;
}
JSFiddle
!important
rules. – John Dvorak