45

To target elements only in IE browsers i'll use

IE6:

* html #nav li ul {
    left: -39px !important;
    border: 1px solid red;
}

IE7:

*+html #nav li ul  {
    left: -39px! important;
}

Does anyone know how to target IE8?

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • 20
    Hey, it passed ACID2, so what do you need an IE8 hack for? (Just joking...) – Boldewyn Oct 26 '09 at 09:28
  • 5
    Also, underscore before the property (div {_display:none;}) works for IE6, asterisk before the property (div {*display:none;}) works for IE7 – Dirk Diggler Jul 22 '10 at 16:35

14 Answers14

84

I'm not going to get in a debate about whether or not this method should be used, but this will let you set specific css attributes for IE8-9 only (note: it is not a selector, so a bit different than what you asked):

Use '\0/' after each css declaration, so:

#nav li ul  {
  left: -39px\0/ !important;
}

And to build off another answer, you can do this to assign variou styles to IE6, IE7, and IE8:

#nav li ul  {
   *left: -7px    !important; /* IE 7 (IE6 also uses this, so put it first) */
   _left: -6px    !important; /* IE 6 */
    left: -8px\0/ !important; /* IE 8-9 */
}

source: http://dimox.net/personal-css-hacks-for-ie6-ie7-ie8/

David Murdoch
  • 87,823
  • 39
  • 148
  • 191
Nick B
  • 7,639
  • 2
  • 32
  • 28
74

2013 update: IE10+ no longer supports conditional comments.

Original answer:

Some people seem to be confused because this does not answer the letter of the question, only the spirit - so for clarification:

There is no such thing as a browser selector. There are hacks that take advantage of bugs and/or glitches in specific browsers' CSS parsers, but relying on these are setting yourself up for failure. There is a standard, accepted way to deal with this:

Use conditional comments to target IE only.

Example:

<!--[if gte IE 8]>
<style>
(your style here)
</style>
<![endif]-->

Everything inside the two <!--> will be ignored by all non-IE browsers as a comment, and IE versions that are less than IE8 will skip it. Only IE8 and greater will process it. 2013 update: IE10+ will also ignore it as a comment.

Rex M
  • 142,167
  • 33
  • 283
  • 313
  • 3
    I'd go so far as to say "Use conditional comments to target any version(s) of IE". – Quentin Jul 22 '09 at 16:22
  • 1
    Rex nailed it. CSS hacks are called hacks for a reason - they're unprofessional programming. Use conditional comments. http://blogs.msdn.com/ie/archive/2005/10/12/480242.aspx – Jon Galloway Jul 22 '09 at 16:22
  • 7
    I guess your conditional statements do the trick, though this doesn't really answer the question by Chris who wants to know of a selector to address IE8 only – Michiel Aug 08 '09 at 20:55
  • 1
    @Michiel since that's not possible without exploiting a browser bug, the answer has two parts: a) don't do that; and b) here's how to do it instead. – Rex M Aug 08 '09 at 21:53
  • 3
    A little late, but this was not the question ;) It is not about conditional comments, but about a CSS selector. I think everyone around here knows that those are around, and the selectors are the thing that are difficult to find. – Sander Mar 22 '11 at 12:43
  • @Sander there is no such thing as a browser selector, and hacks are only setting yourself up for failure. Such questions are great opportunities for education. – Rex M Mar 22 '11 at 13:01
  • Ok, while it would seem that we can agree that this is the "right" way to fix the issue, what if you are using themes with ASP.NET (another MS product)? ASP.NET themes wires up the css files automatically in the HEAD and although the proposed solution can be done manually after the fact, it does not support ASP.NET themes (file-per-theme). – NightOwl888 Jul 30 '11 at 04:29
  • @nightowl888 a simple solution off the top of my head would be to use masterpage in your theme and manually reference the IE specific override files. – Rex M Jul 30 '11 at 04:54
  • In other words, roll my own theme solution? The only way I see around this is to not put the CSS files in the App_Themes directory where the framework automatically wires them up (or to maintain separate css files outside of the theme). – NightOwl888 Jul 30 '11 at 19:02
  • 35
    @jon "CSS hacks are called hacks for a reason - they're unprofessional programming." Well I suppose if browsers like IE8 were "professionally programmed" we wouldn't need the hacks, now would we? – Alkanshel Aug 05 '11 at 01:26
  • 1
    @Amalgovinus making your software bad because other software is bad hardly improves the situation. – Rex M Aug 05 '11 at 02:07
  • 1
    @Amalgovinius Exactly what Rex M said - as software developers, our job is to write the best code *we* can in any given circumstances. – Jon Galloway Aug 05 '11 at 19:41
  • 10
    I don't think hacky code precludes the better code. It's not the fault of the dev that hacks are needed to deal with unwieldy and legacy platforms without pulling one's hair out--I'll gladly take the scornful gazes that come with hacky presentational code so long as it displays properly in everything I can throw at it, especially considering most people who will be viewing it don't even really know what html is.. – Alkanshel Aug 11 '11 at 21:34
  • 1
    There are two factors that mean you are more likely to tolerate these unsavory hacks as a _necessary evil_: 1. IE6-8 makes up a large portion of your user base (corporate clients, anyone?) 2. For one reason or another you prefer to keep CSS in a single external file (code maintenance, deployment rituals, desire to remove one more http request). In this day and age, [modernizr](http://modernizr.com/) helps with much of this, but that as well might not be feasible in some environments. – peteorpeter Dec 08 '11 at 18:24
  • 1
    @peterorpeter modernizr is helpful, but if you're obligated to maintain the nightmare that is IE6, I don't think an extra HttpRequest for those poor souls is going to make much of a difference, whilst everyone else gets a nice, clean, non-hacked file. Being responsible for one of the largest WCMS systems out there, I can assure you fewer CSS files does *not* enhance maintainability. We went from 3 to about 200 merged at compile-time, and CSS-related bugs dropped by 95%; new changes are turned around 40% faster. – Rex M Dec 09 '11 at 01:16
  • New content added to page with ajax will not be styled with the conditional css styles so this method fails for ajax, you still need specific selectors hack. – codeassembly Jun 01 '12 at 19:58
  • 3
    Might want to mention that IE10 no longer supports conditional comments, so "IE8 and greater" should be "IE8 and IE9" – Zach Lysobey Feb 19 '13 at 19:31
26

Take a look at these:

/* IE8 Standards-Mode Only */
.test { color /*\**/: blue\9 }

/* All IE versions, including IE8 Standards Mode */
.test { color: blue\9 }

(Source: David Bloom’s CSS hack for IE8 Standards Mode)

Gumbo
  • 643,351
  • 109
  • 780
  • 844
14

you can use like this. it's better than

<link rel="stylesheet" type="text/css" media="screen" href="css/style.css" />
<!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="css/ie7.css"  /><![endif]-->
<!--[if IE 6]><link rel="stylesheet" type="text/css" media="screen" href="css/ie6.css"  /><![endif]-->
-------------------------------------------------------------

<!--[if lt IE 7 ]> <body class="ie6"> <![endif]-->
  <!--[if IE 7 ]> <body class="ie7"> <![endif]-->
  <!--[if IE 8 ]> <body class="ie8"> <![endif]-->
  <!--[if !IE]>--> <body> <!--<![endif]-->

div.foo { color: inherit;} .ie7 div.foo { color: #ff8000; }

image72
  • 141
  • 1
  • 3
11

Building upon image72's excellent answer, you could actually have advanced CSS selectors like this:

<!--[if lt IE 7]><body class="IE IE7down IE8down IE9down IE10down"><![endif]-->
<!--[if IE 7]><body class="IE IE7 IE7down IE8down IE9down IE10down IE7up"><![endif]-->
<!--[if IE 8]><body class="IE IE8 IE8down IE9down IE10down IE7up IE8up"><![endif]-->
<!--[if IE 9]><body class="IE IE9 IE9down IE10down IE7up IE8up IE9up"><![endif]-->
<!--[if gte IE 10]><body class="IE IE10 IE10down IE7up IE8up IE9up IE10up"><![endif]-->
<!--[if !IE]>--><body class="notIE"><!--<![endif]-->

so that in your css you can do this:

.notIE   .foo { color: blue;   } /* Target all browsers except IE */
.IE9up   .foo { color: green;  } /* Taget IE equal or greater than 9 */
.IE8     .foo { color: orange; } /* Taget IE 8 only */
.IE7down .foo { color: red;    } /* Target IE equal or less than 7 */

.IE8 .foo, .IE9 .foo {
    font-size: 1.2em;            /* Target IE8 & IE9 only */
}

.bar { background-color: gray; } /* Applies to all browsers, as usual */

/* Maybe show a message only to IE users? */
.notIE #betterBrowser { display: none;  } /* Any browser except IE */
.IE    #betterBrowser { display: block; } /* All versions of IE */

This is great because:

  • It's perfectly standards compliant (no ugly/dangerous css hacks)
  • No need to have separate stylesheets
  • You can easily target any version of IE as well as complex combinations
MrFusion
  • 912
  • 7
  • 16
11

CSS style only for IE8:

.divLogRight{color:Blue; color:Red\9; *color:Blue;}

Only IE8 will be Red.

first Blue: for all browsers.

Red: IE6,7,8 Only

Second Blue: IE6,7 Only


So Red = for IE8 only.

For a very complete summary of browser hacks (including Internet Explorer (IE), Safari, Chrome, iPhone, and Opera) visit this link: http://paulirish.com/2009/browser-specific-css-hacks/

Nohl
  • 329
  • 3
  • 11
SirMoreno
  • 1,109
  • 1
  • 15
  • 34
11

This question is ancient but..

Right after the opening body tag..

<!--[if gte IE 8]>
<div id="IE8Body">
<![endif]-->

Right before the closing body tag..

<!--[if gte IE 8]>
</div>
<![endif]-->

CSS..

#IE8Body #nav li ul {}

You could do this for all IE browsers using conditional statements, OR target ALL browsers by encapsulating all content in a div with browser name + version server-side

anon
  • 111
  • 1
  • 2
  • I saw something similar on the jqueryui themeroller demo http://jqueryui.com/themeroller/developertool/ Works pretty nicely... if you can control the outer markup for your page/site. Working on a major rewrite now, and using this for my IE specific code... ie6,ie7,ie8,ie9, ieold (pre-9) and noie (non-ie) ... there's only a few places where I'm getting specific, but having the option from the markup + CSS alone is nice (no relying on scripts). Though I still need scripts to apply additional styles since IE6 doesn't have attribute selectors. – Tracker1 Oct 27 '10 at 22:14
  • 1
    I don't believe this is the correct way of dealing with this. The first is fine (although why you wouldn't add a class to body is unknown to me), but putting browser-dependent content for the whole page is bad practice. It enlarges the HTML-size dramatically and makes you code hard to maintain. – Aart den Braber Jun 09 '15 at 07:24
4

In the light of the evolving thread, see below for a more complete answer:

IE 6

* html .ie6 {property:value;}

or

.ie6 { _property:value;}

IE 7

*+html .ie7 {property:value;}

or

*:first-child+html .ie7 {property:value;}

IE 6 and 7

@media screen\9 {
    .ie67 {property:value;}
}

or

.ie67 { *property:value;}

or

.ie67 { #property:value;}

IE 6, 7 and 8

@media \0screen\,screen\9 {
    .ie678 {property:value;}
}

IE 8

html>/**/body .ie8 {property:value;}

or

@media \0screen {
    .ie8 {property:value;}
}

IE 8 Standards Mode Only

.ie8 { property /*\**/: value\9 }

IE 8,9 and 10

@media screen\0 {
    .ie8910 {property:value;}
}

IE 9 only

@media screen and (min-width:0) and (min-resolution: .001dpcm) { 
 // IE9 CSS
 .ie9{property:value;}
}

IE 9 and above

@media screen and (min-width:0) and (min-resolution: +72dpi) {
  // IE9+ CSS
  .ie9up{property:value;}
}

IE 9 and 10

@media screen and (min-width:0) {
    .ie910{property:value;}
}

IE 10 only

_:-ms-lang(x), .ie10 { property:value\9; }

IE 10 and above

_:-ms-lang(x), .ie10up { property:value; }

or

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
   .ie10up{property:value;}
}

IE 11 (and above..)

_:-ms-fullscreen, :root .ie11up { property:value; }

Javascript alternatives

Modernizr

Modernizr runs quickly on page load to detect features; it then creates a JavaScript object with the results, and adds classes to the html element

User agent selection

The Javascript:

var b = document.documentElement;
        b.setAttribute('data-useragent',  navigator.userAgent);
        b.setAttribute('data-platform', navigator.platform );
        b.className += ((!!('ontouchstart' in window) || !!('onmsgesturechange' in window))?' touch':'');

Adds (e.g) the below to the html element:

data-useragent='Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)'
data-platform='Win32'

Allowing very targetted CSS selectors, e.g.:

html[data-useragent*='Chrome/13.0'] .nav{
    background:url(img/radial_grad.png) center bottom no-repeat;
}

Footnote

If possible, avoid browser targeting. Identify and fix any issue(s) you identify. Support progressive enhancement and graceful degradation. With that in mind, this is an 'ideal world' scenario not always obtainable in a production environment, as such- the above should help provide some good options.


Attribution / Essential Reading

SW4
  • 69,876
  • 20
  • 132
  • 137
4

I have a solution that I use only when I have to, after I build my html & css valid and working in most browsers, I do the occasional hack with this amazing piece of javascript from Rafael Lima. http://rafael.adm.br/css_browser_selector/

It keeps my CSS & HTML valid and clean, I know it's not the ideal solution, using javascript to fix hacks, but as long as your code is originally as close as possible (silly IE just breaks things sometimes) then moving something a few px with javascript isn't as big of a deal as some people think. Plus for time/cost reasons is a quick & easy fix.

Ammi J Embry
  • 637
  • 4
  • 17
4

In the ASP.NET world, I've tended to use the built-in BrowserCaps feature to write out a set of classes onto the body tag that enable you to target any combination of browser and platform.

So in pre-render, I would run something like this code (assuming you give your tag an ID and make it runat the server):

HtmlGenericControl _body = (HtmlGenericControl)this.FindControl("pageBody");
_body.Attributes.Add("class", Request.Browser.Platform + " " + Request.Browser.Browser + Request.Browser.MajorVersion);

This code enables you to then target a specific browser in your CSS like this:

.IE8 #nav ul li { .... }
.IE7 #nav ul li { .... }
.MacPPC.Firefox #nav ul li { .... }

We create a sub-class of System.Web.UI.MasterPage and make sure all of our master pages inherit from our specialised MasterPage so that every page gets these classes added on for free.

If you're not in an ASP.NET environment, you could use jQuery which has a browser plugin that dynamically adds similar class names on page-load.

This method has the benefit of removing conditional comments from your markup, and also of keeping both your main styles and your browser-specific styles in roughly the same place in your CSS files. It also means your CSS is more future-proof (since it doesn't rely on bugs that may be fixed) and helps your CSS code make much more sense since you only have to see

.IE8 #container { .... }

Instead of

* html #container { .... }

or worse!

jonsidnell
  • 1,210
  • 1
  • 10
  • 20
  • Just for completeness, the jQuery plugin that adds browser and platform classes that you can use in CSS (and even in your jQuery functions) is available at http://jquery.thewikies.com/browser/ – jonsidnell Apr 28 '09 at 08:17
3

I realize this is an old question but it was the first result on Google when I searched and I think I have found a better solution than the highest ranked suggestion and what the OP chose to do.

#nav li ul:not(.stupidIE) { color:red }

So technically this is the opposite of what the OP wanted, but that just means you have to apply the rule you want for IE8 first and then apply this for everything else. Of course you can put anything inside the () as long as it is valid css that doesn't actually select anything. IE8 chokes on this line and doesn't apply it, but previous IEs (ok I only checked IE7, I have stopped caring about IE6), just ignore the :not() and do apply the declarations. And of course every other browser (I tested Safari 5, Opera 10.5, Firefox 3.6) applies that css as you would expect.

So this solution, I guess like any other pure CSS solution would assume that if the IE developers add support for the :not selector then they will also fix what ever discrepancy was causing you to target IE8.

Moss
  • 3,695
  • 6
  • 40
  • 60
2

OK so, it isn't css hack, but out of frustration for not being able to find ways to target ie8 from css, and due to policy of not having ie specific css files, I had to do following, which I assume someone else might find useful:

if (jQuery.browser.version==8.0) {
   $(results).css({
         'left':'23px',
         'top':'-253px'
      });
}
Zeljko Dakic
  • 1,223
  • 1
  • 11
  • 19
1

\9 doesn’t work with font-family, instead you’d need to use “\0/ !important” as Chris mentioned above, for example:

p { font-family: Arial \0/ !important; }
Ricardo Zea
  • 10,053
  • 13
  • 76
  • 79
0

There aren't any selector hacks for IE8. The best resource for this issue is http://browserhacks.com/#ie

If you want to target specific IE8 you should do comment in html

<!--[if IE 8]> Internet Explorer 8 <![endif]-->

or you could use attribute hacks like:

/* IE6, IE7, IE8, but also IE9 in some cases :( */
#diecinueve { color: blue\9; }

/* IE7, IE8 */
#veinte { color/*\**/: blue\9; }

/* IE8, IE9 */
#anotherone  {color: blue\0/;} /* must go at the END of all rules */

For more info on this one check: http://www.paulirish.com/2009/browser-specific-css-hacks/

fernandopasik
  • 9,565
  • 7
  • 48
  • 55