Skip to content

Instantly share code, notes, and snippets.

@padolsey
Created August 16, 2010 20:30
Show Gist options
  • Save padolsey/527683 to your computer and use it in GitHub Desktop.
Save padolsey/527683 to your computer and use it in GitHub Desktop.
// ----------------------------------------------------------
// A short snippet for detecting versions of IE in JavaScript
// without resorting to user-agent sniffing
// ----------------------------------------------------------
// If you're not in IE (or IE version is less than 5) then:
// ie === undefined
// If you're in IE (>=5) then you can determine which version:
// ie === 7; // IE7
// Thus, to detect IE:
// if (ie) {}
// And to detect the version:
// ie === 6 // IE6
// ie > 7 // IE8, IE9 ...
// ie < 9 // Anything less than IE9
// ----------------------------------------------------------
// UPDATE: Now using Live NodeList idea from @jdalton
var ie = (function(){
var undef,
v = 3,
div = document.createElement('div'),
all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
}());
@joacim-boive
Copy link

That's not the problem. The rotation transform works in IE 7-10 with the supplied example. The problem is that using a transform with opacity and border-radius will mess up the look of the border. (The background won't be transparent.)

border-radius works natively in IE9-10 but they both have the above problem. The easies solution is to skip the opacity, but the browser(s) needs to be targeted for this and thus it's a shame they've removed conditional comments...

@SlexAxton
Copy link

You generally won't have a ton of luck using old proprietary DX Transforms and mixing it with anything. It seems like comparing the DX and the CSS3 ones is a little flawed. It's also guaranteed to be phased out eventually. Something like:

.no-css-transforms .flip {
  background-image:url(flipped-badge.jpg);
}

would be a safe way to not just back-fill IE 6-10, but also mobile browsers or any of the slew of browsers that have issues with transforms.

@wamatt
Copy link

wamatt commented Oct 1, 2012

Cool technique, does it matter if IE10 is not detected?

Copy link

ghost commented Nov 13, 2012

Hmm, I wonder if this could be rolled into an IE CSS expression that adds classes to the document. That way HTML5 boilerplate could lose the comments in the HTML and instead shift it to the CSS.

@Daniel15
Copy link

IE10 still supports JavaScript conditional comments, so you could add something like this right below this code snippet:

// 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 && !ie) {
    ie = 10;

You could potentially do user agent sniffing to ensure that it's indeed IE10.

@termi
Copy link

termi commented Feb 6, 2013

For all how what to detect IE10:
It's almost like @Daniel15 suggestion.

(function() {
  "use strict";
  var tmp = (document["documentMode"] || document.attachEvent) && "ev"
       , msie = tmp 
                  && (tmp = window[tmp + "al"])
                  && tmp("/*@cc_on 1;@*/")
                  && +((/msie (\d+)/i.exec(navigator.userAgent) || [])[1] || 0)
  ;
  return msie || void 0;
})();

user-agent sniffing, yeah :(
But this would work with:

  • any JS-preprocessors (GCC, for example, will delete all comments including conditional comments)
  • with any IDE without errors for "eval" in "strict mode"

And still like @Daniel15 said:
"This will have to be revisited once IE 11 comes out... :("

@ttfkam
Copy link

ttfkam commented Mar 2, 2013

Looks like I'm late to the party. Here's my party favor anyway.

var ie = (function(){
    // for-loop saves characters over while
    for( var v = 3,
             // b just as good as a div with 2 fewer characters
             el = document.createElement('b'),
             // el.all instead of el.getElementsByTagName('i')
             // empty array as loop breaker (and exception-avoider) for non-IE and IE10+
             all = el.all || [];
         // i tag not well-formed since we know that IE5-IE9 won't mind
         el.innerHTML = '<!--[if gt IE ' + (++v) + ']><i><![endif]-->',
         all[0];
       );
    // instead of undefined, returns the documentMode for IE10+ compatibility
    // non-IE will still get undefined as before
    return v > 4 ? v : document.documentMode;
}() );

Compatible with "use strict" (tested in Firefox 22 and Chrome 27). Uses no user agent string sniffing. Also compatible with all known JS minifiers as it uses no IE-specific JavaScript comments.

Minifies to 171 bytes.

var ie=function(){for(var a=3,b=document.createElement("b"),c=b.all||[];b.innerHTML="<!--[if gt IE "+ ++a+"]><i><![endif]-->",c[0];);return 4<a?a:document.documentMode}();

Unfortunately, it's now so small that gzip -9 yields 175 bytes.

@mvjoyner
Copy link

I needed IE10 support, as I was using the imagesloaded plugin in combination with imgrefresh (https://code.google.com/p/image-refresh/) (so to refresh unloaded images in ie), as IE still has issues with cached images! So the check had to be extended to IE10. Here's the code. I'm not a JS guru, so I've probably brutalized it, but it does work now for IE10 -- based on Daniel15's Idea.

If someone wants to make it all sparkly again, by all means.

var ie = (function(){
  var undef,
      v = 3,
      div = document.createElement('div'),
      all = div.getElementsByTagName('i');
  while (
    div.innerHTML = '',
    all[0]
  ) { 
    ver = v;
  }
  //ie10 support
  if (/*@cc_on!@*/false && typeof ver === 'undefined') {
    ver = 10;
  } else {
    ver = 3;
  }

  return ver > 4 ? ver : undef;
}());

@ecstaticpeon
Copy link

Regarding IE 10 detection and following @Daniel15's idea, we can use @_jscript_version instead of the UA (see http://msdn.microsoft.com/en-us/library/ie/s59bkzce%28v=vs.94%29.aspx):

var ie_version = (function() {
    var undef,
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');

    while (
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );

    return v > 4 ? v : undef;
}());
/*@cc_on
if (typeof(ie_version) == 'undefined') {
    ie_version = parseInt(@_jscript_version);
}
@*/

Note that we could only use that last if statement, but then that would return incorrect version numbers when changing the browser mode.

As mentioned before, this may break in IE 11.

@nrako
Copy link

nrako commented Aug 15, 2013

Beware I wasted an awful of time on a IE issue related to requirejs trying to eval the last version of this gist submitted by @ecstaticpeon. So if you use this through requirejs and have a http://requirejs.org/docs/errors.html#fromtexteval error msg, it's definitely because of /*@cc_on I just added a space like this /* @cc_on and now the eval() pass. But I didn't tested on IE10 yet... anyway I don't like this conditional compilation stuff, I'll try to find something else.

@0xadri
Copy link

0xadri commented Aug 23, 2013

@nrako: thanks for the heads up. But adding a space like you did does break the code. Try it on http://jsfiddle.net/P5z4N/4/

@0xadri
Copy link

0xadri commented Aug 23, 2013

@nrako: here is a different version that might work for you :)

Try it on http://jsfiddle.net/e8G3S/1/

// Returns the version of Internet Explorer or a -1 (indicating the use of another browser)
function getInternetExplorerVersion(){
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer'){
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
    }
  return rv;
}
function displayAlert(){
  var msg = "You're not using Internet Explorer.";
  var ver = getInternetExplorerVersion();
  if ( ver > -1 ){
    if ( ver <= 8.0 ){
      msg = "You're using Internet Explorer 8 or below" ;
    }
    else if ( ver >= 9.0 && ver < 10.0 ){
      msg = "You're using IE 9 or above";
    }
    else{
      msg = "You're using IE 10"; 
    }
  }
  alert( msg );
}

@nrako
Copy link

nrako commented Aug 26, 2013

@adrien-be indeed it fail on IE10, the last code you sent is quite different it's solely useragent sniffing, and I still love the conditional comment better, I (and requirejs) just don't like the condition compilation stuff for IE10 detection.

Copy link

ghost commented Sep 10, 2013

Smaller yet? https://gist.github.com/devxdev/6506658

I Can't test I'm on Ubuntu. maybe smaller if undefined isn't required in the last ()

@moussahoumani
Copy link

The expression in the while statement was done proper though for clarity I'd use a do-while.
Interesting :{D, fail on IE10, the last code you sent looks odd to me mainly because agent sniffing, I find the conditional comment interesting, I and requires just don't like the condition compilation stuff for IE10 detection. Because James uses a pre-increment to increment v:

Copy link

ghost commented Nov 7, 2013

(+/-) from the grade listed.

Copy link

ghost commented Nov 7, 2013

(+/-) from the grade listed.

Copy link

ghost commented Nov 7, 2013

(+/-) from the grade listed.

Copy link

ghost commented Nov 7, 2013

(+/-) from the grade listed.

@davidhellsing
Copy link

I wanted this script to include IE10+11 as well, and my tests works fine by just returning document.documentMode instead of undefined, since it will be undefined for non-IE browsers anyway (I also prefer do...while...):

var ie = (function() {
  var v = 3
    , div = document.createElement( 'div' )
    , all = div.getElementsByTagName( 'i' )
  do
    div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->'
  while 
    (all[0])
  return v > 4 ? v : document.documentMode
}())

Copy link

ghost commented Jan 23, 2014

So I tried the code above, also davidhellsing's version, and I tested this on ie8, and it always says it's version 7, when it's 8. So I don't think this works on ie8.

Copy link

ghost commented Jan 23, 2014

Also, just tried it in ie10 and ie gets declared as undefined.

@artboard-studio
Copy link

@ttfkam Best Solution for IE10+

@alextreppass
Copy link

For any future spelunkers, the @davidhellsing version just above works fine on IE8 through IE11

@tadudek
Copy link

tadudek commented Aug 8, 2014

If I'm testing IE11, but it's forced into ie8 via 'IE=EmulateIE8', this solution from @davidhellsing still show the IE version as 8, not as 11. Any thoughts? I want to determine if it's really IE10/11.

@hayatbiralem
Copy link

You can use bowser.

@taveras
Copy link

taveras commented Jun 18, 2015

This is slick!

@tamer1an
Copy link

tamer1an commented Jul 2, 2015

Unfortunately IE>=10 don't have conditional comments

@jeremykohn
Copy link

The best option for IE / Edge these days is probably Layout Engine or something similar that uses JavaScript to detect browser features.

User agents can be forged or altered so I wouldn't rely on UA sniffing.

@Webnewbies
Copy link

Maybe help:

var ie = 'NotIE'; //IE5-11
if( !!document.compatMode ) {
if( !!(Math && Math.acosh) ) ie = 'EDGE 12';
if( !!document.uniqueID){
if(!!window.ActiveXObject){ ie = 11; }
else if(!!document.all){
if(!!window.atob){ie = 10;}
else if(!!document.addEventListener) {ie = 9;}
else if(!!document.querySelector){ie = 8;}
else if(!!window.XMLHttpRequest){ie = 7;}
else if(!!document.compatMode){ie = 6;}
else ie = 5;
}
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment