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)))
}
This question is related to
css
gradient
css-transitions
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 :
All you have to do is use the ::before pseudo-element with zero opacity.
On :hover, switch opacity to 1 and if you follow a few simple steps, you should get your transition working.
.element {
position: relative;
width: 500px;
height: 400px;
background-image: linear-gradient(45deg, blue, aqua);
z-index: 2;
}
.element::before {
position: absolute;
content: "";
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: linear-gradient(to bottom, red, orange);
z-index: 1;
opacity: 0;
transition: opacity 0.4s linear;
}
.element:hover::before {
opacity: 1;
}
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;}
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
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:
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;
}
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 {_x000D_
display: inline-block;_x000D_
margin-top: 10%;_x000D_
padding: 1em 2em;_x000D_
font-size: 2em;_x000D_
color: #fff;_x000D_
font-family: arial, sans-serif;_x000D_
text-decoration: none;_x000D_
border-radius: 0.3em;_x000D_
position: relative;_x000D_
background-color: #ccc;_x000D_
background-image: linear-gradient(to top, #6d8aa0, #8ba2b4);_x000D_
-webkit-backface-visibility: hidden;_x000D_
z-index: 1;_x000D_
}_x000D_
.button:after {_x000D_
position: absolute;_x000D_
content: '';_x000D_
top: 0;_x000D_
left: 0;_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
border-radius: 0.3em;_x000D_
background-image: linear-gradient(to top, #ca5f5e, #d68584);_x000D_
transition: opacity 0.5s ease-out;_x000D_
z-index: 2;_x000D_
opacity: 0;_x000D_
}_x000D_
.button:hover:after {_x000D_
opacity: 1;_x000D_
}_x000D_
.button span {_x000D_
position: relative;_x000D_
z-index: 3;_x000D_
}_x000D_
body {_x000D_
text-align: center;_x000D_
background: #ddd;_x000D_
}
_x000D_
<a class="button" href="#"><span>BUTTON</span></a>
_x000D_
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.
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 {_x000D_
display: inline-block;_x000D_
margin-top: 10%;_x000D_
padding: 1em 2em;_x000D_
font-size: 2em;_x000D_
color: #fff;_x000D_
font-family: arial, sans-serif;_x000D_
text-decoration: none;_x000D_
border-radius: 0.3em;_x000D_
position: relative;_x000D_
background-color: #ccc;_x000D_
background-image: linear-gradient(to top, #C0357E, #EE5840);_x000D_
-webkit-backface-visibility: hidden;_x000D_
z-index: 1;_x000D_
}_x000D_
_x000D_
#container div a:after {_x000D_
position: absolute;_x000D_
content: '';_x000D_
top: 0;_x000D_
left: 0;_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
border-radius: 0.3em;_x000D_
background-image: linear-gradient(to top, #6d8aa0, #343436);_x000D_
transition: opacity 0.5s ease-out;_x000D_
z-index: 2;_x000D_
opacity: 0;_x000D_
}_x000D_
_x000D_
#container div a:hover:after {_x000D_
opacity: 1;_x000D_
}_x000D_
#container div a span {_x000D_
position: relative;_x000D_
z-index: 3;_x000D_
}
_x000D_
<div id="container"><div><a href="#"><span>Press Me</span></a></div></div>
_x000D_
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 :)
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;
}
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!
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));}
}
_x000D_
<div class="contener" style="">
<div class="ed"></div>
</div>
_x000D_
With Chrome 85 (and also Edge) adding support for @property rule, now we can do this in CSS:
@property --colorPrimary {
syntax: '<color>';
initial-value: magenta;
inherits: false;
}
@property --colorSecondary {
syntax: '<color>';
initial-value: green;
inherits: false;
}
The rest is normal CSS.
Set initial gradient colors to the variables and also set the transition of those variables:
div {
/* Optional: change the initial value of variables
--colorPrimary: #f64;
--colorSecondary: brown;
*/
background: radial-gradient(circle, var(--colorPrimary) 0%, var(--colorSecondary) 85%) no-repeat;
transition: --colorPrimary 3s, --colorSecondary 3s;
}
Then, on the desired rule, set the new values for variables:
div:hover {
--colorPrimary: yellow;
--colorSecondary: #f00;
}
@property --colorPrimary {
syntax: '<color>';
initial-value: #0f0;
inherits: false;
}
@property --colorSecondary {
syntax: '<color>';
initial-value: rgb(0, 255, 255);
inherits: false;
}
div {
width: 200px;
height: 100px;
background: radial-gradient(circle, var(--colorPrimary) 0%, var(--colorSecondary) 85%) no-repeat;
transition: --colorPrimary 3s, --colorSecondary 3s;
}
div:hover {
--colorPrimary: red;
--colorSecondary: #00f;
}
_x000D_
<div>Hover over me</div>
_x000D_
See the full example here and refer here for @property
support status.
The @property rule is part of the CSS Houdini technology. For more info refer here and here.
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{ _x000D_
background: -webkit-linear-gradient(#C7D3DC,#5B798E); _x000D_
background: -moz-linear-gradient(#C7D3DC,#5B798E); _x000D_
background: -o-linear-gradient(#C7D3DC,#5B798E); _x000D_
background: linear-gradient(#C7D3DC,#5B798E); _x000D_
_x000D_
-webkit-transition: background 1s ease-out; _x000D_
-moz-transition: background 1s ease-out; _x000D_
-o-transition: background 1s ease-out; _x000D_
transition: background 1s ease-out; _x000D_
_x000D_
background-size:1px 200px; _x000D_
border-radius: 10px; _x000D_
border: 1px solid #839DB0; _x000D_
cursor:pointer; _x000D_
width: 150px; _x000D_
height: 100px; _x000D_
} _x000D_
#DemoGradient:Hover{ _x000D_
background-position:100px; _x000D_
}
_x000D_
<div id="DemoGradient"></div>
_x000D_
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:
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;
}
Source: Stackoverflow.com