Can animation and gradients work together? - css

I put some gradients in an animation but it didn't work, why? (blah blah blah, to be able to post this question)
EDIT:
CSS
#keyframes sample {
0% {background: -moz-linear-gradient(#000,#fff)}
100% {background: -moz-linear-gradient(#fff,#000)}
}
button {
animation: sample 1s;
-moz-animation: sample 1s;
}

Only answering because the duplicate examples seemed rubbish since they don't even offer a potential workaround, and I like helping people learn. So, for you to tinker...and even added a little pizazz for flavor...
CODEPEN
Keep in mind you're not animating your gradient, you're animating movement to give the illusion of animated gradients.
and some html/css...
#-webkit-keyframes vertigoBG {
0%, 100% {
background-position: 0 0; }
50% {
background-position: 100% 0; } }
#keyframes vertigoBG {
0%, 100% {
background-position: 0 0; }
50% {
background-position: 100% 0; } }
#magic {
background: linear-gradient(to right, #fefefe, #ED1C24, #ED1C24, #f60, #f60, #ff0, #ff0, #0c4, #0c4, #09c, #09c, #00c, #00c, #909, #909, #ED1C24, #ED1C24, #fefefe);
background-size: 1000% 100%;
background-position: 0 0;
-webkit-animation: vertigoBG 100s linear infinite;
animation: vertigoBG 20s linear infinite;
position: absolute;
top: 0;
width: 100%;
height: 170px;
-webkit-transform: skewY(-2deg);
-ms-transform: skewY(5deg);
transform: skewY(5deg);
margin-top: -85px;
z-index: -1;
}
<div id="magic"></div>
Enjoy!

Related

Vertical skeleton loader not working from bottom to top animation

I'm using both vertical and horizontal skeleton loader in a react component, please refer to this codepen - https://codepen.io/phutschi/pen/jejzbK for reference, I want to like this for vertical loader from bottom to top.
Loader.js
import './loader.scss'
function Loader() {
return (
<div className="animated-background">
<div className="background-masker content-first-line"></div>
<div className="background-masker content-second-line"></div>
<div className="background-masker content-third-line"></div>
<div className="background-masker vertical-line"></div>
</div>
)
}
export default Loader
loader.scss
#keyframes placeHolderLoader {
0% {
background-position: -468px 0;
}
100% {
background-position: 468px 0;
}
}
#keyframes verticalPlaceHolderLoader {
0% {
background-position: bottom ;
}
100% {
background-position: top;
}
}
.animated-background {
// height: 120px;
// position: relative;
.background-masker{
height: 14px;
border-radius: 7px;
width: 80%;
margin-bottom: 2px;
animation-duration: 1.3s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderLoader;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 100%;
&.vertical-line{
width: 50px;
height: 140px;
animation-duration: 1.3s;
background: linear-gradient(to bottom, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
animation-name: verticalPlaceHolderLoader;
}
}
}
u can see, that I'm using separate gradient and animation for vertical lines, but the animation is not working for vertical lines, the animation should work from bottom to top.
Change the vertical animation keyframe to the following and it should work:
#keyframes verticalPlaceHolderLoader {
0% {
background-position: 0 70px;
}
100% {
background-position: 0 -70px;
}
}
See demo

Blur filter not working as intended (blur filter does not update to match gradient animation)

I am trying to create a text with a blurred background so it looks like the text has an aura. So far the code I have is
.testRainbow {
position:fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
z-index: 9999;
}
.testRainbow::before {
content:'';
position:fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height:100%;
background: linear-gradient(90deg, #03a9f4, #f441a4, #ffeb3b, #03a9f4);
background-size: 400%;
-moz-animation: slideRainbow 8s linear infinite;
-webkit-animation: slideRainbow 8s linear infinite;
animation: slideRainbow 8s linear infinite;
-moz-filter: blur(1em);
-webkit-filter: blur(1em);
filter: blur(1em);
z-index: -1;
}
#keyframes slideRainbow {
0% {
background-position: 0%;
}
100% {
background-position: 400%;
}
}
#-webkit-keyframes slideRainbow {
0% {
background-position: 0%;
}
100% {
background-position: 400%;
}
}
#-moz-keyframes slideRainbow {
0% {
background-position: 0%;
}
100% {
background-position: 400%;
}
}
<h1 class='testRainbow'>test</h1>
I tested it and it works on Chrome, but it does not work on Safari. Further, I checked that it does not work on mobile Chrome, which is interesting because it works when I open Chrome from my desktop.
The linear gradient is changing as it is supposed to for all browsers, but for the ones that don't work, it seems the blur is not being updated. I checked that while I resize or zoom in, the blur updates to the current gradient. What needs to be changed? Thanks in advance.
EDIT
I fixed the problem, and ran into another problem. I added the filter: blur inside the keyframes as follows:
#keyframes slideRainbow (
0% {
background-position: 0%;
filter: blur(1em);
}
100% {
background-position: 0%;
filter: blur(1em);
}
}
I only have the rainbow gradient here, but there are 3 more colors in the css, and which color is shown is randomized. When the same color is selected twice or more in a row, the animation stops and I have a solid gradient behind the text. When another color is selected, the animation kicks back in.
It is supposed to look like this:
But being selected twice in a row, it becomes like this:

CPU Usage high for my CSS Animation. Can I use the GPU to lessen the burden?

I made the following Animation to play while the page is loading.
HTML
<div class="skeleton"></div>
CSS
#keyframes shimmerBackground {
0% { background-position: -468px 0 }
100% { background-position: 468px 0 }
}
.skeleton:empty{
width: 500px;
height: 40px;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
background: no-repeat #e4e3e3;
background-image: linear-gradient(to right, #e4e3e3 0, #c7c6c6 20%, #e4e3e3 40%, #e4e3e3 100%);
animation: shimmerBackground 1s linear infinite;
}
Here it is in action: https://jsfiddle.net/NuccioJohn/fx1wr8e6/
The animation correctly stops itself after the element is loaded with the data. But the hit to the CPU from Painting and Rendering is absolutely absurd.
I have been able to use other methods to lower the CPU usage significantly, but these methods do not work in IE 11 and having it work in IE is a must.
My instinct is that I should be able to use the GPU to do this animation, and that will lessen the burden this animation has on the GPU.
transform: translateZ(0);
Does anyone know how to rewrite this in a more efficient manner?
Maybe something like this will work? Instead of directly animating the background image, which requires a repaint for each frame, try using transform: translate3d() on a pseudo element. The included z-axis in translate3d() will force GPU rendering too!
#keyframes shimmerBackground {
0% { transform: translate3d(-400px, 0, 0) }
100% { transform: translate3d(900px, 0, 0) }
}
.skeleton:empty{
width: 500px;
height: 40px;
position: relative;
overflow: hidden;
background-color: #e4e3e3;
}
.skeleton:empty::before {
content: "";
display: block;
width: 400px;
height: 100%;
position: absolute;
left: 0;
top: 0;
background: no-repeat #e4e3e3;
background-image: linear-gradient(to right, #e4e3e3 0, #c7c6c6 20%, #e4e3e3 40%, #e4e3e3 100%);
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation: shimmerBackground 1s linear infinite;
}

How to play specific keyframes with css animation

I want to play keyframes 1, 2, 3, 2, 1 with css animation:
This doesn't work:
#keyframes play-specific {
0% {
background-position: 0px;
}
25% {
background-position: -50px;
}
50% {
background-position: -100px;
}
75% {
background-position: -50px;
}
100% {
background-position: -0px;
}
}
with animation:
.hi {
width: 50px;
height: 72px;
background-image: url("http://s.cdpn.io/79/sprite-steps.png");
animation: play-specific 1s steps(4) infinite;
}
see http://jsfiddle.net/CGmCe/12960/
steps() will break animation from a keyframes to another. it can be used to avoid to set each keyframes.
When keyframes are set , 1 will mean jump from a keyframe to another without transition.
.hi {
width: 50px;
height: 72px;
background-image: url("http://s.cdpn.io/79/sprite-steps.png");
animation: play-specific 1s steps(1) infinite;
}
.ho {
width: 50px;
height: 72px;
background-image: url("http://s.cdpn.io/79/sprite-steps.png");
animation: play 1s steps(10) infinite;
}
#keyframes play-specific {/* steps() will be applied in between each keyframes, 1 is to jump from a keyframe to another without transition */
0% {
background-position: 0px;
}
25% {
background-position: -50px;
}
50% {
background-position: -100px;
}
75% {
background-position: -50px;
}
100% {
background-position: -0px;
}
}
#keyframes play {/* steps here need to be adapted in order to break the linearity of animation */
from { background-position: 0px; }
to { background-position: -500px; }
}
<div class="hi"></div>
<div class="ho"></div>
see on W3C
For a keyframed animation, the 'animation-timing-function' applies between keyframes, not over the entire animation. For example, in the case of an ease-in-out timing function, an animation will ease in at the start of the keyframe and ease out at the end of the keyframe. A 'animation-timing-function' defined within a keyframe block applies to that keyframe, otherwise the timing function specified for the animation is used.

2 Background images with separate animations?

This is bugging me, because I know that this is possible, I just don't really know how to write it properly. Here's an image of my vision:
So far in my css, I've implemented the cloud animation
#home{
margin: 0;
padding-top: 327px;
height: 57.78vh;
background: #6bbfff url('../images/clouds.png') repeat-x fixed 50% 10%;
text-align: center;
-webkit-animation: cloudmove 180s infinite linear;
animation: cloudmove 180s infinite linear;
}
#keyframes cloudmove{
0% { background-position: 0% 10%; }
100% { background-position: 100% 10%; }
}
#-webkit-keyframes cloudmove{
0% { background-position: 0% 10%; }
100% { background-position: 500% 10%; }
}
I've been trying to add the landscape illustration in the image shown above as background image number 2, but I'm having trouble. How do I get the css animation to not apply to it?
Thanks!
You do it like this:
Fiddle
Your pertinent CSS relies on some new features of backgrounds in CSS3.
Layered background images
You can instantiate these like so:
.my-rule {
background-image: url(image1.png), url(image2.png);
background-position: 0 0, 50% 50%;
}
It's pretty simple! You just need to separate all rules for each respective background image with commas. That goes straight down to your animations as well, like so:
#keyframes cloudmove{
0% { background-position: 0% 10%, 0% 0%; }
100% { background-position: 100% 10%, 100% 0%; }
}
#-webkit-keyframes cloudmove{
0% { background-position: 0% 10%, 0% 0%; }
100% { background-position: 500% 10%, 100% 0%; }
}
Hope that helps!

Resources