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!
That’s kind of a yucky inclusion on the HTML tag. Could you at least do a little regex to clean it up?
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
.Interesting technique, but I don’t think that’s the best way to do this. And isn’t that basically just user-agent sniffing?
I covered three ways to target IE10 in this post:
http://www.impressivewebs.com/ie10-css-hacks/
I think those are much better (I didn’t come up with them; I cite references). They’re not perfect either, but as far as I know they work and they don’t require the problematic UA string detection.
See also the comments in that post that have green checkmarks, as there were some good additions and warnings about using such techniques.
I think it’s perfectly reasonable to employ User Agent sniffing to determine things like brand / platform. If brand / platform is important to your presentation or behaviour, it’s the only place to go.
I do agree that we shouldn’t use User Agent sniffing in combination with assumptions about available features / behaviours. That’s definitely best done with JavaScript, CSS Media Queries and CSS @supports.
I find user-agent sniffing perfectly reasonable in some cases with CSS. Every browser has at least one little quirk that is different than the others whether it’s a rounding issue on the margin or the way the the text is rendered. Being able to select a specific browser to fix something like that is very helpful, especially when dealing with a company that likes things to be pixel perfect.
Trying to figure out what the browser is with feature detections could cause a problem if another browser later decides to implement it. If someone wants to spoof their string, they’ll just get a less perfect experience.
Obviously feature detection is the best way to go for functionality and most other things but user-agent sniffing is still alright to use in my opinion.
Thanks bro.
I using code below:
@media screen and (min-width:0) {
/* IE9 and IE10 rule sets go here */
}
It works for me.
This is essentially user-agent sniffing via CSS. In the end, there are very few reasons why this should ever be acceptable. Chris and Dave have covered on the Shop Talk Show multiple times why UA-Sniffing is a bad practice, so I don’t need to labor that point here. In the end, this is a clever trick to target the user-agent string with your CSS selectors, but still ultimately the type of practice that breaks the web and sets us back.
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).
Always rely on features rather than mutable strings; except in rare instances. In those situations where it’s legit, this is a handsome practice for connecting your CSS to navigator properties.
Here’s a good example of needing to target IE10 only. http://codepen.io/MichaelArestad/full/KtLsl
Input fields in IE have never quite behaved likely other browsers. I’m unaware of any feature-detection involving basic placeholder text styling. IE11 recently addressed most of these behavioral bugs involving placeholder text rendering in input fields. Thus, I would need to target IE 10 instead of features. IE also does some weird things involving animations combined with a download. That wouldn’t be solved with feature detection either.
I agree that feature detection is the way to go in 99% of cases.
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?
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
< 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).
I won’t test to see if it works :D
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.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.
it’s strange to think, that with Windows 8.1 coming… by the end of 2013 IE10 will be a legacy browser.
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!
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.
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?
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!
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.
Nice article, but main think we will have to watch is that our website should work in IE 10 perfectly.
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
Well, I just use:
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.selector { property:value; }
}
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”]
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.
Thanks Chris, we’ll try to ship this in Browserhacks.com as soon as we can. :)
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.
That’s a very good point, you should never put anything from the client into your HTML unescaped.
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 :)
Hmmm… now how important that is to work for every browsers?
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.
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.
BTW, that particular string would also target Windows Phone 8: http://jonathanstark.com/blog/windows-phone-8-user-agent-string
Well, as far as I know, Windows Phones had IE10 since they first came out.
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.
Been looking IE10 specific CSS hack. Thanks for the tip Chris!
I think I’ll stick to doing user-agent checking on the server.
The way I’ve done it in the past is with a HTML tag like this:
With a <html> tag like this:
And a bit of JavaScript like this:
JavaScript uses
Util.IEVersion
to check the IE version, and CSS useshtml.ie6
throughhtml.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.I found this article to help me when I tried to solve ie10 puzzle
http://geekswithblogs.net/anirugu/archive/2013/03/02/how-to-write-css-only-for-internet-explorer–10.aspx
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.
That indeed is a clever way to write IE10 specific css but certainly not the best one.
Thankx for this tip. it is working for me
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.
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.
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.
I can confirm this worked to target IE10 on a Windows Phone 8. Thanks for posting this gem!
This does not work in IE 11
The method itself still works with IE11. However, since IE no longer reports as MSIE, you need to detect differently:
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.
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.
Hi there!
Nice technique…but does this work for IE11.0 as well?
I already use
for IE10, but i have some issues styling some few elements in IE11.0
Cheers!
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….
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
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!