0

First of all, I'm talking of background and not background-color. I looked around on stack-overflow but this solution but this is for images. Though I won't prefer creating an image of gradient and using this method. It might just blur up the original image as the image size would be variable.

The fade effect I want works with background-color but there seems no way to use linear-gradient in background color.

Here is my code:

#div-text {
  display: flex;
  flex-direction: row;
  width: 80%;
  height: 80%;
  border-radius: 20px;
  background: #2d2e31;
}

.cl-button {
  font-family: 'Merienda One', monospace;
  order: 2;
  align-self: center;
  height: 80%;
  width: 60%;
  border: 0;
  background-color: transparent;
  color: aliceblue;
  font-size: 16px;
  margin-left: 10px;
  text-align: left;
}

#div-text:hover {
  animation-name: div-text-hover;
  animation-duration: 2s;
  animation-fill-mode: forwards;
  animation-iteration-count: infinite;
  animation-timing-function: ease;
}

@keyframes div-text-hover {
  0% {
    background: linear-gradient(45deg, #36D8FF, #00acee, #66757f);
  }
  100% {
    background: linear-gradient(45deg, #36D8FF, #00acee, #66757f);
  }
}
<div id="div-text">
  <button id="button-text" class="cl-button">Text Here</button>
</div>

When I hover my mouse on the DIV it should change the background to the above gradient with FADE effect. But when I hover, the background changes instantly like this:

gif of output

I want that background to fade-in slowly and not so sharply with pure CSS without Jquery or anything else. Just like when we use background-color . I found no way to do this with background.

EDIT: I tried out adding @keyframes every 10% and it's still sharply changes opacity every frame. And it's not efficient to type of the same lines 60 times to get 60fps :-(

Community
  • 1
  • 1
Dharmaraj
  • 47,845
  • 8
  • 52
  • 84

4 Answers4

4

For this, you can use transition but transition does not work for linear-gradient so I'm changing here opacity of ::after pseudo element. button name will not show that why i used z-index for stack order.

#div-text {
    display: flex;
    flex-direction: row;
    width: 80%;
    height: 80%;
    border-radius: 20px;
    background: #2d2e31;
    position: relative;
    z-index: 1;
    overflow: hidden;
  }
  
  #div-text::after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    transition: opacity 1s ease;
    background: linear-gradient(45deg, #36D8FF, #00acee, #66757f);
    opacity: 0;
  }

  .cl-button {
    font-family: 'Merienda One', monospace;
    order: 2;
    align-self: center;
    height: 80%;
    width: 60%;
    border: 0;
    background-color: transparent;
    color: aliceblue;
    font-size: 16px;
    margin-left: 10px;
    text-align: left;
    position: relative;
    z-index: 3;
  }


    #div-text:hover::after{
      opacity: 1;
  }
<div id="div-text">
  <button id="button-text" class="cl-button">Text Here</button>
</div>

I think, it will be helpful for you.

Rahul Vyas
  • 121
  • 5
2

I am sure This will help You.I just changed the keyframe and place that linear-gradiant in hover section.

 @keyframes div-text-hover {
            0% {
                background-position: 0% 50%;
            }
            50% {
                background-position: 100% 50%;
            }
            100% {
                background-position: 0% 50%;
            }
        }
        
        #div-text {
            display: flex;
            flex-direction: row;
            width: 80%;
            height: 80%;
            border-radius: 20px;
            background: #2d2e31;
        }
        
        .cl-button {
            font-family: 'Merienda One', monospace;
            order: 2;
            align-self: center;
            height: 80%;
            width: 60%;
            border: 0;
            background-color: transparent;
            color: aliceblue;
            font-size: 16px;
            margin-left: 10px;
            text-align: left;
        }
        
        #div-text:hover {
            background: linear-gradient(45deg, #36D8FF, #00acee, #66757f);
            background-size: 400% 400%;
            -webkit-animation: div-text-hover 2s ease infinite;
            animation: div-text-hover 2s ease infinite;
            animation-fill-mode: forwards;
        }
<!DOCTYPE html>
<html class="no-js">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
   
</head>

<body>

    <div id="div-text">
        <button id="button-text" class="cl-button">Text Here</button>
    </div>

</body>

</html>
  • The post hover animation is exactly how I wanted. But when I hover over the button, it instantly turns blue. I want that transition also with such fade effect. Like slowly turning blue from grey. – Dharmaraj Apr 30 '20 at 09:49
  • Try to change aniamtion duration and add animation-delay. – Sangeeth A V Apr 30 '20 at 10:39
  • Animation delay simply adds some time before the animation. But it will still be sharp. I've tried that. – Dharmaraj Apr 30 '20 at 10:42
0

I also ran into same problem a while ago, and didn't get an answer. Turns out it is because background's linear gradient property is not animatable, just like background-img. There are some workarounds though:

  1. Stack 2 gradients on top of each other and animate the opacity of the top one. This is given in detail here : https://medium.com/@dave_lunny/animating-css-gradients-using-only-css-d2fd7671e759

  2. What I used is that create a gradient that is 2 times the width of screen and animate the position of the gradient.

Prakhar Londhe
  • 1,431
  • 1
  • 12
  • 26
0

I think in your code, the animation is working but your both the linear gradients have same values of color, hence you cant see it working. In short it is like changing gradient from white to white, which is working but there is no visual change. Instead you can try this :-

#div-text {
    display: flex;
    flex-direction: row;
    width: 80%;
    height: 80%;
    border-radius: 20px;
    background: #2d2e31;
  }

  .cl-button {
    font-family: 'Merienda One', monospace;
    order: 2;
    align-self: center;
    height: 80%;
    width: 60%;
    border: 0;
    background-color: transparent;
    color: aliceblue;
    font-size: 16px;
    margin-left: 10px;
    text-align: left;
  }


    #div-text:hover {
      animation: hover-animation 2s infinite ease-in;
  }
@keyframes hover-animation{
    0%{
      background: #2d2e31;
    }

    100%{
      background: linear-gradient(45deg,#36D8FF, #00acee, #66757f);
    }

}

I too am a beginer so this is not a perfect code. So you might want to make changes to it. And sorry if i have made any mistake.Let me know how it works out. Thank you.

Rohan Nagmoti
  • 31
  • 1
  • 7
  • Unfortunately this didn't work. The div remains remains [#2d2e31] until the 99% of animation and turns into that gradient sharply as the gif in my question at final few moments of the animation. – Dharmaraj Apr 30 '20 at 07:36
  • did you try to play around with opacity??I mean like take the gradient at 100% and add same at 75%-80% with 70% opacity which might smooth it, or change the ease-in to ease,linear,etc. – Rohan Nagmoti Apr 30 '20 at 07:39
  • Tried opacity 0 at 0% and Opacity 1 at 100%. No use. Opacity also changes sharply – Dharmaraj Apr 30 '20 at 07:44
  • Okey. Sorry then. I will let you know if i find something.Thank you. – Rohan Nagmoti Apr 30 '20 at 07:47