198

I hate them, it defies the cascading nature of CSS, and if you don't use them with care you end up in a loop of adding more !important.

But I want to know are they bad for performance?

EDIT
From the (fast) replies I can conclude it won't have a (significant) impact on performance. But it's nice to know, even if it's just as an extra argument for discouraging others ;).

EDIT 2
BoltClock pointed out that if there are 2 !important declarations the specs says it will pick the most specific one.

Martin Smith
  • 438,706
  • 87
  • 741
  • 845
janw
  • 6,672
  • 6
  • 26
  • 45
  • I don't think there is a difference. It's just another bit in the sorting key. – John Dvorak Dec 06 '12 at 12:38
  • 7
    out of curiosity, how do you evaluate the performance of CSS stylesheet? better CSS render faster or something? – xiaoyi Dec 06 '12 at 12:42
  • You could evaluate the performance of selectors (see here for more information: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/ ) – Sean Dec 06 '12 at 12:46
  • But, unless you have a VERY large site, selector performance is likely to be irrelevant. The only other real term you can measure it's performance in is in terms of file size. – Sean Dec 06 '12 at 12:47
  • This may be horrendously naive, but wouldn't it be the other way round? I mean, `!important` would stop the rendering enging from looking any further, and with that, increasing performance. – Yoshi Dec 06 '12 at 12:49
  • 4
    @Yoshi it still has to look for other `!important` rules. – John Dvorak Dec 06 '12 at 12:49
  • And it's not even the rendering engine that does cascade resolution. The rendering engine does nothing but drawing. – BoltClock Dec 06 '12 at 12:50
  • @BoltClock not if you include style resolution into the renderer (which _is_ technically incorrect). – John Dvorak Dec 06 '12 at 12:52
  • @JanDvorak for example, if `color` is in question, the first one with `!important` would remove the need to evaluate that property any further. – Yoshi Dec 06 '12 at 12:53
  • @BoltClock me using *rendering engine* is just the ignorance of not knowing a better name ;) – Yoshi Dec 06 '12 at 12:53
  • @BoltClock: Really? I'm surprised by that. My default assumption was that if two rules are `!important` that it would then use the usual arguments to judge between them (ie specificity and only last one as a last resort). Do you have a spec reference to hand or shall I go hunt myself (just thought if you had already looked it up for that comment it would save me time to have to). – Chris Dec 06 '12 at 13:32
  • @Chris: Ah yep, that's precisely it. Things like selector specificity and where it's declared (i.e. is it in an inline style or an internal stylesheet or an external stylesheet) have to be taken into account as well. It just happens that multiple important declarations can apply to the same element, like normal declarations, so they're subject to the same cascading order, just at a higher priority. Sorry I wasn't too clear in my last comment! – BoltClock Dec 06 '12 at 13:33
  • @BoltClock That's what I tried to imply. After the specificity is taken care of, wouldn't the first property with `!important` remove the need to look further *up*` (for the same property which might have `!important`)?! – Yoshi Dec 06 '12 at 13:38
  • @BoltClock this is more interesting to know than my original question. I've added it in the edit. – janw Dec 06 '12 at 13:39
  • 1
    @janw: I just clarified that it does pick the most specific one... I've removed the misleading comment. – BoltClock Dec 06 '12 at 13:42
  • @Yoshi: That's *probably* implementation dependent. Also, a single rule can have more than one `!important` declaration for the exact same property - a browser has to account for that as well. – BoltClock Dec 06 '12 at 13:44
  • @NullPointer, `[hidden] { display: none !important; }`, ok, so you did say *usually*, but I think it's more important to show people where an appropriate usage would be to have some context for understanding the appropriateness of the tool. – zzzzBov Dec 06 '12 at 14:36
  • @NullPointer When some plugins put styling inline, I have to override parameters somehow... – Christopher Marshall Dec 06 '12 at 17:26
  • 16
    random thought: The title would be *much* funnier if it read: "is !important important?" – Nik Bougalis Dec 06 '12 at 22:03
  • 60
    i always read !important as 'not important' – oɔɯǝɹ Dec 06 '12 at 22:48
  • Nah it just sucks. Hit people with a stick until they stop. They're too lazy to care about performance anyway. – Erik Reppen Dec 07 '12 at 03:17
  • @Erik Reppen: You never know... – BoltClock Dec 07 '12 at 03:33
  • Thinking about performance in web is almost like thinking about running without legs. – luke1985 Dec 25 '13 at 21:51
  • I think it should only be used to override inline styles (made by javascript). Also, some accesible kind of browsers that have rules to help the user wich might not work as expected because of the importants.. Try to make your selectors more specific and you won't need them! – Toni Michel Caubet Apr 05 '14 at 12:51
  • Here is a trick (.class.class) I use to not use !important (amongst other reasons) and that seem to fail for ID's in IE. Input will be appreciated... http://stackoverflow.com/questions/25565928/idid-repeated-occurrances-of-the-same-simple-selector-should-increase-specif – Armel Larcier Aug 29 '14 at 11:23
  • Can anyone review my answer? – Jack Jan 15 '15 at 19:40

9 Answers9

274

It shouldn't have any discernible effects on performance. Seeing Firefox's CSS parser at /source/layout/style/nsCSSDataBlock.cpp#572 and I think that is the relevant routine, handling overwriting of CSS rules.

It just seems to be a simple check for "important".

  if (aIsImportant) {
    if (!HasImportantBit(aPropID))
      changed = PR_TRUE;
    SetImportantBit(aPropID);
  } else {
    // ...
  }

Also, comments at source/layout/style/nsCSSDataBlock.h#219

    /**
     * Transfer the state for |aPropID| (which may be a shorthand)
     * from |aFromBlock| to this block.  The property being transferred
     * is !important if |aIsImportant| is true, and should replace an
     * existing !important property regardless of its own importance
     * if |aOverrideImportant| is true.
     * 
     * ...
     */

  1. Firefox uses a top down parser written manually. In both cases each CSS file is parsed into a StyleSheet object, each object contains CSS rules.

  2. Firefox then creates style context trees which contain the end values (after applying all rules in the right order)

CSS Parser Firefox

From: http://taligarsiel.com/Projects/howbrowserswork1.htm#CSS_parsing

Now, you can easily see, in such as case with the Object Model described above, the parser can mark the rules affected by the !important easily, without much of a subsequent cost. Performance degradation is not a good argument against !important.

However, maintainability does take a hit (as other answers mentioned), which might be your only argument against them.

Jason Stackhouse
  • 1,796
  • 2
  • 18
  • 19
Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
  • 90
    I like that you're the only one who bothered checking instead of assuming. Great work sir! – Moox Dec 06 '12 at 16:27
  • This object model is not the DOM, by the way... it's the CSSOM. Just in case anybody's wondering. – BoltClock Dec 06 '12 at 16:35
  • 5
    This should be the answer. I feel ashamed that my response has double the points as yours. Oh dear oh dear. Someone give this man credit where it's due! – Michael Giovanni Pumo Dec 06 '12 at 18:29
  • 3
    This post is all about parsing, and I would expect the performance impact there to be nil. Parsers are fast. The question is, what about during rendering, when the browser searches for CSS declarations matching a particular element? Is the common case where there are no `!important` rules specially optimized? I don't think so, but it is hard to be sure; the layout/style directory in Firefox is 80,000 lines of code. – Jason Orendorff Dec 07 '12 at 14:51
  • @JasonOrendorff You are right. parsing, has more similarity between different browsers than rendering which is done very differently by webkit and gecko, so it would become very specific. The tree-traversal and adding of `!important` rules is done in [**layout/style/nsStyleSet.cpp**](http://mxr.mozilla.org/mozilla2.0/source/layout/style/nsStyleSet.cpp#515). – Anirudh Ramanathan Dec 07 '12 at 15:38
  • I wish I could favorite this answer. Nice work without assumptions. – 4Z4T4R Dec 11 '12 at 18:02
  • 1
    Your efforts to check the exact source and share this high level of knowledge is simply extraordinary and amazing. People like you are the ones who makes StackOverflow so popular and trustful. Thanks so much for answering and sharing this. – Anmol Saraf Dec 12 '12 at 08:04
114

I don't think that !important is inherently bad in terms of how quickly the browser matches rules (it does not form part of the selector, only part of the declaration)

However, as has already been stated, it will reduce the maintainability of your code, and thus likely cause it to grow unnecessarily in size due to future changes. The usage of !important would also likely reduce developer performance.

If you were being really picky, you could also say that !important adds 11 extra bytes to your CSS file, this isn't really much, but I guess if you have a fair few !importants in your stylesheet it could add up.

Just my thoughts, unfortunately I couldn't find any benchmarks on how !important could affect performance.

Sean
  • 6,389
  • 9
  • 45
  • 69
  • 56
    "11 extra bytes" give or take a few bytes for optional whitespace oh god the whitespace – BoltClock Dec 06 '12 at 12:43
  • @BoltClock note the "If you were being really picky" – Sean Dec 06 '12 at 12:44
  • 11
    I know... I'm just making fun of how extremely picky people do get when it comes to performance, by taking that pickiness to the next level. – BoltClock Dec 06 '12 at 12:45
  • Nice to point out that is part of the declaration not the selector. – janw Dec 06 '12 at 13:18
  • 11
    if you're being *really* picky, the added specificity needed to do it the right way often far exceeds 11 bytes. – BlakeGru Dec 06 '12 at 15:22
  • @BG_Insight that's very debatable, it depends how your structure you HTML + CSS – Sean Dec 06 '12 at 15:46
  • 1
    @BG_Insight: [watch this link on how to avoid specificity in css](http://www.youtube.com/watch?v=R-BX4N8egEc) – Brendon Roberto Dec 06 '12 at 17:26
  • sometimes using these important extra 11 bytes could save you more bytes by avoiding a very specific css selector – xtrahelp.com Dec 06 '12 at 22:41
  • And if you're level-headed you realise that it's nowhere near 11 bytes at all because the stylesheet is served gzipped. – DisgruntledGoat Dec 07 '12 at 14:45
  • 10
    @DisgruntledGoat: A level-headed person would realize it's not bytes that are being wasted but seconds, minutes, hours, days, and neurons. (Why am I still here?) – BoltClock Dec 07 '12 at 14:49
59

!important has its place. Trust me on that one. It's saved me many times and is often more useful as a short-term solution, before a longer and more elegant method to your problem can be found.

However, like most things, it's been abused, but there's no need to worry about 'performance'. I'll bet one small 1x1 GIF has more of a performance hit on a web page than !important would.

If you want to optimize your pages, there are many more !important routes to take ;) ;)

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Michael Giovanni Pumo
  • 14,338
  • 18
  • 91
  • 140
  • 8
    It was just a bit of a fun ending, let's all smile and just...relax! – Michael Giovanni Pumo Dec 06 '12 at 12:48
  • 12
    What donkey? I have to know! – Oscar Broman Dec 06 '12 at 15:45
  • 1
    @Oscar Broman I think he means that :) :) looks like a particular part of the human anatomy that shares a common name with the other name for a donkey in the English language. "The donkey or ass," -- that is the beginning of the wikipedia article about the ass, pardon, donkey. I assume that Mr. Jan Dvorak and two upvoters are amongst the kind of people that are offended by literally every word (or smiley) that is even remotely (or in this case imaginary) offensive. However, saying donkey when you mean ass is pretty stupid and unpolite since few non English speakers would understand it. – Dimitar Slavchev Dec 06 '12 at 18:37
  • 7
    @DimitarSlavchev Jan wasn't talking about the smiley. See the [initial version of Michael's post](http://stackoverflow.com/posts/13743937/revisions) (revision 2). – andytuba Dec 06 '12 at 20:54
  • 5
    @andytuba tbh, it invalidates Dimitars argument, but not his point :):) – Grimace of Despair Dec 07 '12 at 00:30
  • Thanks for the clarification guys. I'm English...and I didn't get the donkey reference either. Apologies for the language and thanks for the edits! – Michael Giovanni Pumo Dec 07 '12 at 10:36
  • 1
    `!important routes` ... not-important routes :-) – bart s Dec 14 '12 at 13:34
32

What's going on here behind the scenes is that as your CSS is being processed, the browser reads it, encounters an !important attribute, and the browser goes back to apply the styles defined by !important. This extra process might seem like a small additional step, but if you are serving up many requests then you will take a hit in performance. (Source)

Using !important in your CSS usually means developer narcissistic & selfish or lazy. Respect the devs to come...

The thinking of a developer when using !important:

  1. My rocking CSS is not working... grrrr.
  2. What should I do now??
  3. And then !important yeah.... now it's working fine.

However its not a good approach to use !important just because we did not manage the CSS well. It creates lots of design issues -- which are worse than performance issues -- but it also forces us to use many extra lines of code since we are overriding other properties with !important and our CSS becomes cluttered with useless code. What we should do instead is first manage the CSS very well, and not let properties override one another.

We can use !important. But use it sparingly and only when there is no other way out.

enter image description here

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
14

I agree with you on not using it because it's bad practice, regardless of performance. On those grounds alone, I'd avoid using !important wherever possible.

But on the question of performance: No, it shouldn't be noticeable. It might have some effect, but it should be so tiny you should never notice it, nor should you worry about it.

If it is significant enough to be noticable then you've likely got bigger problems in your code than just !important. Simple use of a normal syntax element of the core languages you're using is never going to be a performance issue.

Let me answer your question with a retorical question in return; an angle that you probably didn't consider: Which browser do you mean?

Each browser obviously has its own rendering engine, with its own optimisations. So the question now becomes: what are the performance implications in each browser? Perhaps !important performs badly in one browser but really well in another? And perhaps in the next versions, it'll be the other way round?

I guess my point here is that we as web developers shouldn't think about (or need to think about) the performance implications of individual syntax constructs of the languages we're using. We should use those syntax constructs because they're the right way to achieve what we want to do not because of how they perform.

Performance questions should be asked in conjunction with the use of profilers to analyse where the pinch-points are in your system. Fix the things that are truly slowing you down first. There are almost certain to be far far bigger issues for you to fix before you get down to the level of individual CSS constructs.

SDC
  • 14,192
  • 2
  • 35
  • 48
7

It does not noticeably affect performance. It does however reduce the maintainability of your code, and therefore is likely to degrade performance in the long run.

Henrik
  • 3,908
  • 27
  • 48
  • 2
    @Jan Dvorak what is your problem? – Idrizi.A Dec 06 '12 at 12:41
  • @BoltClock I am refering to the first sentence. – John Dvorak Dec 06 '12 at 12:41
  • 4
    @Enve my problem is that I would like to see a benchmark, not apriori assumptions presented as facts. I don't know which one is this one. – John Dvorak Dec 06 '12 at 12:42
  • I would argue that the fact that it makes your code harder to maintain should be sufficient argument to not use it. I have never experienced any performance degradation, even when compared to other minor performance enhancements such as using ID instead of CLASS selectors. – Henrik Dec 06 '12 at 14:25
7

Having had to use !important several times before, I have personally noticed no demonstrable performance hit when using it.

As a note see the answer to this stack question for a reason you might want to use !important.

Also I'll mention something that everyone else has failed to mention. !important is the only way to override inline css short of writing a javascript function (which will effect your performance if even only a little bit). So it could actually save you some performance time if you need to override inline css.

Community
  • 1
  • 1
Ryan
  • 5,644
  • 3
  • 38
  • 66
6

hmm... !important or !!important?

Let's go through this step by step:

  1. The Parser has to check for !important for each property, regardless of whether you use it or not - so performance difference here is 0
  2. When overwriting a property, the parser has to check whether the property being overwritten is !important or not - so performance difference here is 0 again
  3. If the property being overwritten is !!important, it has to overwrite the property - performance hit of -1 for not using !important
  4. If the property being overwritten is !important, it skips overwriting the property - performance boost of +1 for using !important
  5. If the new property is !important, the parse has to overwrite it regardless of the property being overwritten is !important or !!important - performance difference 0 again

So I guess !important actually has better performance as it can help parser skip many properties that it won't skip otherwise.

and as @ryan mentions below, the only way to override inline css and avoid using javascript... so another way to avoid an unnecessary performance hit

hmm... turns out out that !important is important

and also,

  • using !important saves a lot of time for a developer
  • sometimes saves you from redesigning the whole css
  • sometimes html or the parent css file is not in your control, so it saves your life there
  • obviously prevents !important elements from being accidentally overwritten by other !!important elements
  • and sometimes browsers just don't pick the right properties, without being too specific in selectors, so using !important really becomes important and saves you from writing tonnes of specific css selectors in your css. so i guess even if you use more bytes for writing !important, it could save you bytes in other places. and we all know, css selectors can get messy.

So I guess using !important can make developers happy, and I think that's very important :D

xtrahelp.com
  • 926
  • 8
  • 14
  • 1
    "So I guess !important actually has better performance as it can help parser skip many properties that it won't skip otherwise." This statement is immediately nullified once you have multiple `!important` declarations. The browser will have to check all of them. So it's back to step 1, really. – BoltClock Dec 07 '12 at 14:26
  • 1
    @BoltClock the parser has to check for the property regardless of how many times you use it... so if you have 10 properties, the parser has to make that check 10 times regardless of whether those properties are !important or not. so if you have 10 !important properties, the parser makes the check 10 times, and if you have 10 not !important properties, the parser still makes the check 10 times... makes sense? – xtrahelp.com Dec 07 '12 at 23:10
  • Still unsure whether !important is a performance boost or not, really... but I am thoroughly enjoying all comments and discussions. My knowledge is taking its next steps forward. StackOverflow is just amazing :D – Anmol Saraf Dec 12 '12 at 08:12
4

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.

Important CSS rule meme

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

Community
  • 1
  • 1
Jack
  • 1,901
  • 1
  • 19
  • 32