It\'s been a while since I asked a question here. So excuse me if I do anything wrong.
I have an issue with CSS animation. I would like my animation
A similar problem has already been described on SO: How to have the object not revert to its initial position after animation has run? The problem is that at the beginning of the animation, the object returns to its original state. But I solved the problem differently: I simply combined both animations into one, and now both reversals are described by one function. If you definitely need both animations, then redo it, as stated in the question I've given link to. Here is my code:
#loader {
width: 240px;
height: 100px;
}
.inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 2s;
transform-style: preserve-3d;
background-color: transparent;
}
.front,
.back {
position: absolute;
width: 80px;
height: 50px;
backface-visibility: hidden;
}
#loader1 {
float: left;
width: 80px;
height: 50px;
perspective: 1000px;
background-color: transparent;
}
#loader1 .inner {
animation: spin 20s ease 0s infinite;
-webkit-animation: spin 20s ease 0s infinite;
}
#loader1 .front {
background-color: #db9834;
}
#loader1 .back {
background-color: #3498db;
transform: rotateY(180deg);
}
/* -------------------------------------------------------- */
#loader2 {
float: left;
width: 80px;
height: 50px;
perspective: 1000px;
background-color: transparent;
}
#loader2 .inner {
animation: spin 20s ease 1s infinite;
-webkit-animation: spin 20s ease 1s infinite;
}
#loader2 .front {
background-color: #db8834;
}
#loader2 .back {
background-color: #3488db;
transform: rotateY(180deg);
}
/* -------------------------------------------------------- */
#loader3 {
float: left;
width: 80px;
height: 50px;
perspective: 1000px;
background-color: transparent;
}
#loader3 .inner {
animation: spin 20s ease 2s infinite;
-webkit-animation: spin 20s ease 2s infinite;
}
#loader3 .front {
background-color: #db7834;
}
#loader3 .back {
background-color: #3478db;
transform: rotateY(180deg);
}
/* -------------------------------------------------------- */
#loader4 {
float: left;
width: 80px;
height: 50px;
perspective: 1000px;
background-color: transparent;
}
#loader4 .inner {
animation: spin 20s ease 3s infinite;
-webkit-animation: spin 20s ease 3s infinite;
}
#loader4 .front {
background-color: #db6834;
}
#loader4 .back {
background-color: #3468db;
transform: rotateY(180deg);
}
/* -------------------------------------------------------- */
#loader5 {
float: left;
width: 80px;
height: 50px;
perspective: 1000px;
background-color: transparent;
}
#loader5 .inner{
animation: spin 20s ease 4s infinite;
-webkit-animation: spin 20s ease 4s infinite;
}
#loader5 .front {
background-color: #db5834;
}
#loader5 .back {
background-color: #3458db;
transform: rotateY(180deg);
}
/* -------------------------------------------------------- */
#loader6 {
float: left;
width: 80px;
height: 50px;
perspective: 1000px;
background-color: transparent;
}
#loader6 .inner {
animation: spin 20s ease 5s infinite;
-webkit-animation: spin 20s ease 5s infinite;
}
#loader6 .front {
background-color: #db4834;
}
#loader6 .back {
background-color: #3448db;
transform: rotateY(180deg);
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotateY(0deg);
}
8% {
-webkit-transform: rotateY(180deg);
}
50% {
-webkit-transform: rotateY(180deg);
}
58% {
-webkit-transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(0deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotateY(0deg);
}
8% {
-webkit-transform: rotateY(180deg);
}
50% {
-webkit-transform: rotateY(180deg);
}
58% {
-webkit-transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(0deg);
}
}
<div id="loader">
<div id="loader1">
<div class="inner">
<div class="front">
</div>
<div class="back"> </div>
</div>
</div>
<div id="loader2">
<div class="inner">
<div class="front"> </div>
<div class="back"> </div>
</div>
</div>
<div id="loader3">
<div class="inner">
<div class="front"> </div>
<div class="back"> </div>
</div>
</div>
<div id="loader4">
<div class="inner">
<div class="front"> </div>
<div class="back"> </div>
</div>
</div>
<div id="loader5">
<div class="inner">
<div class="front"> </div>
<div class="back"> </div>
</div>
</div>
<div id="loader6">
<div class="inner">
<div class="front"> </div>
<div class="back"> </div>
</div>
</div>
</div>
First I would simplify your code and use less HTML/CSS. Then I would consider only one animation where I will have both states.
The animation will be: the first flip then we keep the first color then the second filp then we keep the second color. It's divided into 12
time slots (1 + 5 + 1 + 5
) (1+5 = 6
which is the number of the divs)
If the duration is S
then the delay should be multiple of one slot S/12
. Notice that I have used the perspective within the transform to avoid an extra element:
#loader {
width: 240px;
height: 100px;
display: flex;
flex-wrap: wrap;
}
#loader>div {
width: calc(100%/3);
position: relative;
transform-style: preserve-3d;
animation: spin 6s linear var(--delay, 0s) infinite;
}
#loader>div:before,
#loader>div:after {
content: "";
position: absolute;
top:0;
left:0;
width: 100%;
height: 100%;
backface-visibility: hidden;
background-color: var(--front, #db9834);
}
#loader>div:after {
background-color: var(--back, #3498db);
transform: rotateY(180deg);
}
/* -------------------------------------------------------- */
#loader>div:nth-child(2) {
--front: #db8834;
--back: #3488db;
--delay: 0.5s;
}
#loader>div:nth-child(3) {
--front: #db7834;
--back: #3478db;
--delay: 1s;
}
#loader>div:nth-child(4) {
--front: #db6834;
--back: #3468db;
--delay: 1.5s;
}
#loader>div:nth-child(5) {
--front: #db5834;
--back: #3458db;
--delay: 2s;
}
#loader>div:nth-child(6) {
--front: #db4834;
--back: #3448db;
--delay: 2.5s;
}
@keyframes spin {
0% {
transform:perspective(500px) rotateY(0deg);
}
8.33%,
50%{
transform:perspective(500px) rotateY(180deg);
}
58.33% {
transform:perspective(500px) rotateY(0deg);
}
}
<div id="loader">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Related questions for more details about the difference between perspective
and perspective()
CSS 3d transform doesn't work if perspective is set in the end of property
perspective and translateZ moves diagonally
We can simplify more if we change the div coloration while rotating instead of having two elements. The change should be made at half the slot where we do the flip (first and sixth) without any transition to create the illusion:
#loader {
width: 240px;
height: 100px;
display: flex;
flex-wrap: wrap;
}
#loader>div {
width: calc(100%/3);
animation:
spin 6s linear var(--delay, 0s) infinite,
colors 6s linear var(--delay, 0s) infinite;
background-color: var(--front, #db9834);
}
/* -------------------------------------------------------- */
#loader>div:nth-child(2) {
--front: #db8834;
--back: #3488db;
--delay: 0.5s;
}
#loader>div:nth-child(3) {
--front: #db7834;
--back: #3478db;
--delay: 1s;
}
#loader>div:nth-child(4) {
--front: #db6834;
--back: #3468db;
--delay: 1.5s;
}
#loader>div:nth-child(5) {
--front: #db5834;
--back: #3458db;
--delay: 2s;
}
#loader>div:nth-child(6) {
--front: #db4834;
--back: #3448db;
--delay: 2.5s;
}
@keyframes spin {
0% {
transform:perspective(500px) rotateY(0deg);
}
8.33%,
50%{
transform:perspective(500px) rotateY(180deg);
}
58.33% {
transform:perspective(500px) rotateY(0deg);
}
}
@keyframes colors {
0%,4.15% {
background-color: var(--front, #db9834);
}
4.16% {
background-color: var(--back, #3498db);
}
54.15% {
background-color: var(--back, #3498db);
}
54.16% {
background-color: var(--front, #db9834);
}
}
<div id="loader">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Another simplification can be done using filter considering the fact that you want to have the same shades of colors:
#loader {
width: 240px;
height: 100px;
display: flex;
flex-wrap: wrap;
}
#loader>div {
width: calc(100%/3);
animation:
spin 6s linear var(--delay, 0s) infinite,
colors 6s linear var(--delay, 0s) infinite;
background:
linear-gradient(#db9834 50%, #3498db 0);
background-size: 100% 200%;
}
/* -------------------------------------------------------- */
#loader>div:nth-child(2) {
filter: brightness(0.9);
--delay: 0.5s;
}
#loader>div:nth-child(3) {
filter: brightness(0.8);
--delay: 1s;
}
#loader>div:nth-child(4) {
filter: brightness(0.7);
--delay: 1.5s;
}
#loader>div:nth-child(5) {
filter: brightness(0.6);
--delay: 2s;
}
#loader>div:nth-child(6) {
filter: brightness(0.5);
--delay: 2.5s;
}
@keyframes spin {
0% {
transform:perspective(500px) rotateY(0deg);
}
8.33%,
50%{
transform:perspective(500px) rotateY(180deg);
}
58.33% {
transform:perspective(500px) rotateY(0deg);
}
}
@keyframes colors {
4.15% {
background-position: top;
}
4.16%,
54.15% {
background-position:bottom;
}
54.16% {
background-position: top;
}
}
<div id="loader">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
This result is not exactly the same as I used a random filter but you can easily try another kind of filtration to get the needed result.