How can I set a CSS keyframes in Javascript?
Asked Answered
L

6

15

I have a CSS keyframes shown as below, my problem is I would like to set it as JavaScript (to put inside my div which already have some functions) so that I can return the "element" value to my function

.cylon-eye {
  background-color: yellow;
  background-image: linear-gradient( to right, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.9) 75%);
  color: none;
  height: 100%;
  width: 20%;
  animation: 4s linear 0s infinite alternate move-eye;
}
@keyframes move-eye {
  from {
    margin-left: -20%;
  }
  to {
    margin-left: 100%;
  }
}

I've tried to convert as below after suggestion, is that the return value i should call is var cylon-eye = document.getElementById("cylon-eye");?

<script type="text/javascript">
function appendStyle(styles) {
var css = document.createElement('style');
css.type = 'text/css';

if (css.styleSheet) css.styleSheet.cssText = styles;
else css.appendChild(document.createTextNode(styles));

document.getElementsByTagName("head")[0].appendChild(css);

}

var styles = '#cylon-eye { background-color: yellow; background-image: linear-gradient(to right,rgba(255,255,255, 0.9) 25%,rgba(255,255,255, 0.1) 50%,rgba(255,255,255, 0.9) 75%); color: none; height: 100%; width: 20%;animation: 4s linear 0s infinite alternate move-eye; z-index: 10;}';
var keyFrames = '\
@keyframes move-eye {\
  from {\
    margin-left: -20%;\
  }\

  to {\
    margin-left: 100%;\
  }\
}';

window.onload = function() { appendStyle(styles) };
</script>
Leading answered 3/1, 2020 at 5:44 Comment(3)
@lvy Hoo Hui En , I have shared example with two option in https://mcmap.net/q/763099/-how-can-i-set-a-css-keyframes-in-javascript post, You can check that post, Hope it helps to you.Allowable
hi @ankitkanojia, thanks for the suggestion and coding. if i want to return the colors to a boxes that i create, i only need to "return element;" right?Leading
@lvy Hoo Hui En, yes you can return but you need to provide an id to your dynamically created element on DOM in your example. or else you can refer https://mcmap.net/q/108562/-get-a-css-value-with-javascript post better understanding, let me know still required anything. Thank you!!Allowable
S
18

2022 SOLUTION

Now it's possible to use the method .animate() as in this example

document.getElementById("tunnel").animate([
  // key frames
  { transform: 'translateY(0px)' },
  { transform: 'translateY(-300px)' }
], {
  // sync options
  duration: 1000,
  iterations: Infinity
});

Docs:

Suomi answered 22/10, 2022 at 10:58 Comment(1)
How can I set @keyframes scroll using this?Dianemarie
A
8

let me share with you two snippets, one is using CSS + javascript and another is only using javascript, you can use whatever preferred to you. Hope its helpful to you.

WITH JAVASCRIPT

let dynamicStyles = null;

function addAnimation(body) {
  if (!dynamicStyles) {
    dynamicStyles = document.createElement('style');
    dynamicStyles.type = 'text/css';
    document.head.appendChild(dynamicStyles);
  }

  dynamicStyles.sheet.insertRule(body, dynamicStyles.length);
}

addAnimation(`
      @keyframes move-eye { 
         from {
           margin-left: -20%;
         }
        to {
          margin-left: 100%;
        }
      }
    `);



var element = document.createElement("div");
element.className = "cylon-eye";
element.style.height = "50px";
element.style.width = "50px";
element.style.backgroundImage = "linear-gradient(to right,rgba(255, 0, 0, 0.1) 25%,rgba(255, 0, 0) 50%,rgba(255, 0, 0, 0.1) 75%)";
element.style.animation = "4s linear 0s infinite alternate move-eye";

document.body.appendChild(element);

WITH CSS + JAVASCRIPT

var element = document.createElement("div");
element.className = "cylon-eye";
element.style.height = "50px";
element.style.width = "50px";
document.body.appendChild(element);
.cylon-eye {
  background-color: yellow;
  background-image: linear-gradient(to right, rgba(255, 0, 0, 0.9) 25%, rgba(255, 0, 0, 0.1) 50%, rgba(255, 0, 0, 0.9) 75%);
  color: none;
  height: 100%;
  width: 20%;
  animation: 4s linear 0s infinite alternate move-eye;
}

@keyframes move-eye {
  from {
    margin-left: -20%;
  }
  to {
    margin-left: 100%;
  }
}
Allowable answered 3/1, 2020 at 8:20 Comment(1)
The former doesn't work on Cromium, in my case. The latter does not really add (or modify, as I needed) the keyframes.Edrisedrock
A
3

this works fine for me, Hope this will help :)

var style = document.createElement('style');
style.type = 'text/css';
var keyFrames = '\
@keyframes slidein {\
  from {\
    margin-left: 100%;\
    width: 300%; \
  }\

  to {\
    margin-left: 0%;\
    width: 100%;\
  }\
}';

document.getElementsById('slideDiv')[0].appendChild(style);
Ashcroft answered 3/1, 2020 at 6:38 Comment(3)
Please use developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Fosque
And keyFrames can be a const as it's never changedFosque
Don't you think the keyFrames should be related to the style, somehow?Edrisedrock
R
3

It would be wise to use Native API functionality to alter CSSStyleSheets. You can access existing stylesheets using the following method

document.styleSheets[0].cssRules

This will return all applied rules and you will be able to edit the rule where the selectorText matches your selector

Rushton answered 3/1, 2020 at 8:34 Comment(0)
O
3

have you tried using a <style></style> tag?

For example:

const loading = document.querySelector('.loading');
const keyFrames = document.createElement("style");

keyFrames.innerHTML = `
  @keyframes loading {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }

  .loading {
    animation: loading 1s ease infinite;
  }
`;

loading.appendChild(keyFrames);
.loading {
  width: 100px;
  height: 100px;
  background-size: cover;
  background-image: url('https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmedia.24ways.org%2F2009%2F15%2Fassets%2Fimg%2Fspinner.png&f=1&nofb=1');
  background-repeat: no-repeat;
}
<!doctype html>
<html>
  <head>
    <title>Keyframes in js</title>
  </head>
  <body>
    <div class="loading"></div>
  </body>
</html>
Outer answered 3/1, 2020 at 10:0 Comment(2)
document.head.appendChild(keyFrames); is more reasonable, I think.Edrisedrock
This worked on Firefox and Cromium, for me and when modifying keyFrames multiple times (onResize).Edrisedrock
G
0

This is good for me.

document.getElementById(nodeID).insertAdjacentHTML("beforeend",
`
<style type="text/css">
  @keyframes your-animation {
    0% { transform: rotate(0deg);}
    100% { transform: rotate(360deg);}
  }
</style>
`
)
Gand answered 5/12, 2023 at 12:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.