Infinitely rotating vertical carousel animation. CSS only.
Created
March 3, 2023 05:10
-
-
Save adrianbj/d5a1316aa73f18f2cbaa6c80ca7ab450 to your computer and use it in GitHub Desktop.
CSS vertical carousel animation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.wrapper | |
.carousel | |
- emojis = [ ["π³", "spouting whale", "U+1F433 "], | |
["π", "whale", "U+1F40B "], | |
["π¬", "dolphin", "U+1F42C "], | |
["π", "fish", "U+1F41F "], | |
["π ", "tropical fish", "U+1F420 "], | |
["π‘", "blowfish", "U+1F421 "], | |
["π¦", "shark", "U+1F988 "], | |
["π", "octopus", "U+1F419 "], | |
["π", "spiral shell", "U+1F41A "] ] | |
- emojis.each do |i| | |
.carousel__item | |
.carousel__item-head | |
#{i[0]} | |
.carousel__item-body | |
%p.title #{i[1]} | |
%p Unicode: #{i[2]} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$animation-timing: 27s; | |
$carousel-items: 9; | |
$animation-delay-fraction: $animation-timing / $carousel-items; | |
$animation-steps-fraction: 100 / $carousel-items; | |
$slide-change-timing: 3; // percentage of total animation cycle | |
*, *::before, *::after { | |
box-sizing: border-box; | |
} | |
body { | |
font-family: 'Work Sans', sans-serif; | |
font-weight: 400; | |
height: 100vh; | |
} | |
.wrapper { | |
background: linear-gradient(60deg, #420285, #08BDBD); | |
height: 100%; | |
width: 100%; | |
display: flex; | |
justify-content: center; | |
} | |
.carousel { | |
position: relative; | |
width: 100%; | |
max-width: 500px; | |
display: flex; | |
justify-content: center; | |
flex-direction: column; | |
} | |
.carousel__item { | |
display: flex; | |
align-items: center; | |
position: absolute; | |
width: 100%; | |
padding: 0 12px; | |
opacity: 0; | |
filter: drop-shadow(0 2px 2px #555); | |
will-change: transform, opacity; | |
animation: carousel-animate-vertical $animation-timing linear infinite; | |
} | |
@for $i from 1 through ($carousel-items - 1) { | |
.carousel__item:nth-child(#{$i}) { | |
animation-delay: calc(#{$animation-delay-fraction} * #{$i - 2}); | |
} | |
} | |
.carousel__item:last-child { | |
animation-delay: calc(-#{$animation-delay-fraction} * 2); | |
} | |
// example without negative delays | |
// @for $i from 1 through ($carousel-items) { | |
// .carousel__item:nth-child(#{$i}) { | |
// animation-delay: calc(#{$animation-delay-fraction} * #{$i}); | |
// } | |
// } | |
.carousel__item-head { | |
border-radius: 50%; | |
background-color: #d7f7fc; | |
width: 90px; | |
height: 90px; | |
padding: 14px; | |
position: relative; | |
margin-right: -45px; | |
flex-shrink: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-size: 50px; | |
} | |
.carousel__item-body { | |
width: 100%; | |
background-color: #fff; | |
border-radius: 8px; | |
padding: 16px 20px 16px 70px; | |
} | |
.title { | |
text-transform: uppercase; | |
font-size: 20px; | |
margin-top: 10px; | |
} | |
@keyframes carousel-animate-vertical { | |
0% { | |
transform: translateY(100%) scale(0.5); | |
opacity: 0; | |
visibility: hidden; | |
} | |
#{$slide-change-timing}%, | |
#{$animation-steps-fraction}% { | |
transform: translateY(100%) scale(0.7); | |
opacity: .4; | |
visibility: visible; | |
} | |
#{$animation-steps-fraction + $slide-change-timing}%, | |
#{$animation-steps-fraction * 2}% { | |
transform: translateY(0) scale(1); | |
opacity: 1; | |
visibility: visible; | |
} | |
#{($animation-steps-fraction * 2) + $slide-change-timing}%, | |
#{$animation-steps-fraction * 3}% { | |
transform: translateY(-100%) scale(0.7); | |
opacity: .4; | |
visibility: visible; | |
} | |
#{($animation-steps-fraction * 3) + $slide-change-timing}% { | |
transform: translateY(-100%) scale(0.5); | |
opacity: 0; | |
visibility: visible; | |
} | |
100% { | |
transform: translateY(-100%) scale(0.5); | |
opacity: 0; | |
visibility: hidden; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment