Grow your CSS skills. Land your dream job.

IE 10 Specific Styles

Published by Chris Coyier

Conditional comments are gone in IE 10. That's good. IE 10 is a very good browser. Feature detection is a better way to go in nearly all cases. But what if you find some styling situation where you absolutely need to target IE 10? I guess you'll have to do this.

Rogie posted a really simple idea a while back that should still work great for this. Add the User Agent to the <html> element with a tiny bit of JavaScript:

var doc = document.documentElement;
doc.setAttribute('data-useragent', navigator.userAgent);

IE 10's User Agent string is:

Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)

Which will result in:

<html data-useragent="Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)">

And you can then style like:

html[data-useragent*='MSIE 10.0'] h1 {
  color: blue;
}
Check out this Pen!

Comments

  1. That’s kind of a yucky inclusion on the HTML tag. Could you at least do a little regex to clean it up?

    • Jeremy
      Permalink to comment#

      It’s funny we so often utilize another yucky things when trying to get rid of the first one. I’d suggest just using a simple method to do this job, probably indexOf.

      var doc = document.documentElement;
      doc.setAttribute(
          'data-useragent',
          (navigator.userAgent.indexOf("MSIE 10.0") !== -1 ? "MSIE 10.0" : "no-MSIE 10.0");
      
  2. Marcel
    Permalink to comment#

    I like the approach, but it may be a bit cleaner to sniff the UA string with JS and just add the proper class to the HTML element. What do you think?

  3. Permalink to comment#

    I have a little question about selector codestyle.
    Maybe, it’s better to use classic Irish classes style like , what do you think?
    Look like .ie10 mush easier to use

    • Permalink to comment#

      < html class=”ie10″>, I mean

    • I think the point here is to allow you the power of targeting any part of the user-agent string to begin with, without using JavaScript to look for specific parts. After all, your JavaScript would potentially get a little verbose if you want to include Chrome, Safari, Firefox, Opera, and Internet Explorer. Toss a few version numbers on top for added frustration. The beauty of this approach (though the practice is still bad) is that you can put that effort into your CSS instead, where many people feel more comfortable.

    • Ivan, you can use Paul Irish’s conditional classes only with IE6-9, not IE10. That’s why Chris posted this, because you can’t target IE10 with CC’s. (See the first link in the post).

  4. I won’t test to see if it works :D

  5. Sadly this is needed. So far, IE10 does not render like Chrome or FF. This bit: html[data-useragent*='MSIE 10.0'] — is a little long-winded, but simple enough to create a snippet in TextExpander. Thanks Chris!

    • Scott, I would be curious what you have found in IE10 that deviates so greatly from Chrome/FF that it would merit the use of ua-sniffing. In my experience IE10 is an outstanding browser that rarely provides a substantially different experience than that of Chrome or Firefox. I know of a few areas (such as progressively-enhanced form elements like <metric>, <input type='number'>, and <range>) that look different, but not broken.

    • Jamie
      Permalink to comment#

      border-collapse is one for IE10, there are also a few weird bugs around gradients and backgrounds for IE and Chrome.

      Firefox has issues with outline-offset.

      For an experience that is pretty much unified across Firefox/Chrome and IE you unfortunately need these hacks.

    • thewoozle
      Permalink to comment#

      it’s strange to think, that with Windows 8.1 coming… by the end of 2013 IE10 will be a legacy browser.

  6. Jozsef Kerekes
    Permalink to comment#

    Well, conditional comments were the best way to sniff out browsers because they were activated soon as the page loaded. When you sniff out browsers like IE and put some class on the body, like msie and then you have in css IE specific styling for this .msie class, it can be verry slow. IE7, IE8 has an ugly flicker because of the delay, untill javascript loads and adds the class on the body.Conditional comments work instantly, html solutions is always faster then js solution.

    Nice post @Louis!

    • Permalink to comment#

      If your initial HTML is constructed dynamically by the server, then the server code (e.g. Ruby, PHP, JavaScript, whatever) can inject the “data-…” attribute. Then the CSS can be active before JavaScript executes.

  7. Just looking at conditionizr and it detects for ie10 (and can serve based on that) – Does anyone know what method that uses to actually detect ie10?

  8. Jon Humphrey
    Permalink to comment#

    Brilliant tips once again Chris, thank you! :-D

    Quick question for all: am I the only one who finds myself using attribute selectors more and more these days as you can isolate elements by various and sundry values across browsers without proprietary bells and whistles?

    Just curious on other’s usage and investigations really?

    Cheers!

  9. I’d like to see a real world use case for this. I have yet to run into anything in IE10 that would make this a requirement, and as you say feature detection is a much better way to go.

    I’m actually surprised you posted this as the general attitude toward UA sniffing is ‘NEVER; it’s unreliable’.

    It’s a smart way of doing it, but I’m wondering if it should be done at all.

  10. Nice article, but main think we will have to watch is that our website should work in IE 10 perfectly.

  11. I wrote a tiny JavaScript plugin called Layout Engine which feature detects IE10 and every other type of browser, and gives you a class on HTML and a JS object to use.

    Take a look here: http://mattstow.com/layout-engine.html

  12. Well, I just use:


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

    • Michael McGuire
      Permalink to comment#

      Setting-up a new site scaffold today, I decided to use a variant of this, incorporating several different ideas I found trolling around the web. This adds the browser to as a class and adds the version as an INT if its IE. For instance, IE-10 returns ‘[html class="MSIE-10" lang="en"] ‘ while Chrome returns [html lang="en" class="Chrome"]

      function get_browser(){
          var N=navigator.appName, ua=navigator.userAgent, tem;
          var M=ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
          if(M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
          M=M? [M[1], M[2]]: [N, navigator.appVersion, '-?'];
          return M[0];
      }
      function get_browser_version(){
          var N=navigator.appName, ua=navigator.userAgent, tem;
          var M=ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
          if(M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
          M=M? [M[1], M[2]]: [N, navigator.appVersion, '-?'];
          return M[1];
      }
      var browser=get_browser();
      if (browser=="MSIE") {
          browser += '-'+ parseInt(get_browser_version())
      }
      
      $('html').addClass(browser);
      
    • Not sure why one would have to target standards compliant browsers these days, and with JavaScript too.

      Nonetheless, interesting script you have here, thanks for posting it. I will add it to my toolbox.

  13. Thanks Chris, we’ll try to ship this in Browserhacks.com as soon as we can. :)

  14. Philip Taunton
    Permalink to comment#

    Be very careful about putting the full user agent into any part of a web page. There is a known security exposure where a user can supply a malicious user agent string to achieve an XSS exploit of the site. Parsing the user agent string for known values such as “MSIE 10.0″ is a safer option.

    • Lee Kowalkowski
      Permalink to comment#

      That’s a very good point, you should never put anything from the client into your HTML unescaped.

  15. Permalink to comment#

    I’d love to know the percentage of css-tricks visitors who actually saw that text in blue! I’m guessing 90% saw black text :)

  16. Hmmm… now how important that is to work for every browsers?

    • Michael McGuire
      Permalink to comment#

      I recently had an issue where a page header was perfect in Chrome but the font/text was to long in firefox and wrapped. If I made it smaller for firefox, it looked to short in Chrome. With this, I can give them different font-sizes.
      Ditto, there’s a odd bug with Safari when you have a draggable popup that also has a vertical scroll bar, clicking on the scrollbar sticks the popup to the cursor with no ‘mouse-up’ event. I can make the popup not draggable in safari.

    • Lee Kowalkowski
      Permalink to comment#

      Work as in function? Extremely. First time users of your broken site are probably not going to try to see if it’s their browser.

      Work as in pixel-perfect/exact-same rendering in every browser? Futile. Users of your site are probably blissfully unaware that it looks better or worse in a different browser.

  17. Adam Stoffel
    Permalink to comment#

    BTW, that particular string would also target Windows Phone 8: http://jonathanstark.com/blog/windows-phone-8-user-agent-string

  18. My idealistic self says “don’t do this”, as under almost every situation, you should’t need to browser sniff (and that is basically what this technique is) on a modern browser. And I consider IE10 to be a modern browser. However, my pragmatic side says that “OK, this is a smart technique (that I’m surprised wasn’t thought of earlier), and under very specific situations, it could be a useful weapon in the arsenal.”

    However, what I would disagree with is making this a technique for targeting IE10. Every browser has certain bugs that are hard to work around. Just looking around Stackoverflow you’ll see developers bemoaning how xyz thing doesn’t work as they’d expect in Firefox, or Opera, or what have you. There is no reason why this can’t be used for any other browser either. The use case is just as legitimate (or illegitimate) for any modern (or old) browser.

    I would only consider using this technique if it is actually a bug (rather than say the browser acting differently to your favourite browser as you didn’t test until the end, and it could even be your favourite browser at fault – no kidding, I’ve seen posts where people complain all other browsers except their favourite are wrong), and there are no ways you can work around the issue by other means. It is often possible to not trigger a bug by using a slightly different but equally valid technique than the one that exhibits the buggy behaviour. For many browsers (especially old IE), the bugs are well known and a skilled developer can avoid them like an experienced Minesweeper. For example, IE10 doesn’t support rem units for the font-size in the font shorthand. It is easy enough to work around. Just define font-size again after the shorthand, or avoid the shorthand altogether (the font shorthand often resets things you don’t want, such as the line-height, anyway).

    Having said all that, I prefer this approach to using Media Query hacks to target IE10. The good thing about this approach is it will break in IE11. The MSIE token isn’t included (at least currently). As browsers in active development fix their bugs, if you target future browsers, then the browser will be penalised for fixing the bug and could break. This will likely happen with the IE specific media feature technique. With this technique, the selector will no longer match, and it will not give the workaround. This will, of course, break IE11 and beyond if the bug is not fixed, but I think the approach of having to revisit, re-evaluate and maintain your hacks is better than damning a browser for all eternity due to its past transgressions. That is a reason why UA strings have become like a song and dance around avoiding bad sniffing, and crazy things like document and browser mode switching exists.

    So, use if you really really must, after exhausting all other options, but proceed with caution, and remember, that this is equally valid for any browser. IE10 isn’t the odd man out, and the only one that needs hacks.

    • Conceptually you’re correct, this principle/technique would apply for any browser.

      But I have to say: I’ve never had to use any hacks to target Firefox, Chrome or Opera exclusively. I did once for Safari a very long time ago when it first came out for Windows (and learned my lesson some time after when Firefox was upgraded), but other than that, no hacks of any kind for standards compliance browsers.

      For IE… ALL IEs I must say, plenty of hacks of all sorts, we all have.

      Which brings me to my point: Technology-wise I’d have to disagree with you that the technique described here applies for any browser.

      I think that if this technique is valid at all, it’s valid only for ANY IE instead.

  19. Been looking IE10 specific CSS hack. Thanks for the tip Chris!

  20. Ryan
    Permalink to comment#

    I think I’ll stick to doing user-agent checking on the server.

  21. The way I’ve done it in the past is with a HTML tag like this:
    With a <html> tag like this:

    <!--[if lt IE 7 ]> <html lang="en" class="ie ie6"> <![endif]-->
    <!--[if IE 7 ]>    <html lang="en" class="ie ie7 non-ie6"> <![endif]-->
    <!--[if IE 8 ]>    <html lang="en" class="ie ie8 non-ie6"> <![endif]-->
    <!--[if IE 9 ]>    <html lang="en" class="ie ie9 non-ie6"> <![endif]-->
    <!--[if (gt IE 9)|!(IE)]><!-->
    <html lang="en" class="non-ie non-ie6">
    <!--<![endif]-->
    

    And a bit of JavaScript like this:

    // Based off James Padolsey's IE detection - http://james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/
    Util.IEVersion = (function () {
        var undef, v = 3,
            div = document.createElement('div'),
            all = div.getElementsByTagName('i');
        while (div.innerHTML = '', all[0]);
        return v > 4 ? v : undef;
    } ());
    
    // IE 10 no longer supports conditional comments in HTML, but does support JavaScript conditional comments
    // This will have to be revisited once IE 11 comes out... :(
    if (/*@cc_on!@*/false && !Util.IEVersion) {
        Util.IEVersion = 10;
        document.documentElement.className = document.documentElement.className.replace('non-ie', 'ie ie10');
    }
    

    JavaScript uses Util.IEVersion to check the IE version, and CSS uses html.ie6 through html.ie10. The last JavaScript snippet is making an assumption – If JavaScript conditional comments are supported, but HTML conditional comments are not, the browser must be IE 10. Of course, this will also match future IE versions, until JavaScript conditionals are removed.

  22. kris
  23. I am having a big issue using joomla as my CMS and ie not recognizing my css. I’ve tried pretty much all of your suggestions and still have been unsuccessful. It’s a single page that I restyled just to keep the branding consistent. Looks good in all browsers except IE.

  24. rakesh juyal
    Permalink to comment#

    That indeed is a clever way to write IE10 specific css but certainly not the best one.

  25. marmik
    Permalink to comment#

    Thankx for this tip. it is working for me

  26. Gerald
    Permalink to comment#

    Thanks for this post Chris! This was hugely helpful.

    I’m using the detection code above to deal with the fact that when using Modernizr, IE10 tests positive for flexbox support… but doesn’t fully support flexboxes.

    By sniffing for IE10, I can back out my CSS flex class that was added as a result of the ‘false positive’ Modernizr test.

    The above would be insufficient when 10.1 ships, or when another browser ships with a similar super-string like AMSIE 10.01, or if Microsoft decides to change the UA String to simply “IE 10.0″ (talk of this happening following the IE11 leaks).

    I want this code snippet to be insufficient and break when something changes or if a new version of IE is released. If and when that happens, it may mean that CSS3 flexbox support changed. I only want this code snippet to work on the current ‘in-between’ version of IE10.

  27. Chris S
    Permalink to comment#

    Thank you for this article! I hadn’t really thought about using this method to narrow down the browser using CSS. Ignore the naysayers. It’s still a great method.

  28. Permalink to comment#

    I can confirm this worked to target IE10 on a Windows Phone 8. Thanks for posting this gem!

  29. ScarLight
    Permalink to comment#

    This does not work in IE 11

    • Chris Stahl
      Permalink to comment#

      The method itself still works with IE11. However, since IE no longer reports as MSIE, you need to detect differently:

      html[data-useragent*='Trident/7.0'] h1 {
            color: blue;
          }
      

      As noted here

    • Although technically possible, I would like to think that we don’t need to target IE11.

      So to ScarLight’s point, this doesn’t work in IE11… and that’s the whole point, that it shouldn’t.

  30. Jennifer
    Permalink to comment#

    IE 10 is not a very good browser. A very good browser would function like Firefox when it reads css code and IE 10 does not do that.
    In fact, IE has always had problems with css, that is why conditional comments were necessary in the fist place.
    Getting rid of conditional comments now just makes us have to write more code and it makes a lot of people just waste a lot of time.

  31. Marcel
    Permalink to comment#

    Hi there!

    Nice technique…but does this work for IE11.0 as well?

    I already use

    `@media screen and (-ms-high-contrast: active) (-ms-high-contrast: none) {}`
    

    for IE10, but i have some issues styling some few elements in IE11.0

    Cheers!

  32. VZAN
    Permalink to comment#

    Hi Marcel, There is a fix for IE11,

    Use the same codes from the above,

    For JavaScript,

    var b = document.documentElement;
    b.setAttribute(‘data-useragent’, navigator.userAgent);
    b.setAttribute(‘data-platform’, navigator.platform);
    alert(navigator.userAgent+”**********”+navigator.platform);

    I’ve tested it, you will get alert, in that you can see that “useragent & platform with rv:11″

    For the css use this code:

    html[data-useragent*='rv:11.0'] h1 {
    color: blue;
    }

    h1{
    margin-top:50px;
    margin-left:50px;
    }

    It works for me, hope it will works for u….

  33. Alex
    Permalink to comment#

    Not sure if it is because of windows 8.1 IE update
    This works for me in IE 10,11 versions, all you need to do is check for conditional stylesheets and add also ie8,ie9

            if (document.documentMode===10){
                document.documentElement.className+=' ie10';
            }
            else if (document.documentMode===11){
                document.documentElement.className+=' ie11';
            }
    
  34. Larry

    I’m aware the user agent sniffing is bad practice and stuff but I have a deadline to hit before we go into UAT and need a quick fix for IE 10. Thanks a million Chris!

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".