Vertical skeleton loader not working from bottom to top animation - css

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

Related

CSS: repeated animated background

I'm trying to create a repeated background existing out of two parts. Each part is a gradient and while the one moves up, the other moves down.
The best I got is this:
html {
background: black;
color: #4c4c4c;
}
body {
margin: 30vh auto;
max-width: 80vw;
}
.wave {
background: none;
height: 1rem;
width: 50%;
position: absolute;
z-index: 2;
animation: move 700ms 0ms steps(2) infinite both;
}
.color::after,
.color::before {
content: "";
position: absolute;
left: 0;
right: 0;
height: 100%;
top: 0;
}
.color {
background-image: linear-gradient(#fe0000 50%, #6531ff 0 100%);
}
.color::after {
background: linear-gradient(to bottom, #f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%), linear-gradient(to right, #042a2b 3rem, transparent 3rem, transparent 6rem);
}
.wave,
.color::after,
.color::before {
background-size: 5rem 1rem;
background-repeat: repeat-x;
}
#keyframes move {
0% {
margin-top: -3rem;
}
100% {
margin-top: -3.25rem;
}
}
<div class="color wave"></div>
I get why this doesn't work, but not sure how to proceed.
Since it is difficult to describe, here is an image of what I'm looking for:
At first (position 1), all odd blocks are higher than the even blocks. After the first animation, it's the other way around (position 2) and so on.
Maybe like below:
.box {
height:100px;
background:linear-gradient(red,blue,yellow,red) 0 0/100% 200%;
animation:y 2s linear infinite;
}
.box::after {
content:"";
display:block;
height:100%;
background:linear-gradient(green,lightblue,pink,green) 0 0/100% 200%;
animation:inherit;
animation-direction: reverse;
-webkit-mask:linear-gradient(90deg,#fff 50%,transparent 0) 0 0/20% 100%;
}
#keyframes y {
to {
background-position:0 -200%;
}
}
<div class="box"></div>
UPDATE: This is an interesting problem. I'm surprised to find that I don't have an obvious or particularly elegant solution to having a gradient running vertically while repeating with horizontal gaps.
Far more elusive than I initially expected.
Best I could come up with is to put one of the gradients in a pseudo element and apply a mask-image. This won't work in IE, but it appears to be supported everywhere else.
See updated demo below.
If I understand what you're trying to do, I think you could accomplish it by animating the background positions:
.demo {
height: 200px;
background-image:
linear-gradient(#f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%);
animation: move 0.7s infinite alternate;
background-size: 3rem;
position: relative;
}
.demo::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(#042a2b, transparent);
/* This is the magic part: using a horizontal repeating-linear-gradient
to mask out "columns", allowing the container's background gradient to
show through */
-webkit-mask-image: repeating-linear-gradient(to right, black 0 3rem, transparent 3rem 6rem);
background-size: 3rem;
/* run the same animation in reverse to animate up instead of down */
animation: move 0.7s infinite alternate-reverse;
}
#keyframes move {
from {
background-position: 0 0;
}
to {
background-position:
0 200px;
}
}
<div class="demo"></div>
It's difficult to infer exactly what you're trying to do, but here's another sample (very similar to #ray hatfield's answer) that will move the first background down while the second background moves up:
.sample {
width: 250px;
height: 50px;
position: relative;
background-image: linear-gradient(to bottom, #f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%), linear-gradient(to right, #042a2b 3rem, transparent 3rem, transparent 6rem);
animation: move 1s infinite linear;
}
#keyframes move {
0%, 100% {
background-position: 0 -75px, 0 0;
}
50% {
background-position: 0 0, 0 -75px;
}
}
<div class="sample"></div>

Animation changing a HSL variable isn't working

I'm trying to create a rainbow animation with CSS variables and HSL. I've got the following code, however in Chrome it just snaps between both states.
#keyframes rainbow {
from {
--accent-bright: hsl(0,87%,48%);
--accent-dark: hsl(0,94%,48%);
--accent-verydark: hsl(0,88%,33%);
}
to {
--accent-bright: hsl(359,87%,48%);
--accent-dark: hsl(359,94%,48%);
--accent-verydark: hsl(359,88%,33%);
}
}
.rainbow, .rainbow *, .rainbow > * {
animation-name: rainbow;
animation-duration: 3.6s;
animation-iteration-count: infinite;
}
[...]
#topBar {
height: 56px;
width:100vw;
position:fixed;
top:0;
background-image: linear-gradient(to right, var(--accent-bright),var(--accent-dark));
color: var(--text-onaccent);
}
If I change the hue in one of the keyframes to someething more noticible, you can see the gradient flipping.
The property background-image is not animatable
However... opacity is animatable.
This means that you can create an ::after pseudo-element, exactly overlapping your original element and animate the pseudo-element's opacity so that it fades into view.
Remember to apply pointer-events: none to the pseudo-element, so that, as far as interactivity goes, the pseudo-element remains entirely insubstantial.
Working Example:
N.B. I have introduced yellow to make the animation more visible.
.rainbow {
--accent-bright: hsl(0, 87%, 48%);
--accent-dark: hsl(0, 94%, 48%);
--accent-verydark: hsl(0, 88%, 33%);
position: relative;
width: 100px;
height: 100px;
background-image: linear-gradient(to right, var(--accent-bright), var(--accent-dark));
color: var(--text-onaccent);
}
.rainbow::after {
--accent-bright: hsl(359, 87%, 48%);
--accent-dark: yellow;
--accent-verydark: hsl(359, 88%, 33%);
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(to right, var(--accent-bright), var(--accent-dark));
pointer-events: none;
animation: rainbow 3.6s infinite;
}
#keyframes rainbow {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="rainbow"></div>

How to use the linear gradient and keyframes such that the animation is smooth using css? [duplicate]

I want to create a shine loading animation which will appear on multiple elements with different background colors.
Currently, I'm using background-image gradient and I'm animating the background-position using vw units, but it's not scalable, my elements will have different lengths.
Is there a way I can animate background-image with percentage units?
The animation created
body {
background: black;
}
header {
width: 100%;
height: 50px;
background-color: rebeccapurple;
background-image: linear-gradient(
to right,
transparent 0%,
rgba(255,255,255,0.3) 50%,
transparent 100%
);
background-repeat: no-repeat;
background-position: -100vw;
animation: shine 2s infinite;
}
#keyframes shine {
0% {
background-position: -100vw;
}
100% {
background-position: 100vw;
}
}
<header></header>
An idea is to make the size of the gradient to be 3 times bigger than the container and color the middle part of it then you slide it from left to right:
body {
background: black;
}
.box {
height: 50px;
margin:5px;
background:
linear-gradient(90deg,#0000 33%,rgba(255,255,255,0.3) 50%,#0000 66%)
rebeccapurple;
background-size:300% 100%;
animation: shine 2s infinite;
}
#keyframes shine {
0% {
background-position: right;
}
/*100% {
background-position: left; it's the default value, no need to define it
}*/
}
<div class="box"></div>
<div class="box" style="width:60%"></div>
<div class="box" style="width:40%"></div>
Another alternative for a different animation:
body {
background: black;
}
.box {
height: 50px;
margin:5px;
background:
repeating-linear-gradient(90deg,#0000 0,rgba(255,255,255,0.3) 25%,#0000 50%)
rebeccapurple;
background-size:200% 100%;
animation: shine 1s infinite linear;
}
#keyframes shine {
0% {
background-position: right;
}
}
<div class="box"></div>
<div class="box" style="width:60%"></div>
<div class="box" style="width:40%"></div>
Related question: Using percentage values with background-position on a linear-gradient

Why css animation doesn't work with background size 100%

I'm working with css animation with steps...my problem is:
when step() == (frame length -1) everything is fluid exept that I can't see the last frame
when step() == frame length I can't still see the last frame and animation is messy...
I'm looking for a way to use background 100% (or at least an explanation of why it doesn't work), for I can use it with sprites with differents number of frames and just use step() to adjust to the actual sprite..
Demo:
#sprite1, #sprite2, #sprite3 {
height: 41px;
width: 41px;
background: url('https://img4.hostingpics.net/thumbs/mini_756487pacanim2.png') 0 center;
}
#sprite1 {
animation: sprite 1s steps(3) infinite;
}
#sprite2 {
animation: sprite 1s steps(4) infinite;
}
#sprite3 {
animation: sprite2 1s steps(4) infinite;
}
#keyframes sprite {
100% { background-position: right center; }
}
#keyframes sprite2 {
100% { background-position: 164px center; }
}
Case1: <br>
<div id="sprite1"></div>
Case2:
<div id="sprite2"></div>
What it should be:
<div id="sprite3"></div>
Required. Percentage of the animation duration.
Legal values:
0-100%
from (same as 0%)
to (same as 100%)
Note: You can have many keyframes-selectors in one animation.
sprit image 4 one start on 50% so i gave. check below sample code.
#sprite1, #sprite2, #sprite3 {
height: 41px;
width: 41px;
background: url('https://img4.hostingpics.net/thumbs/mini_756487pacanim2.png') 0 center;
}
#sprite1 {
animation: sprite 1s steps(3) infinite;
}
#sprite2 {
animation: sprite3 1s steps(3) infinite;
}
#sprite3 {
animation: sprite2 1s steps(4) infinite;
}
#keyframes sprite {
60% { background-position: right center; }
}
#keyframes sprite2 {
100% { background-position: 164px center; }
}
#keyframes sprite3 {
50% { background-position: right center; }
}
Case1: <br>
<div id="sprite1"></div>
Case2:
<div id="sprite2"></div>
What it should be:
<div id="sprite3"></div>
You need to change the initial position to be background-position:-33% center; instead of background-position: 0 center;
in this case the four steps will work like this:
step1: background-position: -33% center; which will display img4
step2: background-position: 0% center; which will display img1
step3: background-position: 33% center;which will display img2
step4: background-position: 66% center;which will display img3
#sprite1 {
height: 41px;
width: 41px;
background: url('https://img4.hostingpics.net/thumbs/mini_756487pacanim2.png') -33% center;
}
#sprite1 {
animation: sprite 1s steps(4) infinite;
}
#keyframes sprite {
100% { background-position: right center; }
}
<div id="sprite1"></div>
Try this:
10 = frames/steps;
For Edge you have to calculate the percentage;
#keyframes sprite{
100%{
background-position: calc(100% / (10 - 1) * 10) 0;
background-position: 111.111% 0;/* Edge/IE */
}
}
#container {
width: 50px;
height: 72px;
animation: container 1s linear infinite;
}
#keyframes container {
50% {
width: 72px;
height: 50px;
}
}
#sprite {
width: 100%;
height: 100%;
background-color: red;
background-image: url(http://i.imgur.com/xtk0SCC.png);
background-position: 0% 0;
background-size: calc(100% * 10) 100%;
background-repeat: no-repeat;
animation: sprite 1s steps(10) infinite;
}
#keyframes sprite {
100% {
background-position: calc(100% / (10 - 1) * 10) 0;
background-position: 111.111% 0;/* Edge/IE */
}
}
<div id="container">
<div id="sprite"></div>
</div>

Can animation and gradients work together?

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!

Resources