It’s very likely that you’ve dropped support for IE6 in your designs, seeing as the worldwide share for that browser is below 5% and declining each month.
And if you’re developing websites or web apps in any technology-related niche (like web design), then IE6 visitors are probably even lower. For this website, IE6 visitors since January 1, 2011 account for about 0.5% of users, and in the last 30 days, that’s dropped to about 0.3%. You might have similar stats.
For this reason, it’s more than likely that the only CSS hacks you’ll need are for IE7 and IE8. Firstly, if you follow some basic CSS coding principles, then you might very well need no hacks or workarounds for IE7 and IE8. For the design of this blog, I currently have zero very few IE-specific hacks — so it’s obviously possible to get by without relying too strongly on hacks. (Update: I’m no longer supporting IE6 on this site, so that does help greatly).
Nonetheless, many beginners may need ways to target IE7 and/or IE8. Here I outline the best methods for doing so.
Paul Irish’s Conditional Classes
The best method, by far, is the conditional classes technique popularized by Paul Irish. Here’s how you do it:
<!--[if lte IE 7]> <html class="ie7"> <![endif]--> <!--[if IE 8]> <html class="ie8"> <![endif]--> <!--[if IE 9]> <html class="ie9"> <![endif]--> <!--[if !IE]><!--> <html> <!--<![endif]-->
This uses conditional comments to target certain versions of Internet Explorer, and the <html>
element receives a custom class name for different versions of IE, and no class name when the browser is not IE.
Then in your CSS, you would target IE7 or IE8 like this:
.element { margin-bottom: 20px; } .ie7 .element { margin-bottom: 10px; } .ie8 .element { margin-bottom: 15px; }
Every browser will have a bottom margin of 20px on the element in question, but IE7 and IE8 will have a bottom margin of 10px and 15px respectively.
It’s important to note here that although targeting IE is necessary at times, I strongly suggest you try to find a better way to fix any browser differences, and avoid using conditional classes or any of the hacks mentioned below, if at all possible. Sometimes you just need to rethink your CSS and possibly your markup, and you can avoid this extra code from the start.
CSS Hacks
Another way to target IE7 or IE8 is using hacks.
First, how to target IE7 only. There are probably more than just two ways to do this, but here are two (which is really all you’ll need):
* + html .element { margin-bottom: 10px; }
(Thanks to Anthony for the tip on this first one, above)
The hack is the part of the selector that comes before .element
. No other browser will recognize that selector, so the 10px bottom margin will only appear to users of IE7.
Here’s another less memorable method:
*:first-child+html .element { margin-bottom: 10px; }
Yet another way to target IE7 is like this:
.element { margin-bottom: 20px; *margin-bottom: 10px; }
The “hack” is the asterisk at the start of the line of CSS that you want to apply to IE7. The only problem here is that this will also apply to IE6. So you should only use this if you know that this hack will look fine in IE6, or if you don’t care what it looks like in IE6. So if you’ve dropped support for IE6, then this should be fine.
From my research on this subject, there does not appear to be a way to target only IE8 (and not IE6, IE7, and IE9+) with a CSS hack. The only way seems to be using a conditional comment.
However, if you’ve dropped support for IE7, then you could use the following:
.element { margin-bottom: 20px; margin-bottom: 10px\9; }
The “hack” is the \9
following the value and preceding the closing semicolon. This will target IE8 and below, so you should only use this as an IE8-only hack if you no longer support IE6 or IE7 (because both those versions will apply the style in this hack).
Conditional Comments
Finally, you could separate your CSS for IE7 and IE8 into separate files, using conditional comments, like this:
<!--[if IE 7]> <link rel="stylesheet" href="ie7.css"> <![endif]--> <!--[if IE 8]> <link rel="stylesheet" href="ie8.css"> <![endif]-->
But I do not recommend you use this method. This has two main problems: First, it separates your CSS into three different files, making it much harder to maintain. And second, you’re adding extra HTTP requests in two of the slowest browsers, making your pages load much more slowly.
So my suggestion is to use either the conditional classes or else a simple hack to target IE7 or IE8.
*:first-child+html .element
A tad complicated, don’t you think?
* + html .element
works very well, afaik.
You’re right. I’ve added that one as the primary one in the article.
Thanks!
The difference is that some old Operas used to recognize
*+html
as well but not*:first-child+html
, so back in these old days it was more safe to use the latter. However, those ancient Opera versions are long gone, there should be no need for:first-child
anymore.*+html
is fine to target the one and only IE 7.I use the :not pseudo class in cases when I need different CSS for the older IE’s.
It’s valid CSS3, and I think it’s quite readable for a browser hack.
Start off with the base style, which will be used for IE 6 and 7. Make another selector and add :not(#ie6or7) to target modern browsers. Here you can overwrite the style for all browsers except IE6 and IE7.
Wow, you still get 3.2% using IE6? One of the sites I run, which isn’t even technical (though perhaps a little geeky) has 21% total IE share, made up of 0.3% IE6, 2% IE7, 7.3% IE9 and 11.6% IE8. Weird, no?
Doh! That was a mistake on my part.
My IE6 numbers are 0.3% — exactly what you said. I mistakenly drilled down to the IE numbers alone, and out of all my IE users, about 3% are IE6. I’ll correct that. Thanks for the heads up! :)
Targeting IE7 – underscore hack (not applies to IE6):
.element {
_width: 100px;
}
Nope, that’s for IE6. That will not work in IE7.
Shouldint this work?
Yes, absolutely.
But that’s assuming that you need three different values for a single property, which would rarely be the case (at least in my experience).
not likely – but quite possible, maybe not for margin but other stuffs maybe. say you are using a differnet method to style in a border to avoid inner / outer differences… its always nice to see the full stack like that.
Personally I’m not comfortable with the use of hacks like this. It doesn’t seem right to use a bug in the CSS parser to build a feature of your CSS.
I remember hacks being written about ten years ago when non-IE browsers first started to gain a better market share. Shortly afterwards they were regarded as harmful practices and their use was discouraged. It’s sad to see great blogs start to recommend their usage again. Hacks go against standards, and they just seem lazy. Why teach bad habits?
If I’m missing something I’d be happy to be enlightened.
For experienced developers, you’re absolutely right. Hacks should either never be used, or only as an absolute last resort.
Unfortunately, for beginners and others with little experience developing for IE7 and IE8, and in the face of a tight deadline, there is sometimes little option but to use a hack to get things looking right.
In some cases, hacks could even be used as temporary fixes, to roll stuff out to production on time, then re-work things later when time is not as much of a constraint.
Yes, those are good points. Everyone’s used a technique that they’re not proud of to get around limitations. I suppose it’s better to have a fuller understanding of the hack you’re using rather than apply it blind. It’d be good to mention why hacks are harmful when discussing them, especially if writing to rookie developers. Always nice to encourage people to write quality code :)
In my humble opinion, if you design for IE6 (trying to give users the same experience as in other browsers) then you have no other choice than using hacks.
Louis says that his blog is IE hack-free, but he does not mention the fact that it looks a bit broken in IE6.
And for people who still “fully” support IE6, I want to point out that the following targets both IE 7 and 6:
And that a reset would be:
Using the
_property
hack that Louis suggested in a previous comment.As a side note, if I recall, MS did not fix the
*property
hack in IE7 on purpose. To let authors address its “issues”.I think there is nothing wrong in using CSS *filters* that became features.
Imho, using CSS filters does not show “poor quality” code, it shows that you know how to style things across the board. It is certainly better than IE hacks-free styles sheets that contain things like this:
Yeah, I would never claim “hack free” if I was supporting IE6. I don’t think it’s possible to do that, especially when you incorporate PNGs and other modern techniques.
Actually, after looking again, I had completely forgotten that I was using a couple of * hacks for IE7 to get it to recognize “display: inline-block”.
So that was a little boastful of me to say I didn’t have any IE hacks. I think there are about 4 or 5 lines of them, but if I were to avoid using inline-block, then there would probably only be one or two lines at most.
Grrrr… disgusting recommendation to use hacks. If you are not supporting IE6 then very little hacks should be required. The better option IS to use the override styles targeting specific versions of IE. Remember all those IE 5 hacks that people strung together and all of a sudden their site broke in IE6 cos those hacks were interpreted some other way?
Conditional includes are much more elegant and spefically tell me that I am overriding something for a specific reason. My page CSS will also validate.
If they are n00b’s then they would be better to learn it right from the start than resort to hacks and pick up bad habits.
“Conditional includes are much more elegant…”
In which way?
Conditional Comments break the separation of concerns. They mix structure with presentation and on top of that they don’t help regarding maintenance as styles for the same elements can be found across different sheets.
Imho, using Conditional Comments is just plain wrong. It may help authors pass CSS validation, but as far as I know they are not defined in any spec. So I’m curious to know why people think they are better than CSS filters when it comes to Standards, etc.
There are also many jobs (such as my own) where styling has to be accomplished without any control over the markup. Hacks are the only way to get things looking right across all major browsers when you have no ability to move around elements or use conditional CSS.
Mini tip: you can use combinators inside conditional comments
[if (IE 7) | (IE 8)]
To target both IE 7 and 8 specifically with a single conditional comments.
The hack list from Paul Irish website:
/* IE6 */
#element { _color: blue }
/* IE6, IE7 */
#element { *color: blue; or #color: blue}
/* Everything but IE6 */
#element { color/**/: blue }
/* IE6, IE7, IE8 */
#element { color: blue\9; }
/* IE7, IE8 */
#element { color/*\**/: blue\9; }
/* IE6, IE7 -- acts as an !important */
#element { color: blue !ie; } /* string after ! can be anything */
/* IE8, IE9 */
#element {color: blue/;} /* must go at the END of all rules */
I noticed IE9 also reads
#element { color: blue\9; }
I think you’re right. I can’t test in IE9, (I keep a native IE8 install instead) but I tested in IE10 PP2, and it seems to work there, as well as in all the document modes (from IE5 and up).
I’m assuming they did that for forward compatibility but I really don’t know if it still works in the latest IE10 PP.
*+html
and* html
is valid CSS, hence safe to use._property: value
,*property: value
,property: value\9
and the like is not valid CSS. You can never be sure how browsers will process invalid code.I’d stay away from dirty hacks.
modernizr is pretty awesome too: http://www.modernizr.com/
I like using the jquery file, CSS Browser Selector. It allows you to define CSS for any OS, browser, or device in your CSS like this
.win .ie7 .classname {content}
Here us the link: http://t.co/kE8qfpbH
@Matt Woods thank’s for your post!
jQuery uses User-Agent sniffing which has never been a good idea to rely on. In version 1.9
$.browser
will eventually be removed.Hi Louis,
Thanks, You have really provided a detailed explanation of the way CSS works on IE7 and IE8.
I have an issue in CSS.I want different margin-top for IE 7 and IE 8 , but none of the solutions provided above work i.e. either I craete 2 seperate CSS files also.
Its kind of a deadlock, if it works on IE 7 it will not work on IE 8 and vice-versa.
Is it possible to have difgferent CSS classes for IE 7 and IE 8.
Yes, just use the “conditional classes” method that I discussed first.
Thanks Louis,
I will surely try the Conditional classes with more precesion.
regards
I just had a site viewer send me an email stating “On IE8 the main content comes up in one very narrow column.” I am a Mac user, not a coder. This is a “free” site for a club I belong to so want to curb discontent when possible.
The site is http://www.nwodga.org
What do I need to post [here] to get an answer as to how to fix the problem? I read through your posts but am still not sure how to proceed…
Is there any code you can add to the html that tells IE 7-8 to just go fly a kite? :-)
Hi Patty.
I just tested that site in IE8, and I don’t see the problem the viewer is claiming. I have a native install of IE8, too, so it’s not just one of those standalone versions that isn’t always accurate.
Thanks Louis.
Is there a general line of code that will over-ride IE’s defaults? Seems to me I heard that at one point.
I’m not sure exactly what you mean by that…? Override what defaults?
It seems to me that I was told IE displayed web pages by using default settings. I don’t know if it was just type sizes, or styles, had anything to do with page structure. It is one of those areas that I don’t really understand: what is it about IE that makes it display things differently?
It hasn’t been a huge deal until lately. Now that I am trying to use CSS driven designs it seems displaying issues are popping up. I must be missing something. Never a lack of things to learn! Thanks.
You might be thinking about the effects of a CSS reset. For info on CSS resets, see section #1 in this post:
http://www.impressivewebs.com/cross-browser-css-workflow/
There are lots of good links covering the history of CSS resets. IE has probably been the main reason for the need for resets, so that might be what you had in mind.
Hacks are to be preferred over conditional comments if you are opting for speed. Using modernizr is also a slowdown. Both modernizr and additional stylesheets require extra HTTP requests. Bad for performance.
Is ok to use that on my css ?
input[IE 8]{
background-color:lime !important;
}
I don’t see what the problem with using the filters * \9 , works and I can keep all my css in one stylesheet
The provided conditional classes solution is wrong because for IE < 7 and IE 9 there’s no opening
<html>
tag. Even though the tag is optional in HTML 4 and HTML5 (not in XHTML 1 and polyglot HTML5/XHTML5), keep in mind that this is the place where you should specify the language of the document, so the tag is needed.To make sure to have an openening tag in all browsers, use
That’s pretty much what Paul Irish suggests. Remarks:
1. I’ve left out IE 6 off the game; it gets the class “ie7” which is probably better than no class.
2.
!IE
should not be necessary in the last line; non-IEs don’t recognize the code in comments anyway3. Don’t use
lang="en"
for non-English content but set the value accordinglyAs you can already see, a drawback is that you have to repeat all attributes of the
html
element. There might be more than just@lang
: more classes or a page ID, a namespace in XHTML/polyglot HTML5… And you might end up withThis post was mainly concerned with discussing solutions for targeting IE7 and IE8, so that conditional classes example wasn’t meant to be complete. But since people will probably copy and paste it, I will update it. It’s actually also missing an HTML tag for IE9, to be honest.
Regarding “!IE”: It’s true non-IE browsers won’t read that anyhow, but I suppose it’s good for readability, so the developer knows which tag is seen by the other browsers.
Also, your example uses “gt IE 9”, but that’s a bit useless because IE10+ don’t support conditional comments. So it might as well be “!IE”, simply for readability.
You’re right that for browsers
!IE
would do as well asgt IE 9
. But since IE 10 is an IE,!IE
seems less appropriate thangt IE 9
to me. You have a point to include both for readability for human developers, though.In order to keep the markup clean and DRY (no pun intented), the “ie7”/“ie8”/“ie9” classes could be set with JavaScript – not using User-Agent sniffing, but conditional compilation and the IE-specific
document.documentMode
:If you still need to tell IE 6 apart from IE 7, you might use the hacky
To set a “ie10” class as well (not sure you would need such):
For Opera:
Adding the Opera version would be possible with the
window.opera
object.However, keep in mind that depending on JavaScript might not be a good idea.
The second is not an issue when you have not just additional rules for IE 7 and 8, but all the styles in the stylesheet files ie7.css and ie8.css, and don’t load the standard.css for those browsers, like so:
I agree that maintainability is a real problem here. Once you make changes in standard.css you might forget to change ie7.css and ie8.css as well. That’s why I used to raise my voice against separate stylesheets for older IEs.
However, with a CSS preprocessor you can have the best of both worlds: multiple stylesheets for various browsers generated from one single maintained source file.
can we use common hack for all IE7,8, & 9? do we have any such hack?
Yes, you can do this in your HTML:
Then in your CSS you target IE9 and lower, by doing:
And this would also target IE6, so if you need separate ones for IE6, then just add another line to your HTML to create a seperate class for IE6.
Not technically a “hack” but it will do what you’re asking for.
I am designing a site and it is on my testing server http://www.krtesting.com. It works great in Safari and Firefox but IE is the problem, like in most cases. Does anyone have any advice? I designed the site in Dreamweaver. I have got to get the spry menubar to stay in the correct space, drop down to work in IE and fix my floats. The 3 px bug is the problem I think. I have never had this problem before. Any advice would be appreciated. Thank you.
Katie, I can’t figure out what’s wrong with that menu in IE8. But you need to do a few things:
1) Validate your CSS. You have a section of CSS that looks like this:
If you look closely, you’ll see the curly braces are all messed up (not enough, too many, etc). That might not be causing the problem. From what I can tell, the problem is caused by the Spry menu script, because it seems to happen when the script is triggered.
2) The other thing you should do is create a reduced test case so you can narrow down what the problem is.
But if that’s too difficult for you, then I’d recommend a simpler drop-down menu solution. The Spry menu does not seem very easy to use, and seems too bloated for what you’re trying to accomplish. I would try something like Twitter Bootstrap’s dropdowns or Chris Coyier’s simple drop-downs.
Hey your blog messed up in IE8!! :)
IE8 is not supported in Gmail either!
* + html thing worked for me, great article.
Thanks
Dhanesh Mane
THANK YOU!!! This article is fantastic and EXTREMELY insightful into IE hacks done, well, in an organized fashion so to speak. Good read! Bookmarked for sure!
wow, thanks bro!!
Unfortunately the \9 hack is rendered in IE10. Hacks are bad, mmkay?
Conditional Complication is not a hack its a native feature of Internet Explorer.
http://www.javascriptkit.com/javatutors/conditionalcompile.shtml
Thanks for your article, it’s helpful for me.