<h2>Your Browser Native Web Animations API Support (<a href="https://codepen.io/danwilson/pen/XmWraY" target="_blank">Check including Polyfill</a>)</h2>
<p><span class="passed">Supported</span> |<span>Not Supported</span> |<span class="deprecated">Old Spec</span> |<span class="deprecated passed">Old Spec Supported</span></p>

<ul>
<li id="test-animate">Element.animate() support
  <ul>
  <li id="test-animate-kfa" class="sub">First parameter as array of keyframes like: [
      {opacity: 1},
      {opacity: 0} ]</li>
  <li id="test-animate-kfo" class="sub">First parameter as object with property arrays like: { opacity: [1, 0] }</li>
    <li id="test-animate-single">Single keyframe (<a href="https://codepen.io/danwilson/pen/qrMpWP/" target="_blank">Example</a>)</li>
  <li id="test-pid" class="sub">id</li>
  <li id="test-pcp" class="sub">play()</li>
  <li id="test-pcs" class="sub">pause()</li>
  <li id="test-pcr" class="sub">reverse()</li>
  <li id="test-pcc" class="sub">cancel()</li>
  <li id="test-pcf" class="sub">finish()</li>
  <li id="test-pbr" class="sub">playbackRate</li>
  <li id="test-ctst" class="sub">currentTime/startTime</li>
  <li id="test-poc" class="sub">oncancel handler</li>
  <li id="test-pof" class="sub">onfinish handler</li>
  <li id="test-pfp" class="sub">finished Promise</li>
  <li id="test-prp" class="sub">ready Promise</li>
    <li id="test-pe" class="sub">effect (also see <a href="#test-kec">KeyframeEffect constructor</a>)
      <ul>
        <li id="test-pe-gct">getComputedTiming()</li>
        <li id="test-pe-gf" class="deprecated">getFrames()/setFrames() [old spec and polyfill - renamed getKeyframes()/setKeyframes()</li>
        <li id="test-pe-gkf">getKeyframes()</li>
        <li id="test-pe-skf">setKeyframes()</li>
      </ul>
    </li>
  </ul>
</li>
<li id="test-ega">Element.getAnimations()</li>
<li id="test-kec">KeyframeEffect constructor
  <ul>
  <li id="test-kec-duration" class="sub">set duration</li>
  <li id="test-kec-fill" class="sub">set fill</li>
  <li id="test-kec-direction" class="sub">set direction</li>
  <li id="test-kec-iterations" class="sub">set iterations</li>
  <li id="test-kec-iterationStart" class="sub">set iterationStart</li>
  <li id="test-kec-delay" class="sub">set delay</li>
  <li id="test-kec-endDelay" class="sub">set endDelay</li>
  <li id="test-kec-easing" class="sub">set easing</li>
  <li id="test-kec-spacing" class="sub">set spacing</li>
  <li id="test-kec-composite" class="sub">set composite</li>
  <li id="test-kec-iterationComposite" class="sub">set iterationComposite</li>
  </ul>
</li>
<li id="test-ac">Animation constructor</li>
<li id="test-dt">Document default timeline
  <ul>
    <li id="test-dtct" class="sub">timeline.currentTime</li>
    <li id="test-dtga" class="sub deprecated">timeline.getAnimations() [old spec and polyfill - moved in spec to document.getAnimations()]</li>
  </ul>
</li>
<li id="test-dga">document.getAnimations()
  <ul>
    <li id="test-dgaca">includes CSS Animations</li>
    <li id="test-dgact">includes CSS Transitions</li>
  </ul>
</li>
<li id="test-dtc">DocumentTimeline constructor</li>
</ul>

<p>Status updates: <a href="https://birtles.github.io/areweanimatedyet/">Firefox</a>, <a href="https://www.chromestatus.com/features#animations">Chrome/Opera</a>, <a href="https://dev.windows.com/en-us/microsoft-edge/platform/status/webanimationsjavascriptapi">Edge</a>, Safari</p>

<aside>
  <div id="waapi-anim">Infinite WAAPI Animation</div>
  <div id="css-anim">Infinite CSS Animation</div>
  <div id="css-tran">Long CSS Transition</div>
</aside>
*, *:before {
  box-sizing: border-box;
}
body {
  font-family: "Helvetica Neue", sans-serif;
  line-height: 1.4;
  padding: 1rem;
}
h2 {
  margin-bottom: 1rem;
}
p, p + ul {
  margin-bottom: 2rem;
}
li, span {
  &::before {
    content: 'N';
    color: white;
    text-align: center;
    font-size: .5em;
    vertical-align: text-top;
    padding-top: .1rem;
    width: 1rem;
    height: 1rem;
    background-color: red;
    display: inline-block;
    margin: 0 .5rem;
  }
  &.deprecated {
    &::before {
      background-color: black;
      content: 'O'
    }
    opacity: .4;
  }
  &.passed {
    &::before {
      background-color: green;
      border-radius: 50%;
      content: 'S'
    }
    &.deprecated {
      &::before {
        content: 'O';
      }
    }
  }
  li {
    margin-left: 1rem;
  }
}

li:target {
  border-left: .5rem solid orange;
  //animation: pulse 2s 0s 1;
}

@keyframes pulse {
  50% {
    background: orange;
  }
}


aside {
  opacity: 0;
}
aside div {
  display: inline-block;
  transition: opacity 100s linear;
}
#css-anim {
  animation: pulser 1s 0s infinite alternate linear;
}
@keyframes pulser {
  100% {
    opacity: 0;
  }
}
function handleOnFinish() {
  performBasicTest(true, 'test-pof');
}
function handleOnCancel() {
  performBasicTest(true, 'test-poc');
}
function handleFinished() {
  performBasicTest(true, 'test-pfp');
}
function handleReady() {
  performBasicTest(true, 'test-prp');
}
startAnimation();

var animateTest = document.getElementById('test-animate');
var animateTestAsArray = document.getElementById('test-animate-kfa');
var animateTestAsObject = document.getElementById('test-animate-kfo');
var animateTestSingle = document.getElementById('test-animate-single');

if (animateTest.animate !== undefined) {
  animateTest.classList.add('passed');
  var player = animateTestAsArray.animate([
    {opacity:1},
    {opacity:.5},
    {opacity:1}
  ,], {
    iterations: 1,
    duration: 100,
    id: 'ISetTheId'
  });
  var player3 = animateTestAsArray.animate([
    {opacity:1},
    {opacity:.5},
    {opacity:1}
  ,], {
    iterations: 1,
    duration: 100
  });
  if (player) {
    performBasicTest(true, 'test-animate-kfa');
    player.onfinish = handleOnFinish;
    if (player.finished && player.finished.then) {
      player.finished.then(handleFinished);
    }
    if (player.ready && player.ready.then) {
      player.ready.then(handleReady);
    }
  }
  if (player3) {
    player3.oncancel = handleOnCancel;
    if (typeof player3.cancel === 'function') {
      player3.cancel();
    }
  }
  try {
    var player2 = animateTestAsObject.animate({ opacity: [1,.5,1] }, {
      iterations: 1,
      duration: 100
    });
    if (player2 && (typeof player2.play === 'function') && player2.currentTime >= 0 && window.getComputedStyle) {
      player2.pause();
      player2.currentTime = 50;
     console.log((parseFloat(window.getComputedStyle(animateTestAsObject).opacity))); performBasicTest((parseFloat(window.getComputedStyle(animateTestAsObject).opacity) === 0.5), 'test-animate-kfo');

      player2.play();
      player2.onfinish = handleOnFinish;
    }
  } catch(e) {}
  
  try {
    
    var playerSingle = animateTestSingle.animate([
      { offset: 1, opacity: 1}
    ], {
      iterations: 1,
      duration: 100
    }).onfinish = function() {
      
  performBasicTest(true, 'test-animate-single');
    };
  } catch(e) {
    console.log('Single Keyframe test failed', e);
  }
  
  performBasicTest((player.id === 'ISetTheId'), 'test-pid');
  
  performBasicTest((typeof player.play === 'function'), 'test-pcp');
  performBasicTest((typeof player.pause === 'function'), 'test-pcs');
  performBasicTest((typeof player.reverse === 'function'), 'test-pcr');
  performBasicTest((typeof player.cancel === 'function'), 'test-pcc');
  performBasicTest((typeof player.finish === 'function'), 'test-pcf');
  performBasicTest((player.playbackRate !== undefined), 'test-pbr');
  performBasicTest((player.currentTime !== undefined && player.startTime !== undefined), 'test-ctst');
  if (performBasicTest((player.effect !== undefined), 'test-pe')) {
    performBasicTest((typeof player.effect.getComputedTiming === 'function'), 'test-pe-gct');
    performBasicTest((typeof player.effect.getFrames === 'function'), 'test-pe-gf');
    performBasicTest((typeof player.effect.getKeyframes === 'function'), 'test-pe-gkf');
    performBasicTest((typeof player.effect.setKeyframes === 'function'), 'test-pe-skf');
  }
}
performBasicTest((typeof animateTest.getAnimations === 'function'), 'test-ega');


var options = {
  duration: 1234,
  fill: 'backwards',
  direction: 'alternate',
  iterations: 3,
  iterationStart: 3000,
  delay: 123,
  endDelay: 123,
  easing: 'ease-in-out',
  spacing: 'paced(opacity)',
  composite: 'add',
  iterationComposite: 'accumulate'
};
if (window.KeyframeEffect !== undefined) {
  performBasicTest(true, 'test-kec');
  var kfetest = document.getElementById('test-kec');
  try {
    var kfe = new KeyframeEffect(kfetest, [{opacity:0},{opacity:1}], options);
    if (kfe) {
      var kfeTests = document.querySelectorAll('[id*="test-kec-"]');
      for (var i = 0, l = kfeTests.length; i < l; i++) {
        var currentTest = kfeTests[i];
        var option = currentTest.id.replace('test-kec-','');
        if (options[option] == kfe[option] || (kfe.timing && options[option] == kfe.timing[option])) {
          performBasicTest(true, currentTest.id);
        }
      }
    }
  } catch(e) {}
}

performBasicTest((window.Animation !== undefined), 'test-ac');

var timeline = performBasicTest((document.timeline !== undefined), 'test-dt');
if (timeline) {
  performBasicTest((document.timeline.currentTime !== undefined), 'test-dtct');
  performBasicTest((typeof document.timeline.getAnimations === 'function'), 'test-dtga');
}

var getAnims = performBasicTest((typeof document.getAnimations === 'function'), 'test-dga');
if (getAnims) {
  var allAnimations = document.getAnimations();
  allAnimations.forEach(function(a, i) {
    if (typeof a === 'CSSAnimation' || (a.effect && a.effect.target === document.getElementById('css-anim'))) {
      performBasicTest(true, 'test-dgaca');
    }
    if (typeof a === 'CSSTransition' || (a.effect && a.effect.target === document.getElementById('css-tran'))) {
      performBasicTest(true, 'test-dgact');
    }
  });
}

try {
performBasicTest((typeof window.DocumentTimeline === 'function' && (new DocumentTimeline({originTime:0}))), 'test-dtc');
} catch(e) {}

function performBasicTest(test, id) {
  if (test) {
    document.getElementById(id) && document.getElementById(id).classList.add('passed');
  }
  return test;
}






function startAnimation() {
  document.getElementById('css-tran').style.opacity = .1;
  if (document.body.animate) {
    document.getElementById('waapi-anim').animate({opacity: [1,0]}, {
      duration: 1000,
      iterations: Infinity,
      direction: 'alternate'
    });
  }
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.