Reputation: 2405
I want to change a background after a time. If the background has got a "clear" color there is no problem but if the color is a gradient set as the code doesn't work. is there a work around for that?
background: -webkit-linear-gradient(rgba(39,49,67,1), rgba(226,228,209,1)); /*For Safari 5.1 to 6.0 */
background: -o-linear-gradient(rgba(39,49,67,1), rgba(226,228,209,1)); /*For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(rgba(39,49,67,1),rgba(39,49,67,1), rgba(226,228,209,1)); /*For Firefox 3.6 to 15 */
background: linear-gradient(rgba(39,49,67,1),rgba(51,90,109,1),rgba(83,142,144,1), rgba(226,228,209,1)); /*Standard syntax */
jsfiddle for normal color change
Upvotes: 4
Views: 6699
Reputation: 21
You could try LinearGradient.js to create random and colorful linear gradients.
Upvotes: 2
Reputation: 942
CSS3 doesn't support linear gradient animations, so in order to achieve this effect you'll have to write the animation your self in Javascript or use a background-position trick like the one stated by Easwee. I prefer Javascript because it allows you to easily reuse the code, add dynamic effects, and quickly modify the effect. That being said Easwee's solution is really ingenious although somewhat limiting.
Even though CSS doesn't natively support gradient animations as Easwee stated we can use a "hack" to create gradient animation in css by manipulating the background position of the image.
Example (Go full screen):
body {
margin: 20px;
background-color: #000;
}
.container {
position: relative;
margin: 0 auto;
width: 480px;
height: 140px;
background-color: #333;
border-radius: 8px;
}
button {
position: absolute;
width: 160px;
height: 36px;
top: calc(50% - 18px);
left: 50px;
border: solid 1px #ccc;
border-radius: 8px;
color: #fff;
font: 16px sans-serif;
/* set up background gradient and animation */
background-image: linear-gradient(#5187c4, #1c2f45);
background-size: auto 200%;
background-position: 0 100%;
transition: background-position 0.5s;
}
.container:hover button {
/* shift background gradient position */
background-position: 0 0;
}
.slider {
position: absolute;
top: calc(50% - 18px);
right: 50px;
margin-top: -36px;
width: 160px;
height: 72px;
background-image: linear-gradient(#5187c4, #1c2f45);
transition: margin-top .5s;
}
.container:hover .slider {
margin-top: 0px;
}
.frame {
position: absolute;
top: calc(50% - 18px);
right: 50px;
box-sizing: border-box;
width: 160px;
height: 36px;
border: solid 1px #ccc;
border-radius: 8px;
}
.info {
margin: 20px auto 0;
color: #ccc;
font: 18px/150% sans-serif;
text-align: justify;
width: 480px;
}
<div class="container">
<button disabled>Some Button</button>
<div class="slider"></div>
<div class="frame"></div>
</div>
<div class="info">
You can't animate gradient colors with pure CSS. Gradients are set via background-image, which is not (currently) an animatable property. But background-position is. So you can use background-size to make the background taller than the element it's on, then animate background-position to slide it up or down. The result is a simple animated fading gradient.
</div>
In order to build a Javascript based gradient animation we need to:
(If you'd like a code solution let me know. It is a lengthy process to type up, so for that reason if you're only using this once and for two maybe three gradient colors use Eawee's solution. Otherwise Javascript's your friend.)
var colors = new Array(
[62,35,255],
[60,255,60],
[255,35,98],
[45,175,230],
[255,0,255],
[255,128,0]);
var step = 0;
//color table indices for:
// current color left
// next color left
// current color right
// next color right
var colorIndices = [0,1,2,3];
//transition speed
var gradientSpeed = 0.002;
function updateGradient()
{
if ( $===undefined ) return;
var c0_0 = colors[colorIndices[0]];
var c0_1 = colors[colorIndices[1]];
var c1_0 = colors[colorIndices[2]];
var c1_1 = colors[colorIndices[3]];
var istep = 1 - step;
var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);
var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);
var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);
var color1 = "rgb("+r1+","+g1+","+b1+")";
var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);
var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);
var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);
var color2 = "rgb("+r2+","+g2+","+b2+")";
$('#gradient').css({
background: "-webkit-gradient(linear, left top, right top, from("+color1+"), to("+color2+"))"}).css({
background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});
step += gradientSpeed;
if ( step >= 1 )
{
step %= 1;
colorIndices[0] = colorIndices[1];
colorIndices[2] = colorIndices[3];
//pick two new target color indices
//do not pick the same as the current one
colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length - 1))) % colors.length;
colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length - 1))) % colors.length;
}
}
setInterval(updateGradient,10);
body{
background-color: #000000;
padding: 0px;
margin: 0px;
}
#gradient
{
width: 100%;
height: 800px;
padding: 0px;
margin: 0px;
}
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
</head>
<body>
<div id="gradient" />
</body>
</html>
Javascript Based Gradient Animator (Code Pen)
CSS Gradient Animator Generator
CSS Gradient Animator Walkthrough
Upvotes: 8
Reputation: 15905
What Dbugger said is true - you can't animate a background image with css animations.
However, you could fake it with a 4 stop gradient (cleverly position your color stops - I suggest using a gradient generator as Colorzilla or similar - will make your work easier ) - since a gradient is treated as a background-image
, you can animate it's position by using background-position
. In order to animate the position you need to increase it's size so part of the gradient is outside your container.
You can use animation-delay
to set the initial delay before the animation starts.
html, body {width:100%;height:100%;margin:0;}
div {
width: 100%;
height: 100%;
background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(118,191,36,1) 25%, rgba(224,117,35,1) 50%, rgba(242,38,42,1) 75%, rgba(130,100,70,1) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(30,87,153,1)), color-stop(25%,rgba(118,191,36,1)), color-stop(50%,rgba(224,117,35,1)), color-stop(75%,rgba(242,38,42,1)), color-stop(100%,rgba(130,100,70,1)));
background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(118,191,36,1) 25%,rgba(224,117,35,1) 50%,rgba(242,38,42,1) 75%,rgba(130,100,70,1) 100%);
background: linear-gradient(to bottom, rgba(30,87,153,1) 0%,rgba(118,191,36,1) 25%,rgba(224,117,35,1) 50%,rgba(242,38,42,1) 75%,rgba(130,100,70,1) 100%);
background-size: 100% 400%;
background-position:0 0;
-webkit-animation: animateGradient 5s ease 1;
-moz-animation: animateGradient 5s ease 1;
animation: animateGradient 5s ease 1;
-webkit-animation-delay: 2s;
-moz-animation-delay: 2s;
animation-delay: 2s;
}
@-webkit-keyframes animateGradient {
0% {background-position: 0 0;}
50% {background-position: 0 100%;}
100% {background-position: 0 0;}
}
@-moz-keyframes animateGradient {
0% {background-position: 0 0;}
50% {background-position: 0 100%;}
100% {background-position: 0 0;}
}
@keyframes animateGradient {
0% {background-position: 0 0;}
50% {background-position: 0 100%;}
100% {background-position: 0 0;}
}
<div></div>
Alternative: Another approach you could take is to overlay one element over the other, set the initial gradient in top and ending gradient in the bottom element , and create an opacity animation, that fades out the top element after a certain amount of time (opacity: 0
)
Below is an approach on how you can do it with a single element in markup (rely on the :after
or :before
pseudo element). The following approach has more compatibility cross devices:
html, body {width:100%;height:100%;margin:0;}
.gradient {
position:relative;
width: 100%;
height: 100%;
background: -webkit-linear-gradient(rgba(39,49,67,1), rgba(226,228,209,1));
background: -o-linear-gradient(rgba(39,49,67,1), rgba(226,228,209,1));
background: -moz-linear-gradient(rgba(39,49,67,1),rgba(39,49,67,1), rgba(226,228,209,1));
background: linear-gradient(rgba(39,49,67,1),rgba(39,49,67,1), rgba(226,228,209,1));
}
.gradient:after {
content:"";
position:absolute;
top:0;
left:0;
width: 100%;
height: 100%;
background: -webkit-linear-gradient(rgba(226,228,209,1), rgba(39,49,67,1));
background: -o-linear-gradient(rgba(226,228,209,1), rgba(39,49,67,1));
background: -moz-linear-gradient(rgba(226,228,209,1), rgba(39,49,67,1));
background: linear-gradient(rgba(226,228,209,1), rgba(39,49,67,1));
opacity: 0;
-webkit-animation: animateGradient 3s linear 1;
-moz-animation: animateGradient 3s linear 1;
animation: animateGradient 3s linear 1;
}
@-webkit-keyframes animateGradient {
0% {opacity:1;}
100% {opacity:0;}
}
@-moz-keyframes animateGradient {
0% {opacity:1;}
100% {opacity:0;}
}
@keyframes animateGradient {
0% {opacity:1;}
100% {opacity:0;}
}
<div class="gradient"></div>
Upvotes: 14
Reputation: 25267
A background-gradient is considered a background-image
, and background images can NOT be animated through normal CSS transitions.
Upvotes: 4