Animating a CSS gradient background on the hover event - html

I have some menu items that are styled using a background gradient on hover using the following styling:
#sidebar ul li a:hover {
background-image: linear-gradient(bottom, rgb(68,68,68) 5%, rgb(51,51,51) 100%);
background-image: -o-linear-gradient(bottom, rgb(68,68,68) 5%, rgb(51,51,51) 100%);
background-image: -moz-linear-gradient(bottom, rgb(68,68,68) 5%, rgb(51,51,51) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(68,68,68) 5%, rgb(51,51,51) 100%);
background-image: -ms-linear-gradient(bottom, rgb(68,68,68) 5%, rgb(51,51,51) 100%);
background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.05, rgb(68,68,68)),
color-stop(1, rgb(51,51,51))
);
color: #f0f0f0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
My question is, is it possible to make the new background (defined by gradients) slide in from the right using CSS3 transitions or animations? Or will I have to resort to using a sprite image or Javascript?

Animation on gradients aren't supported yet. However this site provides a pleasing approach for a animated kind of feel on hover-
http://sapphion.com/2011/10/css3-gradient-transition-with-background-position/
Sample css:-
#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;
}

It seems gradients don't support transitions yet (still):
Use CSS3 transitions with gradient backgrounds
If you use a background image rather than a css3 gradient, then you can use css transition to animate it in and out.

Try this as a hack:
<div class="background-animate">
<div class="content">Hi im content</div>
</div>
And style it
.background-animate {
position: relative;
z-index: 10;
display: block;
background: transparent;
}
.background-animate:before {
content: "";
position: absolute;
transition: opacity .35s ease-in-out;
-moz-transition: opacity .35s ease-in-out;
-webkit-transition: opacity .35s ease-in-out;
top:0; left: 0; right: 0; bottom: 0; z-index:-1;
background: -moz-radial-gradient(center, ellipse cover, #ffffff 40%, #e9eae9 100%); /* FF3.6-15 */
background: -webkit-radial-gradient(center, ellipse cover, #ffffff 40%,#e9eae9 100%); /* Chrome10-25,Safari5.1-6 */
background: radial-gradient(ellipse at center, #ffffff 40%,#e9eae9 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
}
.background-animate:hover:before {
opacity: 0;
}
.background-animate:after {
content: ""; opacity: 0;
transition: opacity .35s ease-in-out;
-moz-transition: opacity .35s ease-in-out;
-webkit-transition: opacity .35s ease-in-out;
position: absolute;
top:0; left: 0; right: 0; bottom: 0; z-index:-1;
background: -moz-radial-gradient(center, ellipse cover, #ffffff 80%, #e9eae9 100%); /* FF3.6-15 */
background: -webkit-radial-gradient(center, ellipse cover, #ffffff 80%,#e9eae9 100%); /* Chrome10-25,Safari5.1-6 */
background: radial-gradient(ellipse at center, #ffffff 80%,#e9eae9 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
}
.background-animate:hover:after {
opacity: 1;
}
It basically does an opacity switch between to gradients. Demo found here https://codepen.io/anon/pen/eWOEoR

Related

Animation of linear gradient using css variables (Chrome) [duplicate]

I want to move my gradient that has multiple colors smoothly but the problem is that the animation is not smooth. It just changes its position at every step.
<style>
.animated {
width: 300px;
height: 300px;
border: 1px solid black;
animation: gra 5s infinite;
animation-direction: reverse;
-webkit-animation: gra 5s infinite;
-webkit-animation-direction: reverse;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
}
#keyframes gra {
0% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(21%, #ff670f), color-stop(56%, #ffffff), color-stop(88%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
}
50% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(10%, #ff670f), color-stop(40%, #ffffff), color-stop(60%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
}
100% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(5%, #ff670f), color-stop(10%, #ffffff), color-stop(40%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
}
}
</style>
<div class="animated">
<h1>Hello</h1>
</div>
Is it possible to accomplish without using jQuery?
My jsfiddle link is https://jsfiddle.net/bAUK6
Please try this code:
#gradient
{
height:300px;
width:300px;
border:1px solid black;
font-size:30px;
background: linear-gradient(130deg, #ff7e00, #ffffff, #5cff00);
background-size: 200% 200%;
-webkit-animation: Animation 5s ease infinite;
-moz-animation: Animation 5s ease infinite;
animation: Animation 5s ease infinite;
}
#-webkit-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#-moz-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
<html>
<div id="gradient">
Hello
</div>
</html>
Dynamic implementation of Dave's answer:
:root{
--overlay-color-1: #ff0000;
--overlay-color-2: #0000ff;
--anim-duration: 2s;
}
#gradient {
opacity: 0.8;
background: none;
}
#gradient:after,
#gradient:before {
content: '';
display: block;
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
#gradient:before {
background: linear-gradient(135deg, var(--overlay-color-2) 0%, var(--overlay-color-1) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out 0s infinite alternate;
}
#gradient:after {
background: linear-gradient(135deg, var(--overlay-color-1) 0%, var(--overlay-color-2) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out calc(-1 * var(--anim-duration)) infinite alternate;
}
#keyframes OpacityAnim {
0%{opacity: 1.0}
100%{opacity: 0.0}
}
<div id="gradient"></div>
Using CSS variables it's now a trivial task.
Here is a basic example (hover to see the result)
#property --a{
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}
#property --l{
syntax: '<percentage>';
inherits: false;
initial-value: 10%;
}
#property --c{
syntax: '<color>';
inherits: false;
initial-value: red;
}
.box {
/* needed for firefox to have a valid output */
--a:80deg;
--l:10%;
--c:red;
/**/
cursor:pointer;
height:200px;
transition:--a 0.5s 0.1s,--l 0.5s,--c 0.8s;
background:linear-gradient(var(--a), var(--c) var(--l),blue,var(--c) calc(100% - var(--l)));
}
.box:hover {
--a:360deg;
--l:40%;
--c:green;
}
<div class="box"></div>
More details here: https://dev.to/afif/we-can-finally-animate-css-gradient-kdk
How about this:
Set the body margin and padding to 0. Set an html rule to 100% height (higher than 100% may be required).
Set the body to the end state for the gradient.
Create an empty div with a background which is the start state for the gradient. Give the empty div 100% height.
Give both the body and the empty div a background-attachment: fixed;
Create a wrapper for your body content.
Set the empty div to position: fixed;
Set the wrapper to position: relative;
Give both a z-index, the wrapper being higher.
Create an animation that will change the opacity of the empty div from 1 to 0 over the desired time. Add animation-fill-mode:forwards; to the div rule so the animation stays where it ends.
It's not as sexy as a real animated gradient shift, but it's as simple as you can get with CSS only and keyframes, I think.
Here is another way. The following has the static gradient containing all phases of the animation, which is then moved inside the outer element. This allows to perform animation smoothly (as the topic suggests), because the only animation here is the element position.
Please note that for the sake of performance the gradient element left unchanged. Although the question was to animate the gradient, moving the background does practically the same thing, while the performance wins!
.animated {
width: 300px;
height: 300px;
overflow: hidden;
position: relative;
border: 1px solid black;
}
.innerGradient {
z-index: -1;
width: 300%;
height: 300%;
position: absolute;
animation: gra 5s infinite;
-webkit-animation: gra 5s infinite;
background: linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
background: -webkit-linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
}
#keyframes gra {
0% { left: -200%; top: -200%; }
50% { left: 0%; top: 0%; }
100% { left: -200%; top: -200%; }
}
<div class="animated">
<h1>Hello</h1>
<div class="innerGradient"></div>
</div>

Webkit Transition isnt working in Edge browser

Afternoon, is there a reason as to why the css attribute -webkit-transition: all .8s ease-in-out;isn't doing what it's supposed to?
Browser is MS Edge, my code is below.
Thanks
Todd
.callToActionDefault:hover {
color: white;
text-decoration: none;
background: -webkit-gradient(linear, left top, left bottom, color-stop(20%, #0d89ca), color-stop(100%, #0d89ca));
background: -webkit-linear-gradient(top, #0d89ca 20%, #0d89ca 100%);
background: linear-gradient(to bottom, #0d89ca 20%, #0d89ca 100%);
}
.callToActionDefault {
padding: 8px;
font-size: 15px;
margin-top: 20px;
letter-spacing: 0.5px;
color: white;
width: 60%;
display: block;
position: relative;
background: -webkit-gradient(linear, left top, left bottom, color-stop(20%, #219cdd), color-stop(100%, #0d89ca));
background: -webkit-linear-gradient(top, #219cdd 20%, #0d89ca 100%);
background: linear-gradient(to bottom, #219cdd 20%, #0d89ca 100%);
bottom: 0;
font-weight: 700;
-webkit-transition: all .8s ease-in-out;
}
<a class="callToActionDefault" href="#">This is a button</a>
It doesn't work, because Edge is not a Webkit-based browser. The -webkit- prefix is a feature of old Webkit-based browsers such as Google Chrome.
In order to achieve maximum compatibility with older and newer browsers use the following code:
-webkit-transition: all .8s ease-in-out; // Old Chrome, Safari
-moz-transition: all .8s ease-in-out; // Old Firefox
-ms-transition: all .8s ease-in-out; // Internet Explorer
-o-transition: all .8s ease-in-out; // Old Opera
transition: all .8s ease-in-out; // Newer Browsers

Transition from a gradient to a non-gradient background on hover

I am using a gradient to set the background color on one element. The thing is, I am also having an "hover" background but not using the gradient. At the minute, when I hover on an element having the class .tinted it flashes as it first display no background and then apply the rgba(0,0,0,0.65)
Is there any way that the transition could directly go from background: gradient(left, rgba(0,0,0,0.65), rgba(0,0,0,0.30)) to rgba(0,0,0,0.65) ?
.tinted {
transition: background-color 500ms linear;
background: -webkit-linear-gradient(left, rgba(0,0,0,.65), rgba(0,0,0,.30));
background: -o-linear-gradient(right, rgba(0,0,0,.65), rgba(0,0,0,.30));
background: -moz-linear-gradient(right, rgba(0,0,0,.65), rgba(0,0,0,.30));
background: linear-gradient(to right, rgba(0,0,0,.65), rgba(0,0,0,.30));
}
.tinted:hover {
background: rgba(0, 0, 0, 0.65);
}
You need to define the gradients with background-image and the plain color with background-color:
.tinted {
transition: background-color 500ms linear;
background-image: -webkit-linear-gradient(left, rgba(0,0,0,.65), rgba(0,0,0,.30));
background-image: -o-linear-gradient(right, rgba(0,0,0,.65), rgba(0,0,0,.30));
background-image: -moz-linear-gradient(right, rgba(0,0,0,.65), rgba(0,0,0,.30));
background-image: linear-gradient(to right, rgba(0,0,0,.65), rgba(0,0,0,.30));
}
.tinted:hover {
background-color: rgba(0, 0, 0, 0.65);
}
DEMO
This Is What you Can Use For This Approach:
#box{
width: 200px;
height: 300px;
background-color: orange;
background-image: -webkit-linear-gradient(top, crimson 0%, transparent 100%);
transition: all 1s ease-in-out;
}
#box:hover{
background-color: crimson;
}
<div id="box"></div>
A posibility is to set a gradient that has 2 parts, one with the color changing, and the other with a constant color.
And change the part of the gradient that you are showing with background-image.position
.test {
width: 300px;
height: 100px;
background-image: linear-gradient(to right, rgba(0,0,0,0.65) 50%, rgba(0,0,0,0.3));
background-size: 200% 100%;
background-position: 100% 0%;
transition: background-position 1s;
margin: 10px;
}
.test:hover {
background-position: 0% 0%;
}
#test2 {
background-image: linear-gradient(to right, blue 50%, red 100%);
}
<div class="test"></div>
<div class="test" id="test2"></div>

How to Animate Gradients using CSS

I want to move my gradient that has multiple colors smoothly but the problem is that the animation is not smooth. It just changes its position at every step.
<style>
.animated {
width: 300px;
height: 300px;
border: 1px solid black;
animation: gra 5s infinite;
animation-direction: reverse;
-webkit-animation: gra 5s infinite;
-webkit-animation-direction: reverse;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
}
#keyframes gra {
0% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(21%, #ff670f), color-stop(56%, #ffffff), color-stop(88%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
}
50% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(10%, #ff670f), color-stop(40%, #ffffff), color-stop(60%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
}
100% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(5%, #ff670f), color-stop(10%, #ffffff), color-stop(40%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
}
}
</style>
<div class="animated">
<h1>Hello</h1>
</div>
Is it possible to accomplish without using jQuery?
My jsfiddle link is https://jsfiddle.net/bAUK6
Please try this code:
#gradient
{
height:300px;
width:300px;
border:1px solid black;
font-size:30px;
background: linear-gradient(130deg, #ff7e00, #ffffff, #5cff00);
background-size: 200% 200%;
-webkit-animation: Animation 5s ease infinite;
-moz-animation: Animation 5s ease infinite;
animation: Animation 5s ease infinite;
}
#-webkit-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#-moz-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
<html>
<div id="gradient">
Hello
</div>
</html>
Dynamic implementation of Dave's answer:
:root{
--overlay-color-1: #ff0000;
--overlay-color-2: #0000ff;
--anim-duration: 2s;
}
#gradient {
opacity: 0.8;
background: none;
}
#gradient:after,
#gradient:before {
content: '';
display: block;
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
#gradient:before {
background: linear-gradient(135deg, var(--overlay-color-2) 0%, var(--overlay-color-1) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out 0s infinite alternate;
}
#gradient:after {
background: linear-gradient(135deg, var(--overlay-color-1) 0%, var(--overlay-color-2) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out calc(-1 * var(--anim-duration)) infinite alternate;
}
#keyframes OpacityAnim {
0%{opacity: 1.0}
100%{opacity: 0.0}
}
<div id="gradient"></div>
Using CSS variables it's now a trivial task.
Here is a basic example (hover to see the result)
#property --a{
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}
#property --l{
syntax: '<percentage>';
inherits: false;
initial-value: 10%;
}
#property --c{
syntax: '<color>';
inherits: false;
initial-value: red;
}
.box {
/* needed for firefox to have a valid output */
--a:80deg;
--l:10%;
--c:red;
/**/
cursor:pointer;
height:200px;
transition:--a 0.5s 0.1s,--l 0.5s,--c 0.8s;
background:linear-gradient(var(--a), var(--c) var(--l),blue,var(--c) calc(100% - var(--l)));
}
.box:hover {
--a:360deg;
--l:40%;
--c:green;
}
<div class="box"></div>
More details here: https://dev.to/afif/we-can-finally-animate-css-gradient-kdk
How about this:
Set the body margin and padding to 0. Set an html rule to 100% height (higher than 100% may be required).
Set the body to the end state for the gradient.
Create an empty div with a background which is the start state for the gradient. Give the empty div 100% height.
Give both the body and the empty div a background-attachment: fixed;
Create a wrapper for your body content.
Set the empty div to position: fixed;
Set the wrapper to position: relative;
Give both a z-index, the wrapper being higher.
Create an animation that will change the opacity of the empty div from 1 to 0 over the desired time. Add animation-fill-mode:forwards; to the div rule so the animation stays where it ends.
It's not as sexy as a real animated gradient shift, but it's as simple as you can get with CSS only and keyframes, I think.
Here is another way. The following has the static gradient containing all phases of the animation, which is then moved inside the outer element. This allows to perform animation smoothly (as the topic suggests), because the only animation here is the element position.
Please note that for the sake of performance the gradient element left unchanged. Although the question was to animate the gradient, moving the background does practically the same thing, while the performance wins!
.animated {
width: 300px;
height: 300px;
overflow: hidden;
position: relative;
border: 1px solid black;
}
.innerGradient {
z-index: -1;
width: 300%;
height: 300%;
position: absolute;
animation: gra 5s infinite;
-webkit-animation: gra 5s infinite;
background: linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
background: -webkit-linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
}
#keyframes gra {
0% { left: -200%; top: -200%; }
50% { left: 0%; top: 0%; }
100% { left: -200%; top: -200%; }
}
<div class="animated">
<h1>Hello</h1>
<div class="innerGradient"></div>
</div>

How to reverse a CSS animation on unchecked state?

My project will display a sunny field and a check box that says "make it rain". Upon clicking the button the sun sets, and clouds come in, and there will be animated CSS rain. I'm using a checked pseudo class to start the rain animation and the rotation of the sun.
How can I reverse the animation for the unchecked state?
The order the page should work in is as follows:
Page loads, default unchecked state of button, sun should be up
User clicks button, pseudo class:checked gets activated and the animation starts
User clicks button again, thus unchecking the button and the animation should reverse to it's original state.
Right now, it just resets the whole page when the button gets unchecked. Is there a way to reverse the animation to it's original state without using any JavaScript? This project is CSS only.
.sky {
height: 70%;
width: 100%;
position: absolute;
z-index: 1;
background: #e4f5fc;
/* Old browsers */
background: -moz-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e4f5fc), color-stop(33%, #bfe8f9), color-stop(86%, #9fd8ef));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
/* Opera 11.10+ */
background: -ms-linear-gradient(top, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
/* IE10+ */
background: linear-gradient(to bottom, #e4f5fc 0%, #bfe8f9 33%, #9fd8ef 86%);
/* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4f5fc', endColorstr='#9fd8ef', GradientType=0);
/* IE6-9 */
}
.rainsun {
position: absolute;
margin: 35px 45%;
width: 15.74803%;
/*--300px--*/
color: white;
text-align: center;
text-shadow: 0 1px 0 rgba(0, 0, 0, .5);
font-size: 2.5em;
cursor: pointer;
z-index: 5;
}
.rainsun:after {
position: absolute;
display: block;
padding: 10px 0;
width: 100%;
/*--300px--*/
border: 1px solid #76011b;
border-radius: 8px;
background: linear-gradient(to bottom, rgba(169, 3, 41, 1) 0%, rgba(143, 2, 34, 1) 44%, rgba(109, 0, 25, 1) 100%);
box-shadow: 0px 0px 10px rgba(19, 93, 158, .6);
content: "Make it Rain";
z-index: 5;
}
.rainsun:checked:after {
background: linear-gradient(to bottom, rgba(109, 0, 25, 1) 0%, rgba(143, 2, 34, 1) 61%, rgba(169, 3, 41, 1) 100%);
content: "Make it Shine";
}
.sun_path {
border: 1px dashed black;
width: 44.094488%;
height: 100%;
position: absolute;
z-index: 2;
border-radius: 50%;
margin-left: 10%;
margin-top: 10%;
}
.sun {
width: 30%;
height: 30%;
background-color: yellow;
border: 8px solid orange;
border-radius: 50%;
box-shadow: 0 0 128px red;
margin: auto;
margin-top: -15%;
}
.grass {
height: 30%;
width: 100%;
position: absolute;
bottom: 0;
z-index: 3;
background: #9dd53a;
/* Old browsers */
background: -moz-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9dd53a), color-stop(23%, #a1d54f), color-stop(70%, #80c217), color-stop(100%, #7cbc0a));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
/* Opera 11.10+ */
background: -ms-linear-gradient(top, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
/* IE10+ */
background: linear-gradient(to bottom, #9dd53a 0%, #a1d54f 23%, #80c217 70%, #7cbc0a 100%);
/* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9dd53a', endColorstr='#7cbc0a', GradientType=0);
/* IE6-9 */
}
/*animations*/
.rainsun:checked~.sun_path {
-webkit-animation: spin-right 3s 1 forwards;
-moz-animation: spin-right 3s 1 forwards;
animation: spin-right 3s 1 forwards;
}
/* keyframes */
#-webkit-keyframes spin-right {
100% {
-webkit-transform: rotate(180deg);
}
}
#-moz-keyframes spin-right {
100% {
-webkit-transform: rotate(180deg);
}
}
<input class="rainsun" type="checkbox">
<div class="sky">
</div>
<!--end sky-->
<div class="sun_path">
<div class="sun"></div>
</div>
<!--end sun_path-->
<div class="grass">
</div>
<!--end grass-->
Instead of using keyframes, try a transform and set transition: transform. Here's an example of what I'm talking about:
.rainsun ~ .sun_path {
-webkit-transition: -webkit-transform 3s;
-moz-transition: -moz-transform 3s;
transition: transform 3s;
}
.rainsun:checked ~ .sun_path {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
Codepen Fork: Demo