How Modernizr Automates JavaScript Feature Detection
Modernizr revolutionized front-end web development by replacing unreliable browser user-agent sniffing with automated, real-time feature detection. By programmatically testing whether a user’s browser supports specific HTML5, CSS3, or JavaScript capabilities at runtime, Modernizr provides developers with a structured JavaScript object and corresponding CSS classes. This article explores how Modernizr executes these tests under the hood, registers the results, and automates progressive enhancement workflows for modern and legacy web applications.
The Shift from User-Agent Sniffing to Feature Detection
Before automated feature detection, developers relied heavily on parsing the browser’s User-Agent string to determine capabilities. This approach was notoriously brittle due to spoofing, inaccurate version numbers, and the rapid pace of browser updates.
Modernizr established a new standard: instead of asking the browser who it was, Modernizr directly tested what the browser could actually do. It executed automated, non-destructive runtime tests immediately upon page load, guaranteeing accurate results regardless of the browser brand or platform.
How Modernizr Executes Automated Tests
Modernizr utilizes several programmatic techniques to evaluate features without disrupting the user experience or polluting the visual layout:
- Property Existence Checks: For standard JavaScript
APIs, Modernizr verifies the presence of specific properties or methods
on global objects. For example, testing for the Geolocation API involves
checking
'geolocation' in navigator. - In-Memory Element Inspection: To test HTML5
elements (like
<canvas>or<video>), Modernizr creates a dummy element in memory usingdocument.createElement(). It then inspects the element for specific properties or methods (such asgetContextfor canvas support) to confirm functional implementation rather than a fallback generic element. - Style Property and Vendor Prefix Probing: For CSS
properties, Modernizr creates a blank element, accesses its
styleobject, and attempts to set or read properties. It automatically iterates through vendor prefixes (such as-webkit-,-moz-, and-ms-) to determine if a prefixed or standard version of a feature (like Flexbox or CSS Transitions) is available. - Style Injection and Layout Testing: Some features
cannot be detected through property checks alone (such as
@mediaqueries or@font-facesupport). In these cases, Modernizr temporarily injects a<style>block containing unique CSS rules alongside a hidden test element, checks the computed styles or dimensions via JavaScript, and then immediately cleans up the DOM by removing the test nodes.
Automated Output: The JavaScript API and CSS Classes
Once the suite of automated tests completes, Modernizr exposes the results through two primary mechanisms:
The Global
ModernizrObject: Every test result is attached as a boolean property towindow.Modernizr. For instance, developers can write straightforward conditional logic in their scripts:if (Modernizr.localstorage) { localStorage.setItem('key', 'value'); } else { // Fallback to cookie storage or polyfill }HTML Class Injection: Modernizr automatically appends corresponding class names to the root
<html>element. If a feature is supported, a class named after the feature (e.g.,flexbox,svg) is added. If unsupported, a prefixed class (e.g.,no-flexbox,no-svg) is injected instead. This allows developers to write targeted fallback rules entirely in CSS.
Custom Builds and Performance Automation
To prevent unnecessary overhead, Modernizr introduced a modular architecture. Instead of running hundreds of unnecessary tests, developers could generate custom builds containing only the specific tests required for their project. The Modernizr build tool parsed project dependencies or accepted custom configurations to compile a lightweight, highly optimized JavaScript file tailored specifically to the application’s needs.