0

I have a div that has a background gradient which values are set dynamically using javascript. Sometime, I need to change the gradient values (can be colors or color stop position). I would like to animate those changes without using javascript (dont get me wrong, I set the gradient valeus using javascript but I want to animate thise using CSS3). I tried setting a transition property like I would do with CSS. Here is a MWE:

function getPercent() {
  return Math.random() * 100;
}
setInterval(() => {
  const per = getPercent();
  document.getElementById('foo').style.background =
    `linear-gradient(to right, #aebcbf 0%,#aebcbf ${per}%,#0a0e0a ${per}%,#0a0e0a 100%`
}, 1000)
.container {
  transition: all 1s ease;
  background: linear-gradient(to right, #aebcbf 0%,#6e7774 50%,#0a0e0a 51%,#0a0809 100%);
  width: 150px;
  height: 10px;
}
<div class="container" id="foo"></div>
Vinz243
  • 9,654
  • 10
  • 42
  • 86
  • Possible duplicate of [css transition with linear gradient](http://stackoverflow.com/questions/7363141/css-transition-with-linear-gradient) or http://stackoverflow.com/questions/6542212/use-css3-transitions-with-gradient-backgrounds – evolutionxbox May 10 '17 at 11:41
  • @evolutionxbox I want the values to be originated from javascript, as the last edit now demonstrates, and the question is from 2011 – Vinz243 May 10 '17 at 12:04
  • The date of the question doesn't matter in this case. http://stackoverflow.com/questions/6542212/use-css3-transitions-with-gradient-backgrounds has your answer. CSS gradients are still non-animatable properties (transitions). – evolutionxbox May 10 '17 at 12:10

2 Answers2

0

Hope this is useful

background: linear-gradient(269deg, #ffffff, #ff0000);
background-size: 400% 400%;
-webkit-animation: AnimationName 23s ease infinite;
-moz-animation: AnimationName 23s ease infinite;
-o-animation: AnimationName 23s ease infinite;
animation: AnimationName 23s ease infinite;
@-webkit-keyframes AnimationName {
    0%{background-position:0% 50%}
    50%{background-position:100% 50%}
    100%{background-position:0% 50%}
}
@-moz-keyframes AnimationName {
    0%{background-position:0% 50%}
    50%{background-position:100% 50%}
    100%{background-position:0% 50%}
}
@-o-keyframes AnimationName {
    0%{background-position:0% 50%}
    50%{background-position:100% 50%}
    100%{background-position:0% 50%}
}
@keyframes AnimationName {
    0%{background-position:0% 50%}
    50%{background-position:100% 50%}
    100%{background-position:0% 50%}
}

and for more info about CSS transition check this

0

Unfortunately the background-image is not animatable (more info about background-image). Therefore animating CSS gradients is an issue.

To solve this with pure CSS, you can create an :before that has contains the new gradient. Give it opacity: 0 and change this to opacity: 1 when you want to show the new gradient.

Eventually we can do the following:

.container{
  width: 150px;
  height: 10px;
  background: linear-gradient(to right, #aebcbf 0%, #6e7774 50%, #0a0e0a 51%, #0a0809 100%);
  position: relative;
  z-index: 100;
}
.container:before{
  background: linear-gradient(to right, #aebcbf 0%, #6e7774 10%, #0a0e0a 51%, #0a0809 100%);
  content: '';    
  display: block;
  height: 100%;
  position: absolute;
  top: 0; 
  left: 0;
  opacity: 0;
  width: 100%;
  z-index: -100;
  transition: opacity 0.45s;
}
.container:hover:before {
  opacity: 1;
}
<div class="container" id="foo"></div>

EDIT:

If you want to make the gradients dynamic use a variable that keeps track of which element you changed last, like:

var swapElement = 0;
function getPercent() {
  return Math.random() * 100;
}
setInterval(() => {
  const per = getPercent();
  if(swapElement == 0){
     //change gradient of :before
     //set opacity to 1
     swapElement = 1;
  } else {
     document.getElementById('foo').style.background =
    `linear-gradient(to right, #aebcbf 0%,#aebcbf ${per}%,#0a0e0a ${per}%,#0a0e0a 100%`
}, 1000);
     //set opacity :before to 0
     swapElement = 0;
  }
Tom Groot
  • 1,160
  • 1
  • 9
  • 26
  • You can change the linear-gradients of the container and the before element. They can be completely dynamic. – Tom Groot May 10 '17 at 14:18