Related
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>
I am trying to make a lively blob that blobs smoothly around the shape's plane. However, when I make this approach, the blob is very rigid and the flow of 0-25-50-75-100 can be directly seen in the animation. I am guessing this is because of the ease-in-out transition but I am not sure what to do next. I have tried linear, ease-in, ease-out, and ease-in-out but they are all very choppy
What should I change to make it a smoother animated blob?
.shape-container{
display: flex;
align-items: center;
justify-content: center;
height:100vh;
}
.shape{
width: 400px;
height: 400px;
background: linear-gradient(64deg, #f34868 23%, #f24768 23%, #9e00ec 80%);
animation: blob 8s ease-in-out infinite;
}
#keyframes blob {
0%, 100% {
border-radius:65% 100% 80% 100%
}
25% {
border-radius:100% 80% 100% 65%
}
50% {
border-radius:80% 100% 65% 100%
}
75% {
border-radius:100% 65% 100% 80%
}
}
<div class="shape-container">
<div class="shape"/>
</div>
[UPDATE] This is the 2nd blob I tried, this blob also does not smoothly rotate around, it just goes back and forth
.shape-container{
display: flex;
align-items: center;
justify-content: center;
height:100vh;
}
.shape{
width: 400px;
height: 400px;
background: linear-gradient(64deg, #f34868 23%, #f24768 23%, #9e00ec 80%);
animation: blob 8s ease-in-out infinite;
}
#keyframes blob {
0%, 100% {
border-radius:24% 76% 35% 65% / 27% 36% 64% 73%
}
25% {
border-radius:76% 24% 33% 67% / 68% 55% 45% 32%
}
}
<div class="shape-container">
<div class="shape"/>
</div>
I would have another look at the linear animation timing function because it has the same speed from start to end. Also if you combine the blob animation with a rotate animation you don't easily get the idea there is a pattern in the entire animation.
* {
margin: 0;
padding: 0;
}
.shape-container{
display: flex;
align-items: center;
justify-content: center;
height:100vh;
background-color: #222;
}
.shape{
width: 400px;
height: 400px;
background: linear-gradient(64deg, #f34868 23%, #f24768 23%, #9e00ec 80%);
border-radius: 28% 72% 22% 78% / 39% 23% 77% 61%;
transform: rotate(0deg);
will-change: border-radius, transform;
animation: blob 10s linear infinite, spin 100s linear infinite;
}
#keyframes blob {
0%, 100% {
border-radius: 28% 72% 22% 78% / 39% 23% 77% 61%;
}
50% {
border-radius: 72% 28% 50% 50% / 55% 26% 74% 45%;
}
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
<div class="shape-container">
<div class="shape"/>
</div>
I am trying to animate background exchange using #keyframes. Background is radial gradient. Backgroud changes but it isn't animated.
#mydiv {
background: radial-gradient(circle at 90% 80%, #ff0000, #4d0019);
width: 100%;
height: 1246px;
position: relative;
overflow: hidden;
animation: background-gradient 5s;
animation-iteration-count: infinite;
backface-visibility: hidden;
animation-timing-function: ease-in-out;
}
#-webkit-keyframes background-gradient {
0% {background: radial-gradient(circle at 90% 80%, #ff0000, #4d0019);}
25% {background: radial-gradient(circle at 90% 80%, #993399, #4d0019);}
50% {background: radial-gradient(circle at 90% 80%, #3333cc, #4d0019);}
75% {background: radial-gradient(circle at 90% 80%, #00ffcc, #4d0019);}
100% {background: radial-gradient(circle at 90% 80%, #cc9900, #4d0019);}
}
#keyframes background-gradient {
0% {background: radial-gradient(circle at 90% 80%, #ff0000, #4d0019);}
25% {background: radial-gradient(circle at 90% 80%, #993399, #4d0019);}
50% {background: radial-gradient(circle at 90% 80%, #3333cc, #4d0019);}
75% {background: radial-gradient(circle at 90% 80%, #00ffcc, #4d0019);}
100% {background: radial-gradient(circle at 90% 80%, #cc9900, #4d0019);}
}
<div id="mydiv"></div>
I tried with just solid colors and it works fine (e.g. background: red, background: yellow...).
I tried background-image instead of just background on my gradients, it doesn't help.
Do you have any advice or know solution how to animate exhange, so it is not just rapid exhange of colors but gradual exchange from one to another.
Unfortunately, background gradients are not animatable
Luckily for you, your current desing doesn't need to animate the gradient, since the external color is constant.
Just make the gradient transparent, and set a solid changing color underneath
#mydiv {
width: 100%;
height: 600px;
position: relative;
overflow: hidden;
animation: background-gradient 5s;
animation-iteration-count: infinite;
backface-visibility: hidden;
animation-timing-function: ease-in-out;
background-image: radial-gradient(circle at 90% 80%, transparent, #4d0019);
}
#keyframes background-gradient {
0% {
background-color: #ff0000;
}
25% {
background-color: yellow;
}
50% {
background-color: #3333cc;
}
75% {
background-color: #00ffcc;
}
100% {
background-color: #cc9900;
}
}
<div id="mydiv"></div>
With this code ,the hover effect is working ,the bottom right corner disappears but there is no transition,it's something wrong?
.mydiv:hover{
background-color: blue;
clip-path: polygon(0% 0%, 100% 0%, 80% 100%, 0% 100%);
transition: 0.5s ease;
}
You need to add an initial clip-path definition to have a transition between two states:
.box {
background-color: blue;
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
transition: 0.5s ease;
height:150px;
}
.box:hover {
clip-path: polygon(0% 0%, 100% 0%, 80% 100%, 0% 100%);
}
<div class="box">
</div>
You can also do the same with background and you will have better support:
.box {
background:
linear-gradient(blue,blue) left,
linear-gradient(to bottom right,blue 49.5%,transparent 50%) right;
background-size:100% 100%,0% 100%;
background-repeat:no-repeat;
transition: 0.5s ease;
height:150px;
}
.box:hover {
background-size:80.1% 100%,20% 100%;
}
<div class="box">
</div>
Transition property need set to class if you want to use it for pseudo class
.mydiv {
background: red;
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
transition: all 0.5s ease;
}
.mydiv:hover {
background: blue;
clip-path: polygon(0% 0%, 100% 0%, 80% 100%, 0% 100%);
}
<div class="mydiv">
Hello world
</div>
At this link: [http://codepen.io/FelixKiunke/pen/nvDcj][1] you can see that this guy made a nice circle that finishing filling its edges up every 10 seconds. This is what I want to duplicate.
I have copied the compiled CSS as well as the HTML from this page and put it in some local files. When I open my page with this on it, Chrome tells me that the background CSS elements have invalid syntax and so the circle does not show up at all.
Why is the syntax invalid in my copied code but not on the site?
/*
NOTE ABOUT THE FORK:
This demonstrates the use of radial gradients on the Pie Spinner by HugoGiraudel (http://codepen.io/HugoGiraudel/pen/BHEwo).
Most of the code is unchanged, too make my changes clear I have removed the previous comments.
I added radial gradients (see the color change on hover) and a demonstration for the responsive size (click), and a little "Click me" pseudo element.
*/
* {
box-sizing: border-box;
}
.wrapper {
width: 250px;
height: 250px;
margin: 10px auto;
position: relative;
background: white;
/*The bigger size at click:*/
transition: width 0.5s, height 0.5s;
}
.wrapper.big {
width: 400px;
height: 400px;
}
.pie {
width: 50%;
height: 100%;
transform-origin: 100% 50%;
position: absolute;
/*
Here comes the radial gradient.
Note that it has to have the alignment "left center" for the .filler,
and "right center" for the .spinner!
*/
/*CHROME SAYS THE NEXT LINE IS INVALID*/
background: radial-gradient(left center, circle, #00ccff 0px, #000088 100%);
/* The borders mustn't be transparent, that looks really ugly! */
border: 20px solid #024;
}
.spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 200;
/*CHROME SAYS THE NEXT LINE IS INVALID*/
background: radial-gradient(right center, circle, #00ccff 0px, #000088 100%);
border-right: none;
animation: rota 10s linear infinite;
}
.spinner::after {
position: absolute;
height: 20px;
top: 0px;
right: 0px;
content: "Click me!";
transform: rotate(270deg);
transform-origin: 100% 100%;
color: white;
font: 16px/20px sans-serif;
}
.wrapper:hover .pie {
border-color: #620;
}
.wrapper:hover .filler {
/*CHROME SAYS THE NEXT LINE IS INVALID*/
background: radial-gradient(left center, circle, #ffbb11 0px, #dd6600 100%);
}
.wrapper:hover .spinner {
background: radial-gradient(right center, circle, #ffbb11 0px, #dd6600 100%);
}
.filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
opacity: 0;
z-index: 100;
animation: fill 10s steps(1, end) infinite;
border-left: none;
}
.mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 300;
animation: mask 10s steps(1, end) infinite;
}
#keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
<div class="wrapper">
<div class="pie spinner"></div>
<div class="pie filler"></div>
<div class="mask"></div>
</div>
Update
Here is the updated (and working) CSS:
/Spinner/
/*
NOTE ABOUT THE FORK:
This demonstrates the use of radial gradients on the Pie Spinner by HugoGiraudel (http://codepen.io/HugoGiraudel/pen/BHEwo).
Most of the code is unchanged, too make my changes clear I have removed the previous comments.
I added radial gradients (see the color change on hover) and a demonstration for the responsive size (click), and a little "Click me" pseudo element.
*/
* {
box-sizing: border-box;
}
.wrapper {
width: 250px;
height: 250px;
margin: 10px auto;
position: relative;
background: white;
/*The bigger size at click:*/
transition: width 0.5s, height 0.5s;
}
.wrapper.big {
width: 400px;
height: 400px;
}
.pie {
width: 50%;
height: 100%;
transform-origin: 100% 50%;
position: absolute;
/*
Here comes the radial gradient.
Note that it has to have the alignment "left center" for the .filler,
and "right center" for the .spinner!
*/
background: -webkit-gradient(circle at left center, #00ccff 0px, #000088 100%);
background: -webkit-linear-gradient(circle at left center, #00ccff 0px, #000088 100%);
background: -moz-linear-gradient(circle at left center, #00ccff 0px, #000088 100%);
background: -ms-linear-gradient(circle at left center, #00ccff 0px, #000088 100%);
background: -o-linear-gradient(circle at left center, #00ccff 0px, #000088 100%);
background: radial-gradient(circle at left center, #00ccff 0px, #000088 100%);
/* The borders mustn't be transparent, that looks really ugly! */
border: 20px solid #024;
}
.spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 200;
background: -webkit-gradient(circle at right center, #00ccff 0px, #000088 100%);
background: -webkit-linear-gradient(circle at right center, #00ccff 0px, #000088 100%);
background: -moz-linear-gradient(circle at right center, #00ccff 0px, #000088 100%);
background: -ms-linear-gradient(circle at right center, #00ccff 0px, #000088 100%);
background: -o-linear-gradient(circle at right center, #00ccff 0px, #000088 100%);
background: radial-gradient(circle at right center, #00ccff 0px, #000088 100%);
border-right: none;
-webkit-animation: rota 10s linear infinite;
-moz-animation: rota 10s linear infinite;
-o-animation: rota 10s linear infinite;
animation: rota 10s linear infinite;
}
.spinner::after {
position: absolute;
height: 20px;
top: 0px;
right: 0px;
content: "Click me!";
transform: rotate(270deg);
transform-origin: 100% 100%;
color: white;
font: 16px/20px sans-serif;
}
.wrapper:hover .pie {
border-color: #620;
}
.wrapper:hover .filler {
background: -webkit-gradient(circle at left center, #ffbb11 0px, #dd6600 100%);
background: -webkit-linear-gradient(circle at left center, #ffbb11 0px, #dd6600 100%);
background: -moz-linear-gradient(circle at left center, #ffbb11 0px, #dd6600 100%);
background: -ms-linear-gradient(circle at left center, #ffbb11 0px, #dd6600 100%);
background: -o-linear-gradient(circle at left center, #ffbb11 0px, #dd6600 100%);
background: radial-gradient(circle at left center, #ffbb11 0px, #dd6600 100%);
}
.wrapper:hover .spinner {
background: -webkit-gradient(circle at right center, #ffbb11 0px, #dd6600 100%);
background: -webkit-linear-gradient(circle at right center, #ffbb11 0px, #dd6600 100%);
background: -moz-linear-gradient(circle at right center, #ffbb11 0px, #dd6600 100%);
background: -ms-linear-gradient(circle at right center, #ffbb11 0px, #dd6600 100%);
background: -o-linear-gradient(circle at right center, #ffbb11 0px, #dd6600 100%);
background: radial-gradient(circle at right center, #ffbb11 0px, #dd6600 100%);
}
.filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
opacity: 0;
z-index: 100;
-webkit-animation: fill 10s steps(1, end) infinite;
-moz-animation: fill 10s steps(1, end) infinite;
-o-animation: fill 10s steps(1, end) infinite;
animation: fill 10s steps(1, end) infinite;
border-left: none;
}
.mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 300;
-webkit-animation: mask 10s steps(1, end) infinite;
-moz-animation: mask 10s steps(1, end) infinite;
-o-animation: mask 10s steps(1, end) infinite;
animation: mask 10s steps(1, end) infinite;
}
#-webkit-keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#-moz-keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#-o-keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#-webkit-keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#-moz-keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#-o-keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#-webkit-keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
#-moz-keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
#-o-keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
#keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
[1]: http://codepen.io/FelixKiunke/pen/nvDcj
The syntax indeed is incorrect. It should be radial-gradient(circle at right center, #ffbb11 0px, #dd6600 100%). This is also incorrect in the CodePen, and once you fix it, the animation looks different (it has a 'Click here' call-to-action when you hover it). It is not the core issue, though.
The reason why the animation doesn't work at all in your version, is because the animation properties need a -webkit- prefix in Chrome.
In the CodePen, -prefix-free is used, which is why it works. It is a library that automatically adds the prefixed version of the CSS properties.
CodePen can also use Autoprefixer (another such library) or neither. Once you select 'neither', you'll see that the CodePen example also doesn't work anymore, because the (S)CSS doesn't contain the required prefixed version for the CSS attributes.
So, the solution: either use a library too, or add the required prefixed attributes for Chrome (and maybe other browsers too).