I'm building an animation for cards. I wonder how to have the same effect for the card animation however without animating the z-index
. The animation should use only transform
and opacity
properties.
I want to achieve the same effect(as demonstrated below) without using z-index
in the animation, because it will cause painting to occur.
*,
::before,
::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
position: relative;
}
.item {
padding: 8px;
background-color: blue;
color: white;
opacity: 0;
height: 30px;
width: 32px;
text-align: center;
position: absolute;
top: auto;
bottom: 0;
animation: AnimateCard 16s infinite
cubic-bezier(0.48, 0.18, 0.35, 1.01);
}
.item:nth-child(1) {
animation-delay: -9s;
}
.item:nth-child(2) {
animation-delay: -5s;
}
.item:nth-child(3) {
animation-delay: -1s;
}
.item:nth-child(4) {
animation-delay: 3s;
}
@keyframes AnimateCard {
0% {
transform: translateY(-72px);
z-index: 1;
opacity: 0;
}
26% {
transform: translateY(-72px);
z-index: 1;
opacity: 0.2;
}
34% {
transform: translateY(-36px);
z-index: 1;
opacity: 0.3;
}
51% {
transform: translateY(-36px);
z-index: 1;
opacity: 0.3;
}
58% {
transform: translateY(0);
opacity: 1;
}
74% {
transform: translateY(0);
opacity: 1;
}
100% {
transform: translateY(0);
opacity: 0;
}
}
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
CodePudding user response:
In order to achieve a more marked fading effect between 4 and 1, I've applied two changes:
- removed z-index from keyframes
- changed 100% keyframe with 83%, so that it will fade away before 100%.
Here's the full snippet:
*,
::before,
::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
position: relative;
}
.item {
padding: 8px;
background-color: blue;
color: white;
opacity: 0;
height: 30px;
width: 32px;
text-align: center;
position: absolute;
top: auto;
bottom: 0;
animation: AnimateCard 16s infinite
cubic-bezier(0.48, 0.18, 0.35, 1.01);
}
.item:nth-child(1) {
animation-delay: -9s;
}
.item:nth-child(2) {
animation-delay: -5s;
}
.item:nth-child(3) {
animation-delay: -1s;
}
.item:nth-child(4) {
animation-delay: 3s;
}
@keyframes AnimateCard {
0% {
transform: translateY(-72px);
opacity: 0;
}
26% {
transform: translateY(-72px);
opacity: 0.2;
}
34% {
transform: translateY(-36px);
opacity: 0.3;
}
51% {
transform: translateY(-36px);
opacity: 0.3;
}
58% {
transform: translateY(0);
opacity: 1;
}
74% {
transform: translateY(0);
opacity: 1;
}
83% {
transform: translateY(0);
opacity: 0;
}
}
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
CodePudding user response:
We can clip the bottom most rectangle to height 0 as top one collapse on it:
*,
::before,
::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
position: relative;
}
.item {
padding: 8px;
background-color: blue;
color: white;
opacity: 0;
height: 30px;
width: 32px;
text-align: center;
position: absolute;
top: auto;
bottom: 0;
animation: AnimateCard 16s infinite cubic-bezier(0.48, 0.18, 0.35, 1.01);
}
.item:nth-child(1) {
animation-delay: -9s;
}
.item:nth-child(2) {
animation-delay: -5s;
}
.item:nth-child(3) {
animation-delay: -1s;
}
.item:nth-child(4) {
animation-delay: 3s;
}
@keyframes AnimateCard {
0% {
transform: translateY(-72px);
opacity: 0;
}
26% {
transform: translateY(-72px);
opacity: 0.2;
}
34% {
transform: translateY(-36px);
opacity: 0.3;
}
51% {
transform: translateY(-36px);
opacity: 0.3;
}
58% {
transform: translateY(0);
opacity: 1;
}
74% {
transform: translateY(0);
opacity: 1;
}
76% {
clip: rect(0px, 32px, 32px, 0px);
}
85% {
clip: rect(32px, 32px, 32px, 0px);
}
100% {
transform: translateY(0);
opacity: 0;
}
}
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
CodePudding user response:
I removed z-index from keyframes and just do small changes into your existing CSS style code so check below snippet.
*,::before, ::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
}
.container {
position: relative;
box-shadow: 0 0 0 1px red;
height: 200px;
width: 64px;
overflow: hidden;
}
.item {
display: flex;
align-items: center;
justify-content: center;
padding: 8px;
background-color: blue;
color: white;
height: 60px;
width: 64px;
text-align: center;
position: absolute;
top: auto;
bottom: 0;
animation: AnimateCard 16s infinite cubic-bezier(0.48, 0.18, 0.35, 1.01);
}
.item:nth-child(1) {
animation-delay: -9s;
}
.item:nth-child(2) {
animation-delay: -5s;
}
.item:nth-child(3) {
animation-delay: -1s;
}
.item:nth-child(4) {
animation-delay: 3s;
}
@keyframes AnimateCard {
0% {
transform: translateY(-210px);
opacity: 0;
}
26% {
transform: translateY(-140px);
opacity: 0.5;
}
34% {
transform: translateY(-70px);
opacity: 0.2;
}
51% {
transform: translateY(-70px);
opacity: 0.2;
}
58% {
transform: translateY(0);
opacity: 1;
}
74% {
transform: translateY(0);
opacity: 1;
}
91% {
transform: translateY(140px);
opacity: 1;
}
100% {
transform: translateY(210px);
opacity: 0;
}
}
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>