1

I'm trying to implement a transition with a @keyframe animation that changes the background gradient but can't seem to put my finger on where I'm going wrong.

Right now the background just jumps from gradient to gradient with no transition.

Link to jsfiddle

CSS:

.box {
  position:fixed;
  width:100%;
  height:800px;
  background: #071435;
  background-image: -o-linear-gradient(-44deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
  background-image: -moz-linear-gradient(-44deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
  background-image: -ms-linear-gradient(-44deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
  background-image: linear-gradient(-134deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
  background-image: -o-linear-gradient(-134deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
  background-image: -moz-linear-gradient(-134deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
  background-image: -ms-linear-gradient(-134deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
  background-image: linear-gradient(-224deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
  opacity:1;
}

.box:hover {
  -webkit-animation: playbg 3s infinite;
  -webkit-transition: all 3s linear;
}

@-webkit-keyframes playbg {
  0% {
    background-image: -o-linear-gradient(-44deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
    background-image: -moz-linear-gradient(-44deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
    background-image: -ms-linear-gradient(-44deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
    background-image: linear-gradient(-134deg, rgba(255, 22, 150, 0.64) 0%, rgba(178, 136, 12, 0.85) 100%);
    background-image: -o-linear-gradient(-134deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
    background-image: -moz-linear-gradient(-134deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
    background-image: -ms-linear-gradient(-134deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
    background-image: linear-gradient(-224deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 52%, rgba(0, 0, 0, 0.47) 100%);
    opacity:1;
  }
  20% {
    background-image: -o-linear-gradient(-90deg, rgba(4, 91, 255, 0.64) 11%, #00FDF2 100%);
    background-image: -moz-linear-gradient(-90deg, rgba(4, 91, 255, 0.64) 11%, #00FDF2 100%);
    background-image: -ms-linear-gradient(-90deg, rgba(4, 91, 255, 0.64) 11%, #00FDF2 100%);
    background-image: linear-gradient(-180deg, rgba(4, 91, 255, 0.64) 11%, #00FDF2 100%);
    background-image: -o-linear-gradient(-114deg, #FF1111 29%, rgba(255, 62, 30, 0.50) 97%);
    background-image: -moz-linear-gradient(-114deg, #FF1111 29%, rgba(255, 62, 30, 0.50) 97%);
    background-image: -ms-linear-gradient(-114deg, #FF1111 29%, rgba(255, 62, 30, 0.50) 97%);
    background-image: linear-gradient(-204deg, #FF1111 29%, rgba(255, 62, 30, 0.50) 97%);
    background-image: -o-linear-gradient(-71deg, rgba(130, 254, 152, 0.50) 31%, rgba(68, 93, 204, 0.50) 92%);
    background-image: -moz-linear-gradient(-71deg, rgba(130, 254, 152, 0.50) 31%, rgba(68, 93, 204, 0.50) 92%);
    background-image: -ms-linear-gradient(-71deg, rgba(130, 254, 152, 0.50) 31%, rgba(68, 93, 204, 0.50) 92%);
    background-image: linear-gradient(-161deg, rgba(130, 254, 152, 0.50) 31%, rgba(68, 93, 204, 0.50) 92%);
    opacity:1;
  }
  50% {
    background-image: -o-linear-gradient(-116deg, #F40FD1 0%, #5AD74C 95%);
    background-image: -moz-linear-gradient(-116deg, #F40FD1 0%, #5AD74C 95%);
    background-image: -ms-linear-gradient(-116deg, #F40FD1 0%, #5AD74C 95%);
    background-image: linear-gradient(-206deg, #F40FD1 0%, #5AD74C 95%);
    background-image: -o-radial-gradient(50% 69%, rgba(137, 255, 247, 0.64) 41%, rgba(216, 209, 101, 0.50) 83%);
    background-image: -moz-radial-gradient(50% 69%, rgba(137, 255, 247, 0.64) 41%, rgba(216, 209, 101, 0.50) 83%);
    background-image: -ms-radial-gradient(50% 69%, rgba(137, 255, 247, 0.64) 41%, rgba(216, 209, 101, 0.50) 83%);
    background-image: radial-gradient(50% 69%, rgba(137, 255, 247, 0.64) 41%, rgba(216, 209, 101, 0.50) 83%);
    background-image: -o-linear-gradient(-134deg, rgba(255, 0, 199, 0.50) 0%, rgba(255, 220, 30, 0.50) 100%);
    background-image: -moz-linear-gradient(-134deg, rgba(255, 0, 199, 0.50) 0%, rgba(255, 220, 30, 0.50) 100%);
    background-image: -ms-linear-gradient(-134deg, rgba(255, 0, 199, 0.50) 0%, rgba(255, 220, 30, 0.50) 100%);
    background-image: linear-gradient(-224deg, rgba(255, 0, 199, 0.50) 0%, rgba(255, 220, 30, 0.50) 100%);
    background-image: -o-linear-gradient(-62deg, rgba(255, 245, 127, 0.50) 0%, rgba(131, 139, 176, 0.50) 96%);
    background-image: -moz-linear-gradient(-62deg, rgba(255, 245, 127, 0.50) 0%, rgba(131, 139, 176, 0.50) 96%);
    background-image: -ms-linear-gradient(-62deg, rgba(255, 245, 127, 0.50) 0%, rgba(131, 139, 176, 0.50) 96%);
    background-image: linear-gradient(-152deg, rgba(255, 245, 127, 0.50) 0%, rgba(131, 139, 176, 0.50) 96%);
    opacity:1;
  }
  100% {
    background-image: -o-linear-gradient(-116deg, #1078FF 0%, #4CCCD7 95%);
    background-image: -moz-linear-gradient(-116deg, #1078FF 0%, #4CCCD7 95%);
    background-image: -ms-linear-gradient(-116deg, #1078FF 0%, #4CCCD7 95%);
    background-image: linear-gradient(-206deg, #1078FF 0%, #4CCCD7 95%);
    background-image: -o-linear-gradient(-44deg, #FF1B1B 0%, rgba(204, 255, 99, 0.25) 100%);
    background-image: -moz-linear-gradient(-44deg, #FF1B1B 0%, rgba(204, 255, 99, 0.25) 100%);
    background-image: -ms-linear-gradient(-44deg, #FF1B1B 0%, rgba(204, 255, 99, 0.25) 100%);
    background-image: linear-gradient(-134deg, #FF1B1B 0%, rgba(204, 255, 99, 0.25) 100%);
    background-image: -o-linear-gradient(-134deg, #F66514 0%, rgba(36, 30, 255, 0.25) 100%);
    background-image: -moz-linear-gradient(-134deg, #F66514 0%, rgba(36, 30, 255, 0.25) 100%);
    background-image: -ms-linear-gradient(-134deg, #F66514 0%, rgba(36, 30, 255, 0.25) 100%);
    background-image: linear-gradient(-224deg, #F66514 0%, rgba(36, 30, 255, 0.25) 100%);
    background-image: -o-linear-gradient(-62deg, #1CFFB5 0%, rgba(150, 157, 188, 0.25) 96%);
    background-image: -moz-linear-gradient(-62deg, #1CFFB5 0%, rgba(150, 157, 188, 0.25) 96%);
    background-image: -ms-linear-gradient(-62deg, #1CFFB5 0%, rgba(150, 157, 188, 0.25) 96%);
    background-image: linear-gradient(-152deg, #1CFFB5 0%, rgba(150, 157, 188, 0.25) 96%);
    opacity:1;
  }
}

1 Answer 1

1

background-image is not an animatable or a transitionable property and hence you cannot see it getting transitioned and it just jumps from one state to another.

MDN Reference | CSS Transitions Spec - Animatable CSS Properties

Note that some browsers do support animations/transitions of background-image property but it is not standard and hence not recommended for usage. [Source]


You can achieve a similar effect by transitioning the background-position property. My understanding is that this is because background-position is a numeric/percentage value and hence can be transitioned as the browser can ascertain intermediate states unlike background-image. Check this fiddle for a sample.

.box {
  /* Do not forget to add browser prefixes for gradients and transitions */
  position: relative;
  height: 100px;
  background: -webkit-linear-gradient(-224deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 36%, rgba(0, 0, 0, 0.47) 50%, #1CFFB5 72%, rgba(150, 157, 188, 0.25) 96%);
  background: -moz-linear-gradient(-224deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 36%, rgba(0, 0, 0, 0.47) 50%, #1CFFB5 72%, rgba(150, 157, 188, 0.25) 96%);
  background: -o-linear-gradient(-224deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 36%, rgba(0, 0, 0, 0.47) 50%, #1CFFB5 72%, rgba(150, 157, 188, 0.25) 96%);
  background: linear-gradient(-224deg, #3EAD7E 0%, rgba(29, 83, 60, 0.72) 36%, rgba(0, 0, 0, 0.47) 50%, #1CFFB5 72%, rgba(150, 157, 188, 0.25) 96%);
  background-size: 200% 100%;
  background-position: 0% bottom;
  -webkit-transition: all 1s ease-in-out;
  -moz-transition: all 1s ease-in-out;
  transition: all 1s ease-in-out;
}
.box:hover {
  background-position: 100% bottom;
}
<div class="box"></div>

Also another thing to note is that the transition must be specified in the base class and not just on :hover. If you specify on hover, it will transition while moving the mouse in but while moving out it will just jump. This fiddle illustrates it in comparison with the previous one.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for clarifying that. Could you suggest another approach that I could try?
You could have a look at using background-position or sprites. Mighty Meta | CSS Tricks | W3Conversions

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.