Use CSS3 transitions with gradient backgrounds
Asked Answered
H

21

286

I'm trying to transition on hover with css over a thumbnail so that on hover, the background gradient fades in. The transition isn't working, but if I simply change it to an rgba() value, it works fine. Are gradients not supported? I tried using an image too, it won't transition the image either.

I know it's possible, as in another post someone did it, but I can't figure out how exactly. Any help> Here's some CSS to work with:

#container div a {
  -webkit-transition: background 0.2s linear;
  -moz-transition: background 0.2s linear;
  -o-transition: background 0.2s linear;
  transition: background 0.2s linear;
  position: absolute;
  width: 200px;
  height: 150px;
  border: 1px #000 solid;
  margin: 30px;
  z-index: 2
}

#container div a:hover {
  background: -webkit-gradient(radial, 100 75, 100, 100 75, 0, from(rgba(0, 0, 0, .7)), to(rgba(0, 0, 0, .4)))
}
Handel answered 30/6, 2011 at 23:35 Comment(2)
IE10 supports gradient transitions now - it was a happy surprise !Neaten
@mkprogramming, woha, it really does and looks great! Here's a demo (works with IE10+). Hope other browsers get support for this cool stuff too.Somatology
H
219

This is now possible using the @property workaround. Please see @Mahozad's answer.


Original Answer:

Gradients don't support transitions yet (although the current spec says they should support like gradient to like gradient transitions via interpolation.).

If you want a fade-in effect with a background gradient, you have to set an opacity on a container element and 'transition` the opacity.

(There have been some browser releases that supported transitions on gradients (e.g IE10. I tested gradient transitions in 2016 in IE and they seemed to work at the time, but my test code no longer works.)

October 2018 Update: Gradient transitions with un-prefixed new syntax [e.g. radial-gradient(...)] now confirmed to work (again?) on Microsoft Edge 17.17134. I don't know when this was added. Still not working on latest Firefox & Chrome / Windows 10.

Hushhush answered 1/7, 2011 at 0:55 Comment(7)
But edge webkit browsers now support the new mozilla-heritage gradient spec as well as the older webkit syntax. Confusingly, they're both -webkit prefixedHushhush
That that IE10 fully supports gradient transitions.Gradey
Great simple workaround hereAglaia
Can you add a demonstration on using transitions with gradients now? I can't seem to figure it out based on your answer (and can find no other news about it). The last I heard, you can't transition between two background images, which is what gradients were.Ahmedahmedabad
I'd like to see some sources/code on this as well. I can't get it to work, even with updated 2017-syntax (which afaik means to just drop the prefixes)Frater
Alex - updated syntax is significantly different at least for -webkit: e.g. In Old webkit syntax there was a single gradient property and radial/linear was an attribute - now they're separate properties.Which was how the -moz syntax worked.Hushhush
Transitioning the opacity (and filter brightness/contrast) works great, especially when you have a background image that you want to fade in/out.Spartan
H
126

One work-around is to transition the background position to give the effect that the gradient is changing: http://sapphion.com/2011/10/css3-gradient-transition-with-background-position/

CSS3 gradient transition with background-position

Although you can’t directly animate gradients using the CSS transition property, it is possible to animate the background-position property to achieve a simple gradient animation:

The code for this is dead simple:

#DemoGradient{  
    background: -webkit-linear-gradient(#C7D3DC,#5B798E);  
    background: -moz-linear-gradient(#C7D3DC,#5B798E);  
    background: -o-linear-gradient(#C7D3DC,#5B798E);  
    background: linear-gradient(#C7D3DC,#5B798E);  
  
    -webkit-transition: background 1s ease-out;  
    -moz-transition: background 1s ease-out;  
    -o-transition: background 1s ease-out;  
    transition: background 1s ease-out;  
  
    background-size:1px 200px;  
    border-radius: 10px;  
    border: 1px solid #839DB0;  
    cursor:pointer;  
    width: 150px;  
    height: 100px;  
}  
#DemoGradient:Hover{  
    background-position:100px;  
}  
<div id="DemoGradient"></div>  
Hegel answered 27/10, 2011 at 16:44 Comment(0)
P
92

It is now possible to animate gradients with @property in CSS:

@property --myColor1 {
  syntax: '<color>';
  initial-value: magenta;
  inherits: false;
}

@property --myColor2 {
  syntax: '<color>';
  initial-value: #00ff00;
  inherits: false;
}

The rest is regular CSS.
Set the variables as initial gradient colors and also set the transition of those variables:

div {
  /* Optional: change initial value of the variables */
  /* --myColor1: #f64; --myColor2: brown; */

  background: linear-gradient(var(--myColor1), var(--myColor2));
  transition: --myColor1 3s, --myColor2 3s;
}

Then, on the desired rule, set new values for the variables:

div:hover {  
  --myColor1: #f00;
  --myColor2: yellow;
}

@property --myColor1 {
  syntax: '<color>';
  initial-value: #0f0;
  inherits: false;
}

@property --myColor2 {
  syntax: '<color>';
  initial-value: rgb(40, 190, 145);
  inherits: false;
}

div {
  width: 200px;
  height: 100px;
  background: linear-gradient(var(--myColor1), var(--myColor2));
  transition: --myColor1 3s, --myColor2 3s;
}

div:hover {
  --myColor1: red;
  --myColor2: #E1AF2F;
}
<div>Hover over me</div>

See the full description and example here and refer here for @property specification.
The @property rule is part of the CSS Houdini technology. For more information refer here and here and see this video.

Prejudice answered 11/9, 2020 at 14:17 Comment(3)
Can you change the CSS variables using Javascript? I was trying and can't get the fade effect, it immediately toggles.Mononucleosis
@Mononucleosis yes you can. You can see an example here: frazer.github.io/cssVariables/index.html and code here github.com/Frazer/cssVariables/blob/master/index.htmlDunno
Works perfectly with styled-components and dynamic classNames using clsx!Paredes
H
36

A solution is to use background-position to mimic the gradient transition. This solution was used in Twitter Bootstrap a few months ago.

Update

http://codersblock.blogspot.fr/2013/12/gradient-animation-trick.html?showComment=1390287622614

Here is a quick example:

Link state

 .btn {
  font-family: "Helvetica Neue", Arial, sans-serif;
  font-size: 12px;
  font-weight: 300;
  position: relative;
  display: inline-block;
  text-decoration: none;
  color: #fff;
  padding: 20px 40px;
  background-image: -moz-linear-gradient(top, #50abdf, #1f78aa);
  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#50abdf), to(#1f78aa));
  background-image: -webkit-linear-gradient(top, #50abdf, #1f78aa);
  background-image: -o-linear-gradient(top, #50abdf, #1f78aa);
  background-image: linear-gradient(to bottom, #50abdf, #1f78aa);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff50abdf', endColorstr='#ff1f78aa', GradientType=0);
  background-repeat: repeat-y;
  background-size: 100% 90px;
  background-position: 0 -30px;
  -webkit-transition: all 0.2s linear;
     -moz-transition: all 0.2s linear;
       -o-transition: all 0.2s linear;
          transition: all 0.2s linear;
}

Hover state

.btn:hover {
   background-position: 0 0;
}
Haldeman answered 19/3, 2013 at 12:20 Comment(1)
And here's a fiddle for that: jsfiddle.net/Volker_E/RksTV The key is the property background-size, which you can't in IE8. caniuse.com/#search=background-size Apart from that it's a nice solution.Withers
B
28

For what it's worth, here's a Sass mixin:

Usage:

@include gradientAnimation(red, blue, .6s);

Mixin:

@mixin gradientAnimation( $start, $end, $transTime ){
    background-size: 100%;
    background-image: linear-gradient($start, $end);
    position: relative;
    z-index: 100;
    &:before {
        background-image: linear-gradient($end, $start);
        content: "";
        display: block;
        height: 100%;
        position: absolute;
        top: 0; left: 0;
        opacity: 0;
        width: 100%;
        z-index: -100;
        transition: opacity $transTime;
    }
    &:hover {
        &:before {
            opacity: 1;
        }
    }
}

Taken from this awesome post on Medium from Dave Lunny: https://medium.com/@dave_lunny/animating-css-gradients-using-only-css-d2fd7671e759

Breebreech answered 9/7, 2018 at 4:54 Comment(0)
S
28

::before, the CSS pseudo-element can easily do the trick!

.element {
  position: relative;
  width: 200px;
  height: 150px;
  background-image: linear-gradient(45deg, blue, aqua);
  z-index: 2;
}

.element::before {
  position: absolute;
  content: "";
  inset: 0; /* same as { top: 0; right: 0; bottom: 0; left: 0; } */
  background-image: linear-gradient(to bottom, red, orange);
  z-index: 1;
  opacity: 0;
  transition: opacity 0.25s linear;
}

.element:hover::before {
  opacity: 1;
}
<body>
  <div class="element"></div>
</body>

All you have to do is use the ::before pseudo-element with zero opacity.

On :hover, switch ::before's opacity to 1 and if you follow a few simple steps, you should get your transition working.

  1. Set the element's background gradient using background-image
  2. Use the ::before pseudo-element with opacity zero to setup your next gradient
  3. set opacity to 1 inside :hover::before
  4. make sure your ::before has:
    • position absolute
    • content: ""
    • a lower z-index than the default element
    • zero top, bottom, left, and right (or simply inset: 0)
    • transition targeting opacity with a time interval of your preference

And that's it! Now you should be able tweak your transition with whatever duration / delay / timing-function you like!

Suborder answered 17/2, 2021 at 4:27 Comment(2)
If your initial background is transparent, you can set z-index of the "overlapping" background to -1 so that your fonts won't get covered.Alcheringa
note that for inline elements that span multiple lines this might not give the desired effect. Eg. when trying to underline a link that wraps several lines, this will not work.Esmeralda
B
17

I know that is old question but mabye someone enjoy my way of solution in pure CSS. Gradient fade from left to right.

.contener{   
  width:300px;
  height:200px;
  background-size:cover;
  border:solid 2px black;
}
.ed {
    width: 0px;
    height: 200px;
    background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.75));
    position: relative;
    opacity:0;
    transition:width 20s, opacity 0.6s;
}

.contener:hover .ed{
    width: 300px;
    background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.75));
    position: relative;
    opacity:1;
    transition:width 0.4s, opacity 1.1s;
    transition-delay: width 2s;
    
    animation-name: gradient-fade;
    animation-duration: 1.1s;   
    -webkit-animation-name: gradient-fade; /* Chrome, Safari, Opera */
    -webkit-animation-duration: 1.1s; /* Chrome, Safari, Opera */
}




/* ANIMATION */
@-webkit-keyframes gradient-fade {
    0%   {background:linear-gradient(to right, rgba(0,0,255,0), rgba(255,0,0,0));}
    2%  {background:linear-gradient(to right, rgba(0,0,255,0.01875), rgba(255,0,0,0));}
    4%  {background:linear-gradient(to right, rgba(0,0,255,0.0375), rgba(255,0,0,0.0));}
    6%  {background:linear-gradient(to right, rgba(0,0,255,0.05625), rgba(255,0,0,0.0));}
    8% {background:linear-gradient(to right, rgba(0,0,255,0.075), rgba(255,0,0,0));}
    10%  {background:linear-gradient(to right, rgba(0,0,255,0.09375), rgba(255,0,0,0));}
    12%   {background:linear-gradient(to right, rgba(0,0,255,0.1125), rgba(255,0,0,0));}
    14%  {background:linear-gradient(to right, rgba(0,0,255,0.13125), rgba(255,0,0,0));}
    16%  {background:linear-gradient(to right, rgba(0,0,255,0.15), rgba(255,0,0,0));}
    18%  {background:linear-gradient(to right, rgba(0,0,255,0.16875), rgba(255,0,0,0));}
    20% {background:linear-gradient(to right, rgba(0,0,255,0.1875), rgba(255,0,0,0));}
    22%  {background:linear-gradient(to right, rgba(0,0,255,0.20625), rgba(255,0,0,0.01875));}
    24%   {background:linear-gradient(to right, rgba(0,0,255,0.225), rgba(255,0,0,0.0375));}
    26%  {background:linear-gradient(to right, rgba(0,0,255,0.24375), rgba(255,0,0,0.05625));}
    28%  {background:linear-gradient(to right, rgba(0,0,255,0.2625), rgba(255,0,0,0.075));}
    30%  {background:linear-gradient(to right, rgba(0,0,255,0.28125), rgba(255,0,0,0.09375));}
    32% {background:linear-gradient(to right, rgba(0,0,255,0.3), rgba(255,0,0,0.1125));}
    34%  {background:linear-gradient(to right, rgba(0,0,255,0.31875), rgba(255,0,0,0.13125));}
    36%   {background:linear-gradient(to right, rgba(0,0,255,0.3375), rgba(255,0,0,0.15));}
    38%  {background:linear-gradient(to right, rgba(0,0,255,0.35625), rgba(255,0,0,0.16875));}
    40%  {background:linear-gradient(to right, rgba(0,0,255,0.375), rgba(255,0,0,0.1875));}
    42%  {background:linear-gradient(to right, rgba(0,0,255,0.39375), rgba(255,0,0,0.20625));}
    44% {background:linear-gradient(to right, rgba(0,0,255,0.4125), rgba(255,0,0,0.225));}
    46%  {background:linear-gradient(to right, rgba(0,0,255,0.43125),rgba(255,0,0,0.24375));}
    48%   {background:linear-gradient(to right, rgba(0,0,255,0.45), rgba(255,0,0,0.2625));}
    50%  {background:linear-gradient(to right, rgba(0,0,255,0.46875), rgba(255,0,0,0.28125));}
    52%  {background:linear-gradient(to right, rgba(0,0,255,0.4875), rgba(255,0,0,0.3));}
    54%   {background:linear-gradient(to right, rgba(0,0,255,0.50625), rgba(255,0,0,0.31875));}
    56%  {background:linear-gradient(to right, rgba(0,0,255,0.525), rgba(255,0,0,0.3375));}
    58%  {background:linear-gradient(to right, rgba(0,0,255,0.54375), rgba(255,0,0,0.35625));}
    60%  {background:linear-gradient(to right, rgba(0,0,255,0.5625), rgba(255,0,0,0.375));}
    62% {background:linear-gradient(to right, rgba(0,0,255,0.58125), rgba(255,0,0,0.39375));}
    64%  {background:linear-gradient(to right,rgba(0,0,255,0.6), rgba(255,0,0,0.4125));}
    66%   {background:linear-gradient(to right, rgba(0,0,255,0.61875), rgba(255,0,0,0.43125));}
    68%  {background:linear-gradient(to right, rgba(0,0,255,0.6375), rgba(255,0,0,0.45));}
    70%  {background:linear-gradient(to right, rgba(0,0,255,0.65625), rgba(255,0,0,0.46875));}
    72%  {background:linear-gradient(to right, rgba(0,0,255,0.675), rgba(255,0,0,0.4875));}
    74% {background:linear-gradient(to right, rgba(0,0,255,0.69375), rgba(255,0,0,0.50625));}
    76%  {background:linear-gradient(to right, rgba(0,0,255,0.7125), rgba(255,0,0,0.525));}
    78%   {background:linear-gradient(to right, rgba(0,0,255,0.73125),,rgba(255,0,0,0.54375));}
    80%  {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.5625));}
    82%  {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.58125));}
    84%  {background:linear-gradient(to right, rgba(0,0,255,0.75),rgba(255,0,0,0.6));}
    86% {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.61875));}
    88%  {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.6375));}
    90%   {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.65625));}
    92%  {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.675));}
    94%  {background:linear-gradient(to right, rgba(0,0,255,0.75),rgba(255,0,0,0.69375));}
    96%  {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.7125));}
    98% {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.73125),);}
    100%  {background:linear-gradient(to right, rgba(0,0,255,0.75), rgba(255,0,0,0.75));}
}
<div class="contener" style="">
  <div class="ed"></div>
</div>
Beard answered 1/7, 2016 at 11:50 Comment(0)
G
8

Based on the css code in your question, I have try code as follows and it works for me (run the code snippet), and please try by yourself :

#container div a {
  display: inline-block;
  margin-top: 10%;
  padding: 1em 2em;
  font-size: 2em;
  color: #fff;
  font-family: arial, sans-serif;
  text-decoration: none;
  border-radius: 0.3em;
  position: relative;
  background-color: #ccc;
  background-image: linear-gradient(to top, #C0357E, #EE5840);
  -webkit-backface-visibility: hidden;
  z-index: 1;
}
     
#container div a:after {
  position: absolute;
  content: '';
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 0.3em;
  background-image: linear-gradient(to top, #6d8aa0, #343436);
  transition: opacity 0.5s ease-out;
  z-index: 2;
  opacity: 0;
}
    
#container div a:hover:after {
  opacity: 1;
}
#container div a span {
  position: relative;
  z-index: 3;
}
<div id="container"><div><a href="#"><span>Press Me</span></a></div></div>

Based on the css code in your question, I have try code as follows and it works for me, and please try by yourself :

    #container div a {
  display: inline-block;
  margin-top: 10%;
  padding: 1em 2em;
  font-size: 2em;
  color: #fff;
  font-family: arial, sans-serif;
  text-decoration: none;
  border-radius: 0.3em;
  position: relative;
  background-color: #ccc;
  background-image: linear-gradient(to top, #C0357E, #EE5840);
  -webkit-backface-visibility: hidden;
  z-index: 1;
}

#container div a:after {
  position: absolute;
  content: '';
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 0.3em;
  background-image: linear-gradient(to top, #6d8aa0, #343436);
  transition: opacity 0.5s ease-out;
  z-index: 2;
  opacity: 0;
}

#container div a:hover:after {
  opacity: 1;
}
#container div a span {
  position: relative;
  z-index: 3;
}

Does it works for you? Change the color based on your need :)

Gorham answered 31/8, 2017 at 21:29 Comment(0)
D
4

Partial workaround for gradient transition is to use inset box shadow - you can transition either the box shadow itself, or the background color - e.g. if you create inset box shadow of the same color as background and than use transition on background color, it creates illusion that plain background is changing to radial gradient

.button SPAN {
    padding: 10px 30px; 
    border: 1px solid ##009CC5;

    -moz-box-shadow: inset 0 0 20px 1px #00a7d1;
    -webkit-box-shadow: inset 0 0 20px 1px#00a7d1;
    box-shadow: inset 0 0 20px 1px #00a7d1; 

    background-color: #00a7d1;
    -webkit-transition: background-color 0.5s linear;
    -moz-transition: background-color 0.5s linear;
    -o-transition: background-color 0.5s linear;
    transition: background-color 0.5s linear;
}

.button SPAN:hover {
    background-color: #00c5f7; 
}
Deese answered 25/9, 2013 at 13:9 Comment(1)
clever solution, inset shadow can create the gradient illusion perfectlyCuneo
B
3

You can FAKE transitions between gradients, using transitions in the opacity of a few stacked gradients, as described in a few of the answers here:

CSS3 animation with gradients.

You can also transition the position instead, as described here:

CSS3 gradient transition with background-position.

Some more techniques here:

Animating CSS3 Gradients.

Bantling answered 29/9, 2012 at 3:33 Comment(0)
J
3

In the following, an anchor tag has a child and a grandchild. The grandchild has the far background gradient. The child in the near background is transparent, but has the gradient to transition to. On hover, the child's opacity is transitioned from 0 to 1, over a period of 1 second.

Here is the CSS:

.bkgrndfar {
  position:absolute;
  top:0;
  left:0;
  z-index:-2;
  height:100%;
  width:100%;
  background:linear-gradient(#eee, #aaa);
}

.bkgrndnear {
  position:absolute;
  top:0;
  left:0;
  height:100%;
  width:100%;
  background:radial-gradient(at 50% 50%, blue 1%, aqua 100%);
  opacity:0;
  transition: opacity 1s;
}

a.menulnk {
  position:relative;
  text-decoration:none;
  color:#333;
  padding: 0 20px;
  text-align:center;
  line-height:27px;
  float:left;
}

a.menulnk:hover {
  color:#eee;
  text-decoration:underline;
}

/* This transitions child opacity on parent hover */
a.menulnk:hover .bkgrndnear {
  opacity:1;
}

And, this is the HTML:

<a href="#" class="menulnk">Transgradient
<div class="bkgrndfar">
  <div class="bkgrndnear">
  </div>
</div>
</a>

The above is only tested in the latest version of Chrome. These are the before hover, halfway on-hover and fully transitioned on-hover images:

Before Halfway After

Josey answered 13/7, 2013 at 22:23 Comment(0)
C
3

Found a nice hack on codepen that modifies the opacity property but achieves that fade from one gradient to another by leveraging pseudo-elements. What he does is he sets an :after so that when you change the opacity of the actual element, the :after element shows up so it looks as if it were a fade. Thought it'd be useful to share.

Original codepen: http://codepen.io/sashtown/pen/DfdHh

.button {
  display: inline-block;
  margin-top: 10%;
  padding: 1em 2em;
  font-size: 2em;
  color: #fff;
  font-family: arial, sans-serif;
  text-decoration: none;
  border-radius: 0.3em;
  position: relative;
  background-color: #ccc;
  background-image: linear-gradient(to top, #6d8aa0, #8ba2b4);
  -webkit-backface-visibility: hidden;
  z-index: 1;
}
.button:after {
  position: absolute;
  content: '';
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 0.3em;
  background-image: linear-gradient(to top, #ca5f5e, #d68584);
  transition: opacity 0.5s ease-out;
  z-index: 2;
  opacity: 0;
}
.button:hover:after {
  opacity: 1;
}
.button span {
  position: relative;
  z-index: 3;
}
body {
  text-align: center;
  background: #ddd;
}
<a class="button" href="#"><span>BUTTON</span></a>
Copyright answered 16/3, 2015 at 16:42 Comment(0)
P
3

I wanted to have a div appear like a 3D sphere and transition through colors. I discovered that gradient background colors don't transition (yet). I placed a radial gradient background in front of the element (using z-index) with a transitioning solid background.

/* overlay */
z-index : 1;
background : radial-gradient( ellipse at 25% 25%, rgba( 255, 255, 255, 0 ) 0%, rgba( 0, 0, 0, 1 ) 100% );

then the div.ball underneath:

transition : all 1s cubic-bezier(0.25, 0.46, 0.45, 0.94);

then changed the background color of the div.ball and voila!

https://codepen.io/keldon/pen/dzPxZP

Pansophy answered 26/7, 2017 at 10:33 Comment(0)
I
2

As stated. Gradients aren't currently supported with CSS Transitions. But you could work around it in some cases by setting one of the colors to transparent, so that the background-color of some other wrapping element shines through, and transition that instead.

Insufferable answered 6/8, 2012 at 10:38 Comment(0)
I
2

Try use :before and :after (ie9+)

#wrapper{
    width:400px;
    height:400px;
    margin:0 auto;
    border: 1px #000 solid;
    position:relative;}
#wrapper:after,
#wrapper:before{
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    content:'';
    background: #1e5799;
    background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(50%,#2989d8), color-stop(51%,#207cca), color-stop(100%,#7db9e8));
    background: -webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: -o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: -ms-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: linear-gradient(to bottom, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    opacity:1;
    z-index:-1;
    -webkit-transition: all 2s ease-out;
    -moz-transition: all 2s ease-out;
    -ms-transition: all 2s ease-out;
    -o-transition: all 2s ease-out;
    transition: all 2s ease-out;
}
#wrapper:after{
    opacity:0;
    background: #87e0fd;
    background: -moz-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#87e0fd), color-stop(40%,#53cbf1), color-stop(100%,#05abe0));
    background: -webkit-linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
    background: -o-linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
    background: -ms-linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
    background: linear-gradient(to bottom, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
}
#wrapper:hover:before{opacity:0;}
#wrapper:hover:after{opacity:1;}
Ingamar answered 25/7, 2013 at 13:10 Comment(0)
U
2

I use this at work :) IE6+ https://gist.github.com/GrzegorzPerko/7183390

Don't forget about <element class="ahover"><span>Text</span></a> if you use a text element.

.ahover {
    display: block;
    /** text-indent: -999em; ** if u use only only img **/
    position: relative;
}
.ahover:after {
    content: "";
    height: 100%;
    left: 0;
    opacity: 0;
    position: absolute;
    top: 0;
    transition: all 0.5s ease 0s;
    width: 100%;
    z-index: 1;
}
.ahover:hover:after {
    opacity: 1;
}
.ahover span {
    display: block;
    position: relative;
    z-index: 2;
}
Unidirectional answered 27/10, 2013 at 15:26 Comment(0)
B
2

Can't hurt to post another view since there's still not an official way to do this. Wrote a lightweight jQuery plugin with which you can define a background radial gradient and a transition speed. This basic usage will then let it fade in, optimised with requestAnimationFrame (very smooth) :

$('#element').gradientFade({

    duration: 2000,
    from: '(20,20,20,1)',
    to: '(120,120,120,0)'
});

http://codepen.io/Shikkediel/pen/xbRaZz?editors=001

Keeps original background and all properties intact. Also has highlight tracking as a setting :

http://codepen.io/Shikkediel/pen/VYRZZY?editors=001

Bouse answered 6/1, 2015 at 0:9 Comment(0)
B
1

A much cleaner solution would be to set the background color and use a mask-image.

#container div a {
  background-color: blue;
  transition: background 0.2s linear;
  width: 200px;
  height: 150px;
  mask-image: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, .7), rgba(0, 0, 0, .4));
}

#container div a:hover { 
  background-color: red;
}
Beane answered 7/1, 2022 at 15:35 Comment(0)
B
1

Welcome to 2023 on a super old post. But, I landed here and obviously you did also.

CSS Only

https://jsfiddle.net/BradChesney79/rpa8v50t/

Markup:

<div class="fx-button">
<div class="button-content">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAhCAYAAAALboFLAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV+/UKTFwQ4iHTJUB7EgKuKoVShChVArtOpgcukXNGlIUlwcBdeCgx+LVQcXZ10dXAVB8APE1cVJ0UVK/F9SaBHjwXE/3t173L0D/M0qU83gOKBqlpFJJYVcflXoeUUQIUQQw6jETH1OFNPwHF/38PH1LsGzvM/9OSJKwWSATyCeZbphEW8QT29aOud94igrSwrxOfGYQRckfuS67PIb55LDfp4ZNbKZeeIosVDqYrmLWdlQiaeI44qqUb4/57LCeYuzWq2z9j35C8MFbWWZ6zRjSGERSxAhQEYdFVRhIUGrRoqJDO0nPfxDjl8kl0yuChg5FlCDCsnxg//B727N4uSEmxROAqEX2/4YBnp2gVbDtr+Pbbt1AgSegSut4681gZlP0hsdLX4E9G8DF9cdTd4DLneAwSddMiRHCtD0F4vA+xl9Ux4YuAX61tze2vs4fQCy1FX6Bjg4BEZKlL3u8e7e7t7+PdPu7wdXSnKcEOSXsgAAAAZiS0dEAKMAmwCI3OECOgAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+cEBQ8XBXt+4EwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAABn0lEQVQ4y02UQZJjIQxDn4Rz/7nCrOeEqQlWLww/vUlR+WDZTwL9+/snpAlBLAAs0QkSSKJs0b1YBCQiIUQZEgCoz/9NAh/CfIZtkTQILFPLphMiIALNRmKYFdU92sHPhiBkgRphyssALDFi0qkCWEimktCnQRlo5keCT4BN7b2JjBLSAhnRTz9I1FqLzowvmWQmCsMIgUnONMxpQZLZMH9SO5m1IOlv80cKRJGQDF0pY8eZjEu872hA0wP0yM9K1OtVdPdBsAhgBq41ttfuTXI49zTXBPnyC2V8FExuE4H0o0eNWZk83al4NKenz2c/p/FUUyYRQoQMzLsnV+qBO4rVCeked3tgXjsu+fJa57iQ/SQ9OpkCisMoYioC+1pzBql61bEl4DWkEyLBlXu/3xy3CB/SYOtJBECtVd/G7amkb/MEqrtJQnqPDDrs9QtB91euQ3efe3Dpi3oSmCm/amEy8nruXU8FgWRI0z4X9PZki9Z9KuYt8C+fsSgQT+btyXjOvUtIQslC+aYWglYNSHtg9t6TwA6Rz0vQ493J2g8fnASMeeRW2QAAAABJRU5ErkJggg==" />
<span class="button-text">DESKTOP BUTTON WITH COLOR SHIFT</span>
</div>
</div>
<p>
Drop shadow intrudes into immediate space around the element.
</p>
<p>
Not a particular issue, but something to be aware of.
</p>

CSS:

p {
   border: 1px red solid;
   margin: 0;
   padding: 0;"
}


.fx-button {
  background-image: linear-gradient(15deg, #a09486, #d2c7af);
  border: 1px red solid;
  box-shadow: 5px 5px 13px -4px rgba(0, 0, 0, 0.35);
  -webkit-box-shadow: 5px 5px 13px -4px rgba(0, 0, 0, 0.35);
  color: white;
  height: 33px;
  margin: 0;
  paddng: 0;
  position: relative;
  vertical-align: middle;
  width: fit-content;
  z-index: 1;
}

.fx-button::before {
  background-image: linear-gradient(15deg, #d2c7af, #a09486);
  bottom: 0;
  content: "";
  left: 0;
  opacity: 0;
  position: absolute;
  right: 0;
  top: 0;
  transition: opacity 0.2s linear;
  z-index: -1;
}
.fx-button:hover::before {
  opacity: 1;
}

.button-text {
  border: 0;
  font-family: sans-serif;
  font-size: 12px;
  height: auto;
  margin: 0;
  padding: 0 10px 0 2px;
  position: relative;
  top: -11px;
}
.button-content {
  border: 0;
  height: 33px;
  margin: 0;
  padding: 0;
  width: fit-content;
  vertical-align: middle;
}
Bangle answered 5/4, 2023 at 19:36 Comment(0)
S
0

Thank You Very much

.element {
  position: relative;
  width: 200px;
  height: 150px;
  background-image: linear-gradient(45deg, blue, aqua);
  z-index: 2;
}

.element::before {
  position: absolute;
  content: "";
  inset: 0; /* same as { top: 0; right: 0; bottom: 0; left: 0; } */
  background-image: linear-gradient(to bottom, red, orange);
  z-index: 1;
  opacity: 0;
  transition: opacity 0.25s linear;
}

.element:hover::before {
  opacity: 1;
}
<body>
  <div class="element"></div>
</body>
Soave answered 7/12, 2022 at 6:16 Comment(1)
Could you clarify how this solves the question being asked?Yaelyager
L
0

Here's a quick and simple method using background-blend-mode

.grad {
  height: 100px;
  width: 180px;
  cursor: pointer;
  border-radius: 8px;
  
  /* gradient styling */
  transition: 0.5s background-color;
  background-color: #888; /* initial luminosity */
  background-image: linear-gradient(DodgerBlue, MediumSlateBlue);
  background-blend-mode: color;
}
.grad:hover {
  background-color: #aaa; /* hover state luminosity */
}
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<div class="grad"></div>
</body>
</html>

It only transitions between two luminosity values, so use it in cases where a simple effect is sufficient. It's a CSS only solution and doesn't require preparing an image. (Although it can of course be used with an image too.)

More on the background-blend-mode property

Reference of blend mode types

Lethargy answered 10/11, 2023 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.