<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></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" class="sub">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-ps" class="sub">playState</li>
<li id="test-pbr" class="sub">playbackRate</li>
<li id="test-upbr" class="sub">updatePlaybackRate</li>
<li id="test-pending" class="sub">pending</li>
<li id="test-ctst" class="sub">currentTime/startTime</li>
<li id="test-tl" class="sub">timeline</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-p" class="sub">persist()</li>
<li id="test-cs" class="sub">commitStyles()</li>
<li id="test-pe" class="sub">effect (also see <a href="#test-kec">KeyframeEffect constructor</a>)
<ul>
<li id="test-pe-gt">getTiming()</li>
<li id="test-pe-gct">getComputedTiming()</li>
<li id="test-pe-ut">updateTiming()</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-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>
</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/Edge</a>, <a href="https://webkit.org/status/#specification-web-animations">Safari</a></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: .05;
}
aside div {
display: inline-block;
}
#css-tran {
transition: opacity 100000ms;
}
#css-anim {
animation: pulser 1s 0s infinite alternate linear;
}
@keyframes pulser {
100% {
opacity: 0;
}
}
footer {
font-size: .8em;
}
View Compiled
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.playState !== undefined), 'test-ps');
performBasicTest((player.playbackRate !== undefined), 'test-pbr');
performBasicTest((player.updatePlaybackRate !== undefined), 'test-upbr');
performBasicTest((player.pending !== undefined), 'test-pending');
performBasicTest((typeof player.persist === 'function'), 'test-p');
performBasicTest((typeof player.commitStyles === 'function'), 'test-cs');
performBasicTest((player.currentTime !== undefined && player.startTime !== undefined), 'test-ctst');
performBasicTest((player.timeline !== undefined), 'test-tl');
if (performBasicTest((player.effect !== undefined), 'test-pe')) {
performBasicTest((typeof player.effect.getTiming === 'function'), 'test-pe-gt');
performBasicTest((typeof player.effect.updateTiming === 'function'), 'test-pe-ut');
performBasicTest((typeof player.effect.getComputedTiming === 'function'), 'test-pe-gct');
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',
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');
}
var getAnims = performBasicTest((typeof document.getAnimations === 'function'), 'test-dga');
if (getAnims) {
var allAnimations = document.getAnimations();
allAnimations.forEach(function(a, i) {
console.log('All Animations', i, a);
if (a.animationName === 'pulser') {
performBasicTest(true, 'test-dgaca');
}
if (a.transitionProperty === 'opacity') {
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() {
const tran = document.getElementById('css-tran');
tran.style.opacity = 1;
tran.offsetWidth;
tran.style.opacity = .5;
if (document.body.animate) {
document.getElementById('waapi-anim').animate({opacity: [1,0]}, {
duration: 1000,
iterations: Infinity,
direction: 'alternate'
});
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.