CSS Hacking !important
I'm sure this has been talked about in other places, but I've never seen it, and thought I'd share.
A common misconception is that IE6 (and earlier) does not pay attention to !important rules in CSS. The truth is that this is true only part of the time. (Theoretically IE7 should get it right, and I really hope it does, but who knows any more... someone care to test?)
For those that need a quick refresher, what the !important declaration does is increase the specificity of the rule to a level above that even of inline styles and more specific selectors, or those that come later in the stylesheet. An !important CSS rule looks like the following:
li.here a {
background: #fff !important;
}
(Note: The reason I know IE pays attention to them is that I've only been able to get some rather intense CSS navigation menus to work properly after using !important in a few places. After doing so, things started working in IE6 as expected and just like they looked in Firefox/Safari...)
However, when there are two identical properties in a CSS rule, IE only applies the last property. This can be used quite handily to do things like emulate min-height or take care of those frequent few pixel differences between how IE interprets a particular item (especially nested lists used in navbars). Two quick examples:
li.here {
float: left;
margin: 3px 0 !important; /* IE ignores this unlike Fx/Saf */
margin: 3px 0 0; /* get rid of the 3px margin bug in IE6 */
}
#maincontent {
min-height: 300px;
height: auto !important; /* For Saf/Fx */
height: 300px; /* IE6 expands this if needed */
}
So why all the fuss? Because it validates unlike the underscore hack, and should survive the pending great IE7 transition period just fine. Major emphasis on "should" with a healthy dose of "hopefully" thrown in for good measure (in other words, IE7 should get it right... I hope. :P ) Enjoy!
Comments:
You are right in the exception for a quick, one- or two-shot fix within the stylesheet. As in most projects there will be compromise.
I will say since IE7 became available TODAY I have noticed that it does have rendering differences for some CSS Level 2 selectors and I have had to make some adjustments to horzontal nav-bars that used display:table; for the ul and li. I had used this on three of my sites (never again--more code than needed) and have had to make the changes to avoid crap-outs.
So I used !important a lot to make modifications easy. However, ie7 recognizes !important now. However, all ie versions also understand !anything. So I have been putting the correct code first, then adding !ie to the ie specific code.
Example:
padding-left: 10px;
padding-left: 0px !ie;
This is a quick fix and easy to find/modify when this bug is fixed in ie8, etc.
Do you have an easier better way?
Always looking for (sometimes quick and easy) solutions,
Chuck
Thank you very much for the great article. I didn't know how to use !important before, so I found it very educational.
Thank you,
Taras
PS: I submitted it to digg, so you might get a lot of traffic.
I mean really who hacks for firefox and opera? I don't, I design around firefox and opera and hack for IE. so let this save you some time and heart ache.
!important is still priceless, especially if your working in multiple stylesheets using Conditional Comments.
http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp
You'll find that most of the isses inherited from ie6 into ie7 are what's called "box model" problems. I've got three seperate ie style sheets to handle each set of problems.
Like ProWebscape I to put my standard complient css first then I use the general IE conditional (<!--[if ie]>) to import my box model haks for both browsers. I'll then import my hacks for ie6 (<!--[if ie 6]>) then follow that up with my hacks for ie7 (<!--[if IE]>).
A lot of developers think this is a lot slower than hacking one stylesheet, but in the long run this is a much faster process than troubleshooting which issues are appearing in ie7 from the "/" hack and which are native. For what it's worth you can see this in action here view source. I'm not big on semantics because frankly I don't have the time.
http://www.hiringtruckdrivers.com
and
http://www.hiringowneroperators.com
http://www.positioniseverything.net/articles/cc-plus.html
A set of conditional comments in your template, each aimed at one version (or several versions) of IE will let you style things in a very straightforward way with much less chance of things coming back to bite you, IMHO. *And* you only need one stylesheet.
Bob
You must be logged into the forums to comment. Please login
While you certainly can use the !important indicator. Sure it will validate, but good code is more than whether the validation software thinks it passes or whether it is written as the W3C intends.
For instance you can use a // to comment out a line in the CSS file and it will be parsed by IE6 and less
<code>
.some_class {
color:#000;
//color:#FC0;
}
</code>
This will certainly pass validation but it is a hack becuase it uses a flaw in the parser to render the file instead of a rule.
For readability and managability I prefer to use the well documented IE conditional comments:
<code>
<style type="text/css">@import "/_styles/common.css";</style>
<!--[if IE 7]><style type="text/css">@import "/_styles/ie7.css";</style><![endif]-->
<!--[if lte IE 6]><style type="text/css">@import "/_styles/ie6.css";</style><![endif]-->
</code>
This allows me to seperate the rules for each version of IE as needed instead on relying on shortcomings in particular browsers.
This is especially true as IE7 which was officially released today interprets some box model and spacing rules differently than the Gecko based browsers like FireFox, Safari and Netscape 7+.
In order to address all these different rendering issues it is much easier to allow the various versions of IE to poll the required CSS file and render pages without the use of hacks in the main CSS file.
All the best,
Jay