简体   繁体   中英

Changing a css linear gradient animation without freezing the animation

I have an linear gradient animation for my website and I would like themes, so I am trying to use javascript to change the color's in the css, I got it to do something but it freezes the animation when I do so.

 function changeBackground() { document.body.style.background = "linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB)"; } 
 body { width: 100wh; height: 90vh; color: #fff; background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB); background-size: 400% 400%; -webkit-animation: Gradient 15s ease infinite; -moz-animation: Gradient 15s ease infinite; animation: Gradient 15s ease infinite; } @-webkit-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @-moz-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } 
  <a onclick="changeBackground()">Default</a> <a onclick="clickHandler()">Fire</a> // This will be implemented at a later time. 

Change only the background-image not the whole background . Changing the background will override the background-size and will freeze the animation. Better define background-image in the CSS also to avoid other issues.

You can also get rid of the prefix versions and simplify the animation like below:

 function changeBackground() { document.body.style.backgroundImage = "linear-gradient(-45deg, blue,red)"; } 
 body { width: 100wh; height: 90vh; color: #fff; background-image: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB); background-size: 400% 400%; animation: Gradient 15s ease infinite; } @keyframes Gradient { 0%,100% { background-position: left } 50% { background-position: right } } 
 <a onclick="changeBackground()">Default</a> <a onclick="clickHandler()">Fire</a> // This will be implemented at a later time. 

You can check this answer to understand the simplification and to have more details in case you need different animations: https://stackoverflow.com/a/51734530/8620333

First, since your "a" tag acting as buttons and not as anchors you should use the button element. Secondly, make a class with the desired background colors and fire it with the onclick event. (by the way body width should be on vw and not as you wrote it)

 function changeBackground() { document.body.classList.add('changeBackground'); } 
 body { width: 100vw; height: 90vh; color: #fff; background-image: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB); background-size: 400% 400%; -webkit-animation: Gradient 15s ease infinite; -moz-animation: Gradient 15s ease infinite; animation: Gradient 15s ease infinite; } @-webkit-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @-moz-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } .changeBackground { background-image: linear-gradient(-45deg, yellow, blue, red, green); } 
 <button onclick="changeBackground()">Default</button> 

***Just another approach.

Good Luck!

The Fix

This is because you are overriding the values of your animation. In CSS inline styles have a higher specificity than linked styles, and the background attribute is a shorthand that sets both background-image and background-position . The styles you're applying via JavaScript are setting new values with higher specificty than your animation keyframes. To fix this, set backgroundImage rather than background .

 function changeBackground() { document.body.style.backgroundImage = "linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB)"; } 
 body { width: 100wh; height: 90vh; color: #fff; background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB); background-size: 400% 400%; -webkit-animation: Gradient 15s ease infinite; -moz-animation: Gradient 15s ease infinite; animation: Gradient 15s ease infinite; } @-webkit-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @-moz-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } 
 <a onclick="changeBackground()">Default</a> <a onclick="clickHandler()">Fire</a> // This will be implemented at a later time. 

An Improved Approach

Better yet - use CSS classes to apply the change in styles rather than through JavaScript and avoid the specificity battle altogether. This how CSS is intended to be used.

Also worth mentioning a <button> is a more appropriate element to use for behavior, as anchors are for sending the user somewhere.

Though, if you're pulling the linear gradient values programmatically this may not be an option.

 function setDefault() { document.querySelector('body').setAttribute('class', ''); }; function clickHandler() { document.querySelector('body').classList.add('fire'); }; 
 body { width: 100wh; height: 90vh; color: #fff; background-image: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB); background-size: 400% 400%; -webkit-animation: Gradient 15s ease infinite; -moz-animation: Gradient 15s ease infinite; animation: Gradient 15s ease infinite; } .fire { background-image: linear-gradient(-45deg, #ff0000, #efefef, #ff0000, #efefef); } @-webkit-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @-moz-keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } @keyframes Gradient { 0% { background-position: 0% 50% } 50% { background-position: 100% 50% } 100% { background-position: 0% 50% } } 
 <button onclick="setDefault()" tyle="button">Default</buttopn> <button onclick="clickHandler()" tyle="button">Fire</buttopn> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM