Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes, there is a way. Demonstration follows, explanation below. There are some <strong>very important caveats</strong> involved, so make sure you read on.</p> <p>The following code will test if the browser can animate between two values.</p> <h1>The code</h1> <p><a href="http://jsfiddle.net/Jordan/8L9CM/9/" rel="nofollow noreferrer">jsFiddle demo</a>.</p> <pre class="lang-js prettyprint-override"><code>/* @param property The property to test. @param from A valid starting value for the animation. @param to A valid ending value for the animation. @param [element] The element to test with. (Required for testing properties with prerequisites, e.g. "top" requires non-static position.) */ function isAnimationSupported(property, from, to, element) { var doc = document.documentElement, style = doc.appendChild(document.createElement("style")), rule = [ 'capTest{', '0%{', property, ':', from, '}', '100%{', property, ':', to, '}', '}' ].join(''), propCamel = property.toCamelCase(), prefixes = 'moz ms o webkit '.split(' '), // Unprefixed last, see comments. prefixCount = prefixes.length, canAnimate = false; element = doc.appendChild((element) ? element.cloneNode(false) : document.createElement('div')); // Detect invalid start value. (Webkit tries to use default.) element.style[propCamel] = to; // Iterate through supported prefixes. for (var i = 0; i &lt; prefixCount; i++) { // Variations on current prefix. var prefix = prefixes[i], hPrefix = (prefix) ? '-' + prefix + '-' : '', uPrefix = (prefix) ? prefix.toUpperCase() + '_' : ''; // Test for support. if (CSSRule[uPrefix + 'KEYFRAMES_RULE']) { // Rule supported; add keyframe rule to test stylesheet. style.sheet.insertRule('@'+ hPrefix + 'keyframes ' + rule, 0); // Apply animation. var animationProp = (hPrefix + 'animation').toCamelCase(); element.style[animationProp] = 'capTest 1s 0s both'; // Get initial computed style. var before = getComputedStyle(element)[propCamel]; // Skip to last frame of animation. // BUG: Firefox doesn't support reverse or update node style while // attached. doc.removeChild(element); element.style[animationProp] = 'capTest 1s -1s alternate both'; doc.appendChild(element); // BUG: Webkit doesn't update style when animation skipped ahead. element.style[animationProp] = 'capTest 1s 0 reverse both'; // Get final computed style. var after = getComputedStyle(element)[propCamel]; // If before and after are different, property and values are animable. canAnimate = before !== after; break; } } // Clean up the test elements. doc.removeChild(element); doc.removeChild(style); return canAnimate; } // Cribbed from Lea Verou's prefixfree. String.prototype.toCamelCase = function() { return this.replace(/-([a-z])/g, function($0, $1) { return $1.toUpperCase(); }) .replace('-',''); }; </code></pre> <h1>How to use</h1> <p>The mandatory arguments for this are the property to animate and the starting and finishing values it should take. Optionally, you can pass an element with other initial styles set, e.g. <code>position: absolute</code>. (The function clones the element, so you can pass nodes from the document and they won't be changed.) If you don't pass any element, the animation is tested on a <code>div</code> with whatever default styles the UA applies.</p> <h1>How it works</h1> <p>A keyframe animation rule is added to a dummy stylesheet, with the initial frame set to the <code>from</code> value and the final frame set to the <code>to</code> value. This animation is applied to an element. We then inspect the computed style for the animated property to see if it is different when the animation starts from the initial frame compared to when it starts from the final frame.</p> <p>The reason this works is because the animable properties for both transitions and keyframe animations are the same, and the browser will only apply keyframe values if the property supports animation.</p> <h1>Caveats (read before using, some of these are nasty!)</h1> <p>There are several inconsistencies in how browsers handle animations. A couple of these I have worked around in as future-proof a way as possible; however, a few of them are intractable.</p> <p>Most notably, Firefox tweens position values (e.g. <code>left</code>) on static elements while others (e.g. Webkit and Opera) do not. It doesn't actually <em>move</em> the element, but the value of that property is updated. Thus, you will get different results between browsers if you try to animate a position value without passing a non-statically positioned element.</p> <p>The most current versions of major browsers that support CSS transitions also support CSS keyframes, although some older versions support the former but not the latter. (E.g. Opera 11.)</p> <p>Finally, if I were doing this more elegantly I would use <a href="http://leaverou.github.com/prefixfree/" rel="nofollow noreferrer">prefixfree</a> to determine the correct prefix to use directly; currently I test against an array of prefixes, starting with the unprefixed version.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload