Search code examples
css

Background-Image Gradient Not Animating


I am hoping someone can help clear this up.

I'm working on a search bar using HTML5 CSS3 here is the working example http://jsfiddle.net/4Mr6D/

 text-decoration: none;
transition: all 400ms;
-webkit-transition: all 400ms; 
-moz-transition: all 400ms; 
-o-transition: all 400ms;

starting line 164 or where I commented 'SEARCH RESULTS' I am trying to get the gradient background to animate on hover, it seems to only work animating back to the original color on rollout.

I've tried using background-image to animate, that doesn't work. I then turned to using the keyword 'all' and that isn't working.

So far, only the text color will animate. Can someone help me and locate what I'm doing wrong in getting the background gradient to animate also?


Solution

  • Edit: Even in the modern web, you cannot directly animate a CSS gradient that's a background-image because CSS color properties are not directly animatable and neither are background-images. As such, the below solution (or one like it, such as animating the background position of a gradient that spans a larger size than the element itself) is the only way to do it.


    Background images are not animatable. Since gradients in CSS use background images, you cannot use a transition to a new one like you would text color.

    With that being said, if you only have text in the drop downs, you can do a work around using a pseudo element and animating its opacity instead. The following is an example of how to do so:

    .container {
      width: 500px;
      height: 300px;
      color: white;
      background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #141413));
      background-image: -webkit-linear-gradient(top, #333333, #141413);
      background-image: -moz-linear-gradient(top, #333333, #141413);
      background-image: -ms-linear-gradient(top, #333333, #141413);
      background-image: -o-linear-gradient(top, #333333, #141413);
      background-image: linear-gradient(top, #333333, #141413);
      -webkit-transition: all 1s ease-in-out;
      -moz-transition: all 1s ease-in-out;
      -o-transition: all 1s ease-in-out;
      transition: all 1s ease-in-out;
      position: relative;
      z-index: 0;
    }
    
    .container:after {
      content: "";
      background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #59aaf4), color-stop(100%, #338cdf));
      background-image: -webkit-linear-gradient(top, #FF0000, #770000);
      background-image: -moz-linear-gradient(top, #FF0000, #770000);
      background-image: -ms-linear-gradient(top, #FF0000, #770000);
      background-image: -o-linear-gradient(top, #FF0000, #770000);
      background-image: linear-gradient(top, #FF0000, #770000);
      position: absolute;
      top: 0;
      left: 0;
      opacity: 0;
      width: 100%;
      height: 100%;
      -webkit-transition: all 1s ease-in-out;
      -moz-transition: all 1s ease-in-out;
      -o-transition: all 1s ease-in-out;
      transition: all 1s ease-in-out;
      z-index: -1;
    }
    
    .container:hover {
      color: white;
    }
    
    .container:hover:after {
      opacity: 1;
    }
    <div class='container'>Example Text!</div>

    Also, I'd remove the 900ms delay that you have (I did in my demo). It is REALLY annoying for users, they want immediate feedback, not feedback a second later.

    P.S. You should localize your code to the relevant parts like I did in order to get a quicker, better response. No one wants to look through 300 lines of code for a problem that only takes 20.

    Special thanks to vals for improving it using z-index.