Feature Detection With Modernizr For Cross Browser Compatibility
nikhiltyagi04
Posted on February 7, 2019
Modernizr is an open-source and compact JavaScript library that allows developers to craft various levels of experiences for users depending with respect to cross browser compatibility. Modernizr helps developers to perform cross browser testing to check whether new generation HTML5 and CSS3 features are natively supported by their visitor’s browsers or not and to provide dedicated fallbacks for older browsers that are notorious for their poor feature support. Modernizr coupled with the principle of progressive enhancement helps to design cutting-edge websites layer after layer taking advantage of powerful modern web technologies without discarding users still using older browsers like IE.
How Does Modernizr Work?
Modernizr was launched in 2009 July by Faruk Ateş to battle cross browser compatibility issues in a uniform standardized manner. Today, Modernizr as feature detection library is the world’s most renowned JavaScript library offering more than 270 tests and is being used in 8.76% websites globally(half a million websites in the US alone). Instead of relying on highly untrustworthy browser detection method using “User-Agent” sniffing, Modernizr is rather based on feature detection. While browser detection is centred around the question “what browser is the visitor using?”, feature detection revolves around the question “what features are supported by the visitor’s browser”. Modernizr runs a series of javascript based feature detection tests in a user’s browser to check for cross browser compatibility for HTML and CSS by allowing you to target each browser functionality separately.
Modernizr for feature detection performs 3 basic functions:
- Adds classes indicating feature support which can be used to conditionally applying CSS styling rules to different elements.
- Creates a javascript object to check or validate support for any HTML or CSS feature in a browser.
- Allows to conditionally supply custom JS scripts or polyfills to imitate lacking features.
It’s important to remember that feature detection with Modernizr can only detect which features are supported. It cannot provide functionality for those unsupported features in an older browser. This is achieved by “polyfilling” which we will discuss later in this blog.
I have also written another blog which represents the use of @support feature queries to perform CSS feature detection for cross browser compatibility.
Setting Up Modernizr For Feature Detection
In order to perform feature detection with Modernizr, you need to add the Modernizr. js file to your project. This can be done in 2 ways:
a. Download from website: Visit the official website to build and download the JavaScript file. Click on “Add your detects” to handpick the features that you want according to your project’s needs or click on “development build” to be redirected to the build page with all the tests/detects options pre-selected. Click on the build button to download the file.
b. Using npm and command line: Modernizr can also be installed Node Packet Manager or NPM. You can install NPM here. After installing npm, open command line and enter :
npm install -g modernizr
Now include the downloaded Modernizr file in the section of your page.
<script src="modernizr-custom.js"></script>
Add “no-js” class to the <html> tag.
<!DOCTYPE html> <html class="no-js"> <head> <script src="modernizr-custom.js"></script> </head>
This “no-js” class is a necessary fallback if the user has disabled JavaScript in their browser or the browser itself does not support javascript. Once the page is loaded and in case the browser supports javascript, “no-js” class will be replaced by “js” class automatically by the Modernizr for feature detection.
- Modernizr adds several CSS classes on the root element. These classes are added based on browser’s capabilities (feature/no-feature) – classes are added for features that are supported and classes are added with a “no-“ prefix for features that aren’t supported.
For example, if Flexbox is supported by the browser, “flexbox” class will be added to the <html> tag. If it isn’t supported, “no-flexbox” class is added instead.
<html class="js no-flexbox canvas canvastext no-webgl no-touch geolocation postmessage no-websqldatabase no-indexeddb hashchange no-history draganddrop no-websockets rgba hsla multiplebgs backgroundsize no-borderimage borderradius boxshadow no-textshadow opacity no-cssanimations no-csscolumns no-cssgradients no-cssreflections csstransforms no-csstransforms3d no-csstransitions fontface generatedcontent video audio localstorage sessionstorage no-webworkers no-applicationcache svg inlinesvg smil svgclippaths">
CSS Feature Detection With Modernizr
These classes added to <html> tag by Modernizr for feature detection of CSS style properties based on whether a feature is supported by a given browser or not. Classes with “no-“ prefix will be automatically applied in browsers that do not support those corresponding features.
For example, if the box-shadow property is supported by a browser, then “boxshadow” Modernizr class is added to the tag. If it isn’t supported, then “no-boxshadow” Modernizr class is added instead. We can use just these 2 CSS classes to effectively target all browsers irrespective of their support for this particular feature. “.boxshadow” class can be used to style box-shadow around a div with horizontal offset and vertical offset of 10px, blur of 8px and spread of 15px for all the supported browsers and “.no_boxshadow” class can be used to code a fallback with thicker border width to compensate for lack of any shadow for all the unsupported browsers.
.boxshadow #box { border: 2px solid black; -webkit-box-shadow: 10px 10px 8px 10px #888888; -moz-box-shadow: 10px 10px 8px 10px #888888; } .no-boxshadow #box { border: 5px solid black; }
Thus, instead of writing heaps of code to target individual browsers using User-Agent Strings, Feature detection with Modernizr reduces the task to coding just 2 blocks of code – one for compatible browsers and the other for incompatible ones.
Another example for CSS linear-gradients:
.no-cssgradients .header { background: url("https://unsplash.it/640/425?image=44"); } .cssgradients .header { background-image: url("https://unsplash.it/640/425?image=44"), linear-gradient(red, blue); }
-
Avoid class name clash
It is quite plausible that classes created by Modernizr can clash with a pre-existing CSS class that you would have added to your stylesheet. In order to avoid such a scenario, it is advisable to add a “classPrefix” to all your Modernizr classes to make them completely unique. For example, you may already be using a class called ‘boxshadow’ which will clash with the detect class created by Modernizr by the same name. You can make use of class prefixes to easily address this problem. Make the following changes in your configuration-{ "classPrefix": "foo-", "feature-detects": ["dom/boxshadow"] }
Now instead of <html class="boxshadow">, modernizr will add <html class="foo-boxshadow">
Prevent Modernizr from adding classes to HTML tag
If you want Modernizr to not add any of its classes to your HTML tag, set “enableClasses” to false in your config file. This still excludes the no-js class. To prevent even that, set “enableJSClass” to false as well.
JavaScript Feature Detection With Modernizr
As discussed earlier, instead of trying to detect user’s browser using unreliable and now defunct User-Agent string, Modernizr rather relies on feature-detection. Modernizr runs a series of javascript based checks or tests in the background during page load to detect whether features are supported by the browser or not. These tests return a Boolean value – “True” if a feature is supported and “False” is it isn’t. Using these Boolean results, it creates a javascript object called “Modernizr”. We can access various properties of this object ‘Modernizr’ for feature detection using “Modernizr.featureName”. For example, Modernizr.video will return “true” if the browser supports the video element, and false if the browser doesn’t.
Below is the syntax used for feature detection with Modernizr using JavaScript:
if (Modernizr.feature) { /* Rules for browsers that support this feature*/ } else{ /* fallback for browsers that do not support this feature*/ }
The Modernizr object helps to validate the support for CSS as well as HTML features. This is where Modernizr offers a clear advantage over native CSS feature detection using @supports feature queries. We can use this capability of Modernizr to code necessary fallbacks for important HTML5 elements like canvas, video, audio and semantic elements like article, nav, header, footer etc.
Following example shows how to test for CSS linear gradients using javascript and adding linear gradient class for browsers that support it.
$(document).ready(function () { if (Modernizr.cssgradients) { alert("This browser supports CSS Gradients"); $('#box').addClass('cssgradients'); } if (Modernizr.cssgradients) { alert("This browser doesn't support CSS Gradients"); $('#box').addClass('no-cssgradients'); } });
Apart from feature detection using javascript to test whether a browser supports that particular web technology or not, Modernizr can also be used for loading polyfills/shims to imitate the features that a browser lacks or does not support.
What Are Polyfills?
A Polyfill is a javascript code that acts as a fallback to imitate modern functionality in older browsers that natively do not support such features. For example, if you want to embed a video on your website, you would use HTML5 <video> tag. This is compatible with every modern browser. However, older legacy browsers like Internet Explorer 8 and its previous versions do not support <video> feature. To make sure that any user still using these browsers are not excluded from viewing such content, we use a popular polyfill called mwEmbed Video Player. For Canvas the most popular polyfill is FlashCanvas, for SVGs – svgweb, for audio – SoundJS etc.
Loading Polyfills Using JavaScript
As discussed earlier, apart from performing javascript tests for browser support, Modernizr can also be used to conditionally load polyfill/shim scripts to provide functionality when a browser lacks feature support. This is achieved by the use of Modernizr.load() method.
Modernizr.load
Modernizr.load method is a conditional loader based on an extremely popular yesnope.js library which loads JavaScript files based on the result of a feature detection test. For example, we can use modernizr.load method to test for the availability of support for flexbox and load a polyfill if the browser does not support it.
If the browser supports flexbox, flexlayout .css file will be loaded otherwise in case of lack of support, matchHeight.js polyfill will be loaded which imitates the flexbox feature in older browsers.
Modernizr.load({ test: Modernizr.flexbox, yep : 'flexlayout.css', nope: 'matchHeight.js' });
Modernizr.load() takes the property defining a feature as an argument and performs a test to check its support. If the property is supported and test succeeds, the “yep” case script is loaded. If the property isn’t supported and the test fails, the “nope” case script is loaded. If a script is to be loaded regardless of whether the test fails or not – “both” case. For example:
Modernizr.load({ test: Modernizr.canvas, yep: 'Canvasavailable.js', nope: 'FlashCanvas.js', both: 'CustomScript.js' });
Modernizr.load() can also be used in cases where you want to create a fallback in case Google or Microsoft CDN networks are not accessible which can wreck your entire webpage. Without CDN the jquery or bootstrap scripts will not load if you included them using CDN links. The following example shows how to create a backup for loading jquery if CDN fails. It will first attempt to download jQuery from Google CDN, the use the function corresponding to “complete” case to check if jQuery is present or not. If jQuery is absent because it couldn’t be downloaded from Google CDN, “load” case will load the backup jquery from your local storage.
Modernizr.load([ { load: '//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js', complete: function () { if (!window.jQuery) { Modernizr.load('js/libs/jquery/3.3.1/jquery.min.js'); } } }, { // execute this if jquery couldn’t be loaded. load: 'backup-jquery.js' } ]);
Modernize.load AND yesnope.js Deprecated
NOTE: Modernizr.load and yesnope.js have now been deprecated and no longer supported by the current version of modernizr(v3.5). You can still use this in v2.8. You can read more about the deprecation notice addressed by the creator of modernizr Alex Sexton here.
A viable alternative now is to use jquery getScript() method. Following example shows how to load a polyfill script if a browser does not support feature detection.
if (Modernizr.geolocation){ //feature is supported by the browser console.log('geolocation supported'); } else { // feature not supported - load polyfill $.getScript('path/script.js') .done(function() { console.log('script loaded'); }) .fail(function() { console.log('script failed to load'); }); }
CONCLUSION
It has nearly been a decade since the launch of Modernizr in 2009, but it still hasn’t lost its relevance and purpose today. For every developer who likes to build their websites and web applications with cutting edge modern HTML5 and CSS3 features, Modernizr is an indispensable asset. Not only does it help to avoid heaps of code necessary for cross browser testing, but it also helps to provide an alternative to unreliable User Agent detection. Just like feature queries, Modernizr with feature detection for cross browser compatibility helps to put in place all the necessary fallbacks for unsupported functionalities and features which guarantees an impeccable user experience regardless of which browser the user may be using. Although native CSS @supports feature queries are fast catching up in terms widespread popularity and acceptance among developers, its lack of support in IE(including IE11) means that Modernizr with feature detection mechanism, still remains the premier tool of choice for achieving cross browser compatibility.
Original Source: lambdatest.com
Related Posts:
Posted on February 7, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.