I wanted to use the Modernizr JS library to detect for some browser properties to determine what content to show or not show.
I have an app called Pano2VR which outputs both HTML5 and SWF. I need the HTML5 for iOS device users.
However, IE does not render this "HTML5" output at all. It seems their output uses CSS3 3D transforms and WebGL, one or more apparently unsupported in IE9.
So, for those users I need to display the Flash version. I was planning to use an IFRAME and either pass the SRC via a Modernizr script or document.write out the correct IFRAME code depending on browser.
All of which leads to how do I use Modernizr to detect simply IE or not IE? Or detect for CSS 3d transforms?
Or is there another way to do this?
This question is related to
html
cross-browser
modernizr
If you're looking for a JS version (using a combination of feature detection and UA sniffing) of what html5 boilerplate used to do:
var IE = (!! window.ActiveXObject && +(/msie\s(\d+)/i.exec(navigator.userAgent)[1])) || NaN;
if (IE < 9) {
document.documentElement.className += ' lt-ie9' + ' ie' + IE;
}
You can use the < !-- [if IE] >
hack to set a global js variable that then gets tested in your normal js code. A bit ugly but has worked well for me.
Well, after doing more research on this topic I ended up using following solution for targeting IE 10+. As IE10&11 are the only browsers which support the -ms-high-contrast media query, that is a good option without any JS:
@media screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none) {
/* IE10+ specific styles go here */
}
Works perfectly.
CSS tricks have a good solution to target IE 11:
http://css-tricks.com/ie-10-specific-styles/
The .NET and Trident/7.0 are unique to IE so can be used to detect IE version 11.
The code then adds the User Agent string to the html tag with the attribute 'data-useragent', so IE 11 can be targeted specifically...
Modernizr doesn't detect browsers as such, it detects which feature and capability are present and this is the whole jist of what it's trying to do.
You could try hooking in a simple detection script like this and then using it to make your choice. I've included Version Detection as well just in case that's needed. If you only want to check of any version of IE you could just look for the navigator.userAgent having a value of "MSIE".
var BrowserDetect = {_x000D_
init: function () {_x000D_
this.browser = this.searchString(this.dataBrowser) || "Other";_x000D_
this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "Unknown";_x000D_
},_x000D_
searchString: function (data) {_x000D_
for (var i = 0; i < data.length; i++) {_x000D_
var dataString = data[i].string;_x000D_
this.versionSearchString = data[i].subString;_x000D_
_x000D_
if (dataString.indexOf(data[i].subString) !== -1) {_x000D_
return data[i].identity;_x000D_
}_x000D_
}_x000D_
},_x000D_
searchVersion: function (dataString) {_x000D_
var index = dataString.indexOf(this.versionSearchString);_x000D_
if (index === -1) {_x000D_
return;_x000D_
}_x000D_
_x000D_
var rv = dataString.indexOf("rv:");_x000D_
if (this.versionSearchString === "Trident" && rv !== -1) {_x000D_
return parseFloat(dataString.substring(rv + 3));_x000D_
} else {_x000D_
return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));_x000D_
}_x000D_
},_x000D_
_x000D_
dataBrowser: [_x000D_
{string: navigator.userAgent, subString: "Edge", identity: "MS Edge"},_x000D_
{string: navigator.userAgent, subString: "MSIE", identity: "Explorer"},_x000D_
{string: navigator.userAgent, subString: "Trident", identity: "Explorer"},_x000D_
{string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},_x000D_
{string: navigator.userAgent, subString: "Opera", identity: "Opera"}, _x000D_
{string: navigator.userAgent, subString: "OPR", identity: "Opera"}, _x000D_
_x000D_
{string: navigator.userAgent, subString: "Chrome", identity: "Chrome"}, _x000D_
{string: navigator.userAgent, subString: "Safari", identity: "Safari"} _x000D_
]_x000D_
};_x000D_
_x000D_
BrowserDetect.init();_x000D_
document.write("You are using <b>" + BrowserDetect.browser + "</b> with version <b>" + BrowserDetect.version + "</b>");
_x000D_
You can then simply check for:
BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;
You can use Modernizr to detect simply IE or not IE, by checking for SVG SMIL animation support.
If you've included SMIL feature detection in your Modernizr setup, you can use a simple CSS approach, and target the .no-smil class that Modernizr applies to the html element:
html.no-smil {
/* IE/Edge specific styles go here - hide HTML5 content and show Flash content */
}
Alternatively, you could use Modernizr with a simple JavaScript approach, like so:
if ( Modernizr.smil ) {
/* set HTML5 content */
} else {
/* set IE/Edge/Flash content */
}
Bear in mind, IE/Edge might someday support SMIL, but there are currently no plans to do so.
For reference, here's a link to the SMIL compatibility chart at caniuse.com.
Modernizr can detect CSS 3D transforms, yeah. The truthiness of Modernizr.csstransforms3d
will tell you if the browser supports them.
The above link lets you select which tests to include in a Modernizr build, and the option you're looking for is available there.
Alternatively, as user356990 answered, you can use conditional comments if you're searching for IE and IE alone. Rather than creating a global variable, you can use HTML5 Boilerplate's <html>
conditional comments trick to assign a class:
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
If you already have jQuery initialised, you can just check with $('html').hasClass('lt-ie9')
. If you need to check which IE version you're in so you can conditionally load either jQuery 1.x or 2.x, you can do something like this:
myChecks.ltIE9 = (function(){
var htmlElemClasses = document.querySelector('html').className.split(' ');
if (!htmlElemClasses){return false;}
for (var i = 0; i < htmlElemClasses.length; i += 1 ){
var klass = htmlElemClasses[i];
if (klass === 'lt-ie9'){
return true;
}
}
return false;
}());
N.B. IE conditional comments are only supported up to IE9 inclusive. From IE10 onwards, Microsoft encourages using feature detection rather than browser detection.
Whichever method you choose, you'd then test with
if ( myChecks.ltIE9 || Modernizr.csstransforms3d ){
// iframe or flash fallback
}
Don't take that ||
literally, of course.
I needed to detect IE vs most everything else and I didn't want to depend on the UA string. I found that using es6number
with Modernizr did exactly what I wanted. I don't have much concern with this changing as I don't expect IE to ever support ES6 Number. So now I know the difference between any version of IE vs Edge/Chrome/Firefox/Opera/Safari.
More details here: http://caniuse.com/#feat=es6-number
Note that I'm not really concerned about Opera Mini false negatives. You might be.
Source: Stackoverflow.com