13

I'm displaying a element on my site which I rotate with -90deg but if a browser doesn't support the CSS transform the element looks misspositioned and not really good. Now I want to detect with JavaScript or jQuery (it's indifferent if jQ or JS because I use/loaded already jQ on my site) if this rotation via CSS is supported?

I know Modernizr but just for that little thing I don't want to include that whole library (and speed down the website speed load).

4
  • 2
    Have a look at source of jQuery transform plugin (which extends jQuery .css() and .animate() functions) how they did it. Or, better, just use that plugin :) It's small. Commented Aug 27, 2011 at 2:12
  • 1
    You don't have to download the whole bundle from modernizr, you could just select 2d transform from the custom download Commented Aug 27, 2011 at 2:13
  • I just looked at how modernizr does things and borrowed small pieces from it for a project of mine. Commented Aug 27, 2011 at 2:19
  • @BalusC Post this as answer, I'll accept it :) Commented Aug 27, 2011 at 12:35

5 Answers 5

32

Here's a function based on Liam's answer. It will return either the name of the first supported prefix or false if none of the prefixes are supported.

function getSupportedTransform() {
    var prefixes = 'transform WebkitTransform MozTransform OTransform msTransform'.split(' ');
    var div = document.createElement('div');
    for(var i = 0; i < prefixes.length; i++) {
        if(div && div.style[prefixes[i]] !== undefined) {
            return prefixes[i];
        }
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Nice, up-voted. Just to suggest to have 'div' element created outside for loop.
4

This is about as simple as you get and a jsfiddle. It no longer goes on an infinite loop.

function getSupportedTransform() {
    var prefixes = 'transform WebkitTransform MozTransform OTransform msTransform'.split(' ');
    for(var i = 0; i < prefixes.length; i++) {
        if(document.createElement('div').style[prefixes[i]] !== undefined) {
            return prefixes[i];
        }
    }
    return false;
}

4 Comments

This goes on in an infinite loop if the browser doesn't support transforms (will also eat all the ram).
What's the purpose of 'el' variable? I guess you wanted not to create div element in every pass, but you didn't use it. And obviously, infinite loop in case no prefix is available.
@Dan It doesn't go on an infinite loop anymore.
@Sinisa I changed the code so it does't go into an infinite loop.
2

Here's the code I'm using to detect if CSS3 transitions are supported:

var div = document.createElement('div');
div.setAttribute('style', 'transition:top 1s ease;-webkit-transition:top 1s ease;-moz-transition:top 1s ease;-o-transition:top 1s ease;');
document.body.appendChild(div);
var cssTransitionsSupported = !!(div.style.transition || div.style.webkitTransition || div.style.MozTransition || div.style.OTransitionDuration);

div.parentNode.removeChild(div);
div = null;

I'm purposefully not looking for Microsoft support since Microsoft hasn't yet shipped a browser that supports CSS3 transitions and I don't want my code automatically supporting an implementation I haven't tested yet in the future.

Comments

0

Just pull what you need out of Modernizr

First we need the testProps function

   /**
     * testProps is a generic CSS / DOM property test; if a browser supports
     *   a certain property, it won't return undefined for it.
     *   A supported CSS property returns empty string when its not yet set.
     */
    function testProps( props, prefixed ) {
        for ( var i in props ) {
            if ( mStyle[ props[i] ] !== undefined ) {
                return prefixed == 'pfx' ? props[i] : true;
            }
        }
        return false;
    }

Then run the cssTransform test

var tests = [];
 tests['csstransforms'] = function() {
        return !!testProps(['transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform']);
    };

if tests['csstransforms'] is true, then you have the feature available.

3 Comments

There seems to be a mistake in the code: mStyle is not defined
Define it then :) var myStyle = []
I don't think you can just define it... looks lime mStyle is a global that has the browser supported css props in there....this function is completely useless if you have to define that variable as it will always be false...
0

This code tests for 2D transforms support.

It can be easily adjusted to detect 3D transforms support instead. Just add 'translateZ(1)' to test CSS (see defaultTestValues in source code).

The plus of this code is that it detects the vendor prefix supported (if any). Call it:

testCSSSupport('transform')

Possible return values:

false, when feature unsupported, or

{
    vendor: 'moz',
    cssStyle: '-moz-transform',
    jsStyle: 'MozTransform'
}

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 */) {
    var testDiv,
        featureCapital = feature.charAt(0).toUpperCase() + feature.substr(1),
        vendors = ['', 'webkit', 'moz', 'ms'],
        jsPrefixes = ['', 'Webkit', 'Moz', 'ms'],
        defaultTestValues = {
            transform: 'translateX(.5em)'
           // This will test for 2D transform support
           // Add translateZ(1) to test 3D transform
        },
        testFunctions = {
            transform: function (jsProperty, computed) {
                return computed[jsProperty].substr(0, 9) === 'matrix3d(';
            }
        };

    function isStyleSupported(feature, jsPrefixedProperty) {
        if (jsPrefixedProperty in testDiv.style) {
            var testVal = cssTestValue || defaultTestValues[feature],
                testFn = testFunctions[feature];
            if (!testVal) {
                return false;
            }

            //Assume browser without getComputedStyle is either IE8 or something even more poor
            if (!window.getComputedStyle) {
                return false;
            }

            testDiv.style[jsPrefixedProperty] = testVal;
            var computed = window.getComputedStyle(testDiv);

            if (testFn) {
                return testFn(jsPrefixedProperty, computed);
            }
            else {
                return computed[jsPrefixedProperty] === testVal;
            }
        }
    }

    var cssPrefixedProperty,
        jsPrefixedProperty,
        testDiv = document.createElement('div');

    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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.