How jQuery Automatically Handles CSS Vendor Prefixes
Modern web browsers often require vendor prefixes such as
-webkit-, -moz-, or -ms- to
support experimental or proprietary CSS features. Starting with jQuery
1.8, the library automatically handles these vendor prefixes behind the
scenes when you use the .css() method. This article
explains the internal mechanism jQuery uses to detect, map, and cache
browser-specific properties, allowing developers to write clean,
standard CSS property names without manual prefixing.
1. Camel-Casing and Normalization
When a CSS property name is passed into .css(), jQuery
first normalizes it. If the property is passed in standard hyphenated
CSS notation (for example, box-sizing or
user-select), jQuery converts it into camelCase format
(boxSizing, userSelect). This conversion
aligns with how the Document Object Model (DOM) represents CSS
properties on a standard HTML element's style object.
2. Testing Against the Element Style Object
To check if a browser supports a property natively without a prefix,
jQuery inspects an empty test element (typically created via
document.createElement("div")). It checks whether the
camelCased property exists as an attribute on that test element's
style object:
property in element.styleIf the standard, unprefixed property exists, jQuery uses it directly.
3. Iterating Over Known Vendor Prefixes
If the standard property is not supported, jQuery searches for a prefixed alternative. It capitalizes the first letter of the camelCased property and prepends standard vendor prefixes in sequence:
Webkit(Chrome, Safari, newer Opera versions, iOS browsers)Moz(Firefox)ms(Internet Explorer, legacy Edge)O(Legacy Opera)
For instance, if userSelect is not found, jQuery checks
WebkitUserSelect, MozUserSelect, and
msUserSelect against the element's style
object until it finds a property that is defined.
4. Caching via
jQuery.cssProps
Running feature detection every time a style is read or written would
negatively impact performance. To avoid this overhead, jQuery stores the
discovered working property name in an internal lookup dictionary called
jQuery.cssProps.
Once a supported prefixed property (such as
WebkitUserSelect) is identified for
user-select, that mapping is cached. For all subsequent
calls to .css("user-select", ...) on any element, jQuery
bypasses the detection logic and immediately applies the cached
vendor-prefixed property.
5. Fallback via
cssHooks
For edge cases where vendor prefixing involves value differences
rather than just property names (such as CSS gradients or flexbox syntax
variations), jQuery provides the jQuery.cssHooks API. While
the automatic prefixing mechanism handles standard property names
natively, cssHooks allows jQuery's core and plugin authors
to define custom getter and setter behaviors for complex,
browser-divergent CSS implementations.