Is it bad to use !important in a CSS property?
!important
is a useful tool, but the drawback is that it's kind of a tool of last resort. So you don't want to over-use it as you'll end up causing headaches down the road for anyone that's maintaining the site.
However, your example is a typical use. What is happening is that the JS is injecting inline style attributes on the fly. As such, that's over-riding the cascade in your CSS. !important
allows you to over-ride that.
What are the implications of using !important in CSS?
Yes, I'd say your example of using !important
is bad practice, and it's very likely it would cause undesired effects further down the line. That doesn't mean it's never okay to use though.
What's wrong with !important
:
Specificity is one of the main forces at work when the browser decides how CSS affects the page. The more specific a selector is, the more importance is added to it. This usually coincides with how often the selected element occurs. For example:
button {
color: black;
}
button.highlight {
color: blue;
font-size: 1.5em;
}
button#buyNow {
color: green;
font-size: 2em;
}
On this page, all buttons are black. Except the buttons with the class "highlight", which are blue. Except that one unique button with the ID "buyNow", which is green. The importance of the entire rule (both the color and font-size in this case) is managed by the specificity of the selector.
!important
, however, is added at a property level, not a selector level. If, for instance, we used this rule:
button.highlight {
color: blue !important;
font-size: 1.5em;
}
then the color property would have a higher importance than the font-size. In fact, the color is more important than the color in the button#buyNow
selector, as opposed to the font-size (which is still governed by the regular ID vs class specificity).
An element <button class="highlight" id="buyNow">
would have a font-size of 2em
, but a color blue
.
This means two things:
- The selector does not accurately convey the importance of all the rules inside it
- The only way to override the color blue is to use another
!important
declaration, for example in thebutton#buyNow
selector.
This not only makes your stylesheets a lot harder to maintain and debug, it starts a snowball effect. One !important
leads to another to override it, to yet another to override that, et cetera. It almost never stays with just one. Even though one !important
can be a useful short-term solution, it will come back to bite you in the ass in the long run.
When is it okay to use:
- Overriding styles in a user stylesheet.
This is what !important
was invented for in the first place: to give the user a means to override website styles. It's used a lot by accessibility tools like screen readers, ad blockers, and more.
- Overriding 3rd party code & inline styles.
Generally I'd say this is a case of code smell, but sometimes you just have no option. As a developer, you should aim to have as much control over your code as possible, but there are cases when your hands are tied and you just have to work with whatever is present. Use !important
sparingly.
- Utility classes
Many libraries and frameworks come with utility classes like .hidden
, .error
, or .clearfix
. They serve a single purpose, and often apply very few, but very important, rules. (display: none
for a .hidden
class, for example). These should override whatever other styles are currently on the element, and definitely warrant an !important
if you ask me.
Conclusion
Using the !important
declaration is often considered bad practice because it has side effects that mess with one of CSS's core mechanisms: specificity. In many cases, using it could indicate poor CSS architecture.
There are cases in which it's tolerable or even preferred, but make sure you double check that one of those cases actually applies to your situation before using it.
Is !important bad for performance?
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.
*
* ...
*/
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.Firefox then creates style context trees which contain the end values
(after applying all rules in the right order)
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.
When to use the !important property in CSS
This is the real life scenario
Imagine this scenario
- You have a global CSS file that sets visual aspects of your site globally.
- You (or others) use inline styles on elements themselves which is
usuallyvery bad practice.
In this case you could set certain styles in your global CSS file as important, thus overriding inline styles set directly on elements.
Actual real world example?
This kind of scenario usually happens when you don't have total control over your HTML. Think of solutions in SharePoint for instance. You'd like your part to be globally defined (styled), but some inline styles you can't control are present. !important
makes such situations easier to deal with.
Other real life scenarios would also include some badly written jQuery plugins that also use inline styles...
I suppose you got the idea by now and can come up with some others as well.
When do you decide to use !important
?
I suggest you don't use !important
unless you can't do it any other way. Whenever it's possible to avoid it, avoid it. Using lots of !important
styles will make maintenance a bit harder, because you break the natural cascading in your stylesheets.
Should I avoid using !important in CSS?
Use !important
very, VERY sparingly -- it overrides just about everything, even inline styles, and messes in a less-than-obvious way with the "cascade" of style rules that gives CSS its name. It's easy to use badly, and tends to multiply, particularly when misused. You can easily end up with a element with !important
rules that you want to override, at which point you often have to either refactor your styles, or use another !important
rule and contribute to the problem.
And once it's spread and you're using it everywhere, you're back up in the same situation you'd be in without it (difficulty in specifying elements specifically enough to override other styles), but you also don't have !important
anymore cause everything else is using it too.
When faced with a situation where !important
looks appealing -- or worse, one where it's already in use and spreading -- prefer to refactor your CSS if you can. (Frankly, if you need !important
outside of a user style sheet, it's usually because your selectors are already way too specific, and/or you're not taking advantage of the C in CSS.) You'd do better to define your basic styles as close as possible to the html
or body
elements, and when you want to override, use as little specificity as you can get away with. That way, you have plenty of room to make changes. Usually there's a reason you want to override a style, and those cases can quite often be boiled down to a class name, a particular section of the page (read: a particular parent element), etc.
(The only real exception that springs to mind is if the styles you're overriding are effectively out of your control. (If you use a framework that has very strong opinions on how your page should look, for example, you might find it annoyingly difficult to override anything. I've worked with applications that actually inserted their own inline styles, where nothing but an !important
rule could override them.) If you don't have full access to the code, overriding and refactoring can easily be more trouble than they're worth. You can use !important
to claw back some control, as long as you're aware of the consequences.)
Why using important in css is Bad practice?
I have modified you code. If you want hover like this.
<style type="text/css">
.menustyle a{
position: relative;
}
.menustyle a:before{
position: absolute;
top: -5px;
left: 0;
content: "";
height: 2px;
background-color: #ff0000;
width: 0%;
}
.menustyle > li > a:hover:before{
width: 100% !important;
}
</style>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul id="menu-primary" class="nav navbar-nav menustyle">
<li><a href="#">Home</a></li>
</ul>
</div>
More important than !important (a higher level !important)?
No, there is no keyword or other way to make a declaration more important than !important
. There is no known activity to change this.
In general, it is possible to override a declaration that has !important
by using a rule that also has it and that has higher specificity. However, a declaration in a style
attribute has, by definition, higher specificity than any other author declaration. The only way to defeat it is in CSS is to use a user style sheet with !important
.
There are non-CSS solutions, but they are rather obvious, such as using JavaScript to simply remove or modify the style
attribute.
How do I avoid using !important?
All !important
does is increase specificity. To avoid using !important
, all you need to do is increase specificity.
In your case, both of your selectors have identical specificity. The issue is most likely caused by your media query being placed before your "Normal CSS", and thus getting overridden.
- If they're in the same CSS file, ensure your "Normal CSS" is placed before your media query.
- If they're in different CSS files, ensure the file containing your media query is included in your HTML document after your "Normal CSS".
Is CSS as HTML Attribute Bad Practice?
Yes, it is bad practice. Here are a few reasons:
- You cannot reuse css code if it is inline (it only applies to the element it is on) so you land up writing extra code that does the same thing (e.g. you have two paragraphs of text that need to be styled the same - if you use the
style
attritibute you now have to copy and paste the style for each paragraph.) - Your code will be harder/impossible to maintain - imagine if you had to change the font on your page. If it is declared inline like this it means going to each place to find and change the code.
- You cannot easily override the CSS styles. Properties that are declared inline have the second highest priority. The only way to override a property declared inline in a CSS stylesheet is by using the
!important
keyword.
Related Topics
Equal Height Children of Flex Items
How to Target a Specific Column or Row in CSS Grid Layout
Open Link in New Tab or Window
Draw on Html5 Canvas Using a Mouse
How to Make an HTML Button Not Reload the Page
Make Footer Stick to Bottom of Page Correctly
How to Wrap Text Around a Bottom-Right Div
How to Get This CSS Text-Decoration Override to Work
Does Opacity:0 Have Exactly the Same Effect as Visibility:Hidden
How to Use Colspan and Rowspan in HTML Tables
How to Customize ≪Input Type="File"≫
Absolutely Positioned Flex Item Is Not Removed from the Normal Flow in Ie11
Change Color of Png Image Via Css
Override Browser Form-Filling and Input Highlighting With Html/Css