Jabez du Preez
Jabez du Preez

Reputation: 9

Animating a gradient background on a button when hovering

Currently, I have buttons that have gradient backgrounds, using the bg-gradient property in Tailwind. I've also configured a bg-gradientHover for the hover state. I've set transition-all duration-300 as classes to animate the gradient background on the buttons, and it seems to be fine for normal buttons with a solid color as their backgrounds, BUT the gradient buttons instantly switch colors.

Also note, I'm using shadcn for my UI, but this shouldn't make a difference.

I've added the transition-all and duration-300 classes to the button. But the colors still switch instantly.

Current button classes:

inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-semibold ring-offset-background transition-all duration-300 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:scale-105```

I've also tried configuring the gradient using the bg-gradient-t and bg-gradient-to-b, but this doesn't change anything.

In my globals.css file, I have the gradient variables as follows:

/* Buttons */
  --promo-gradient: linear-gradient(180deg, #ffd775 0%, #c3962d 100%);
  --promo-gradient-hover: linear-gradient(180deg, #ffcf57 0%, #aa7d15 100%);

And then in my tailwind.config.js:

backgroundImage: {
        primaryGradient: 'var(--primary-gradient)',
        primaryGradientHover: 'var(--primary-gradient-hover)',
        secondaryGradient: 'var(--secondary-gradient)',
        secondaryGradientHover: 'var(--secondary-gradient-hover)',

        // promo buttons
        promoGradient: 'var(--promo-gradient)',
        promoGradientHover: 'var(--promo-gradient-hover)',
}

which all checks out, it's just the background is not transitioning nice and smooth. For the button I have a variant called promo:

promo: 'bg-promoGradient text-black hover:bg-promoGradientHover',

I also have a variant called gradient which has the 2 secondary colors:

gradient: 'bg-gradient-to-b from-secondary1 to-secondary2 text-black hover:from-secondary2 hover:to-secondary1',

End result is the same for both, an instant color switch instead of a smooth transition that is controlled by:

'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-semibold ring-offset-background transition-all duration-300 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:scale-105'

Upvotes: 1

Views: 114

Answers (1)

Wongjn
Wongjn

Reputation: 24408

You can't animate background-image value changes in a "smooth" way, since values are considered distinct:

Animation Type: Distinct

However, you could consider using a CSS variable with an associative @property definition to make the color stop have a smooth transition. You also need to explicitly add the CSS variable name to the transition-property property, since all does not sufficiently cover CSS variables.

tailwind.config = {
  theme: {
    extend: {
      backgroundImage: {
        promoGradient: 'linear-gradient(180deg, #ffd775, var(--color))',
      },
    },
  },
};
@property --color {
  syntax: "<color>";
  inherits: false;
  initial-value: transparent;
}
<script src="https://cdn.tailwindcss.com/3.4.15"></script>

<button
  class="
    inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-semibold ring-offset-background transition-[all,--color] duration-300 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:scale-105
    bg-promoGradient [--color:#c3962d] text-black hover:[--color:#aa7d15]
  "
>
  Foo
</button>

Upvotes: 1

Related Questions