I want to serve different javascript files depending on if browser supports CSS3 transition or not. Is there a better way to detect transition support than my code below?
window.onload = function () {
var b = document.body.style;
if(b.MozTransition=='' || b.WebkitTransition=='' || b.OTransition=='' || b.transition=='') {
alert('supported');
} else {
alert('NOT supported')
}
}
The solution is actually quite simple using JavaScript. To trigger an element's transition, toggle a class name on that element that triggers it. To pause an element's transition, use getComputedStyle and getPropertyValue at the point in the transition you want to pause it.
js is a JavaScript library that provides a convenient way to create CSS transitions pragmatically. Correctly adds new transitions to an element with already running transitions. Provides the onTransitionEnd callback that is called not only when the transition was finished, but also when the transition was halted.
I also think including Modernizr is an overkill. The function below should work for any feature.
function detectCSSFeature(featurename){
var feature = false,
domPrefixes = 'Webkit Moz ms O'.split(' '),
elm = document.createElement('div'),
featurenameCapital = null;
featurename = featurename.toLowerCase();
if( elm.style[featurename] !== undefined ) { feature = true; }
if( feature === false ) {
featurenameCapital = featurename.charAt(0).toUpperCase() + featurename.substr(1);
for( var i = 0; i < domPrefixes.length; i++ ) {
if( elm.style[domPrefixes[i] + featurenameCapital ] !== undefined ) {
feature = true;
break;
}
}
}
return feature;
}
var hasCssTransitionSupport = detectCSSFeature("transition");
Inspired by https://developer.mozilla.org/en-US/docs/CSS/Tutorials/Using_CSS_animations/Detecting_CSS_animation_support
Modernizr will detect this for you. Use this link to create a custom download build that only contains CSS3 2D and/or 3D transitions.
Once it's run, you can either test for the csstransitions
class on the html
tag (CSS), or in JavaScript, test if Modernizr.csstransitions
is true
.
More docs: http://modernizr.com/docs/#csstransitions
Here is another testing code. Maybe it is an overkill, but the function tries to set the CSS property to DOM object and then read back from it.
Never tested this code on large amount of exotic browsers, but it is safer than just checking for the CSS property availability. Ah, yes, it can distinguish 2D transform support from 3D transform support! Just pass CSS property values you want to test!
The plus of this code is that it detects the vendor prefix supported (if any). Possible return values:
false
, when feature unsupported, or
{
vendor: 'moz',
cssStyle: '-moz-transition',
jsStyle: 'MozTransition'
}
when feature supported
/**
* Test for CSS3 feature support. Single-word properties only by now.
* This function is not generic, but it works well for transition and transform at least
*/
testCSSSupport: function (feature, cssTestValue/* optional for transition and transform */) {
var testDiv,
featureCapital = feature.charAt(0).toUpperCase() + feature.substr(1),
vendors = ['', 'webkit', 'moz', 'ms', 'o'],
jsPrefixes = ['', 'Webkit', 'Moz', 'ms', 'O'],
defaultTestValues = {
transition: 'left 2s ease 1s',
transform: 'rotateX(-180deg) translateZ(.5em) scale(0.5)'
// This will test for 3D transform support
// Use other values if you need to test for 2D support only
},
testFunctions = {
transition: function (jsProperty, computed) {
return computed[jsProperty + 'Delay'] === '1s' && computed[jsProperty + 'Duration'] === '2s' && computed[jsProperty + 'Property'] === 'left';
},
transform: function (jsProperty, computed) {
return computed[jsProperty].substr(0, 9) === 'matrix3d(';
}
};
/* test given vendor prefix */
function isStyleSupported(feature, jsPrefixedProperty) {
if (jsPrefixedProperty in testDiv.style) {
var testVal = cssTestValue || defaultTestValues[feature],
testFn = testFunctions[feature];
if (!testVal) {
return false;
}
testDiv.style[jsPrefixedProperty] = testVal;
var computed = window.getComputedStyle(testDiv);
if (testFn) {
return testFn(jsPrefixedProperty, computed);
}
else {
return computed[jsPrefixedProperty] === testVal;
}
}
return false;
}
//Assume browser without getComputedStyle is either IE8 or something even more poor
if (!window.getComputedStyle) {
return false;
}
//Create a div for tests and remove it afterwards
if (!testDiv) {
testDiv = document.createElement('div');
document.body.appendChild(testDiv);
setTimeout(function () {
document.body.removeChild(testDiv);
testDiv = null;
}, 0);
}
var cssPrefixedProperty,
jsPrefixedProperty;
for (var i = 0; i < vendors.length; i++) {
if (i === 0) {
cssPrefixedProperty = feature; //todo: this code now works for single-word features only!
jsPrefixedProperty = feature; //therefore box-sizing -> boxSizing won't work here
}
else {
cssPrefixedProperty = '-' + vendors[i] + '-' + feature;
jsPrefixedProperty = jsPrefixes[i] + featureCapital;
}
if (isStyleSupported(feature, jsPrefixedProperty)) {
return {
vendor: vendors[i],
cssStyle: cssPrefixedProperty,
jsStyle: jsPrefixedProperty
};
}
}
return false;
}
Github: https://github.com/easy-one/CSS3test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With