Search code examples
cssanimationbuttongradient

Button Style: Transitioning from solid to gradient color without messing up the animation


I got this code here and made some changes to mimic the button style and functions I like. However, I'm having a little trouble turning the single color into a gradient without messing up the animation. Can you help me with that?

.button-file {
  position: relative;
  text-align: center;
  z-index: 0;
  border-radius: 30px;
  max-width: 180px;
  max-height: 46px;
  overflow: hidden;
  height: 70px;
  padding-top: 10px;
  color: #fff;
}

.button-file::before {
  content: '';
  position: absolute;
  z-index: -2;
  left: 50%;
  top: 50%;
  width: 400px;
  height: 400px;
  border-radius: 30px;
  background-repeat: no-repeat;
  background-size: 50% 50%, 50% 50%;
  background-position: 0 0, 100% 0, 100% 100%, 0 100%;
  background-image: linear-gradient(#38718F, #38718F 0%), linear-gradient(#38718F, #38718F), linear-gradient(#D0555A, #D0555A), linear-gradient(#D0555A, #D0555A);
  transform: translate(-50%, -50%) rotate(90deg);
  transition: transform .7s cubic-bezier(1, 0, 0, 1);
}

.button-file:hover::before {
  transform: translate(-50%, -50%) rotate(180deg);
}

.button-file::after {
  content: '';
  position: absolute;
  z-index: -1;
  left: 3px;
  top: 3px;
  width: calc(100% - 6px);
  height: calc(100% - 6px);
  border-radius: 30px;
}
<div class="background">

  <div class="button-file">
    <a><b>Contact us</b></b></a>
  </div>
</div>


Solution

  • You can now use the @property syntax to animate gradients and use those in the transition CSS property. Some information on CSS Tricks here

    Note: this doesn't work on Firefox at the moment but is included in version 124 which is just coming out so will have almost complete browser coverage.

    Your button would look like this:

    /* set initial values */
    
    @property --redpos{
      syntax: '<percentage>'; 
      inherits: false;
      initial-value: 50%;
    }
    
    @property --bluepos{
      syntax: '<percentage>'; 
      inherits: false;
      initial-value: 50%;
    }
    
    .button-file {
      text-align: center;
      border-radius: 30px;
      max-width: 180px;
      max-height: 46px;
      overflow: hidden;
      height: 70px;
      padding-top: 10px;
      color: #fff;
      
      background: linear-gradient(90deg,  #38718F var(--redpos), #D0555A var(--bluepos));
      transition: --redpos 500ms, --bluepos 500ms;
    }
    
    /* on hover change the values */
    .button-file:hover {
      --redpos:0%;
      --bluepos:100%;
    }
    <div class="button-file">
      <a><b>Contact us</b></a>
    </div>

    Edited to add I've seen from an amendment from your initial answer that you want to rotate the background. The same principle applies, just change the angle of the linear-gradient as follows:

    @property --angle{
      syntax: '<angle>'; 
      inherits: false;
      initial-value: 90deg;
    }
    
    .button-file {
      text-align: center;
      border-radius: 30px;
      max-width: 180px;
      max-height: 46px;
      overflow: hidden;
      height: 70px;
      padding-top: 10px;
      color: #fff;
      
      transition: --angle 500ms;
      background: linear-gradient(var(--angle),  #38718F, #D0555A);
    }
    
    .button-file:hover {
      --angle:270deg;
    }
    <div class="button-file">
      <a><b>Contact us</b></a>
    </div>