A Best Practice for Programming with Vendor Prefixes

Vendor prefixes enable Web developers to experiment with new standards before they reach the Candidate Recommendation stage. I previously wrote how these prefixes are also a mechanism browser vendors use for handling timing conflicts between implementations and specifications. In building demos of new features for our IE Test Drive site and in various presentations, many of us on the IE team deal extensively with vendor prefixes.

This blog post describes a pattern we’ve used in some recent demos that’s making things significantly easier for us and has become a best practice. We’d like to share it with you and hear your thoughts on this approach or any others you consider a best practice.

Error-Prone Code

When using script to access CSS properties with vendor prefixes, it’s easy to end up with code that looks like this:

var elm = document.getElementById("myElement");

elm.style.msTransitionProperty = "all";

elm.style.msTransitionDuration = "3s";

elm.style.msTransitionDelay = "0s";

elm.style.webkitTransitionProperty = "all";

elm.style.webkitTransitionDuration = "3s";

elm.style.webkitTransitionDelay = "0s";

elm.style.MozTransitionProperty = "all";

elm.style.MozTransitionDuration = "3s";

elm.style.MozTransitionDelay = "0s";

elm.style.OTransitionProperty = "all";

elm.style.OTransitionDuration = "3s";

elm.style.OTransitionDelay = "0s";

While functional, it’s bloated, ugly, and error-prone.

Consolidating Vendor-Prefixed Properties to a Single Name

A better pattern is to define a method that loops through a list of property names and returns the first supported property or null if the browser doesn’t support any of them.

function FirstSupportedPropertyName(prefixedPropertyNames) {

var tempDiv = document.createElement("div");

for (var i = 0; i < prefixedPropertyNames.length; ++i) {

if (typeof tempDiv.style[prefixedPropertyNames[i]] != 'undefined')

return prefixedPropertyNames[i];

}

returnnull;

}

We then initialize a variable for each vendor-prefixed property we use, passing it an array of possible properties in the order we prefer to use them.

Testing Sites that Use Vendor-Prefixed Properties

A common question is what property names to use if some browsers don’t yet support the property or if no browser supports the standards-based property without a prefix. There are a couple approaches, each with merit:

Always include all expected names, even if they don’t yet work in shipping browsers. The benefit of this path is that as browsers add support with their vendor prefix or add support for the non-prefixed property, your site will “just work” without changes. The risk is that the site will automatically pick up behavior you’ve never tested. A vendor prefix indicates the behavior isn’t finalized and all prefixed properties and the non-prefixed property may not behave the same, so as browsers add support your site might “just not work.”

Only include property names you can test. The benefit is that your site will behave the same as when you first wrote it even as browsers add support for new properties. The risk is that you have unnecessarily degraded functionality. For sample or demo sites, people can interpret this as a browser not having a feature at all.

You need to determine the right path for your site. In most of our demos we want to show off new Web platform functionality in any browser that supports it. And since small errors in these demos don’t create big problems for users, we usually choose option #1. On the other hand, if you have a production site where a change in behavior will cause a problem for your business, you may opt for the more risk-averse path.

Regardless of which path you choose, the one constant is testing. When using vendor-prefixed properties you’re leveraging early, often unstable functionality that can change even after a browser first introduces support for a property, so it’s critical to test with each browser update to make sure your site functions as expected.