This content originally appeared on DEV Community and was authored by Prahalad S
3D Infinite Carousel/Coverflow Slider in Pure CSS with reflection!
Hi Guys! I wanted to share few CSS tricks creating Infinite Carousel Slider in Pure CSS. So lets begin.
Html Code:
This HTML code creates an image carousel using a <ul>
gallery inside a <div>
container. Each <li>
contains an image and a '--timer'
variable for animation sequencing. Let's create 9 images.
<section>
<div class="carousel">
<ul class="gallery">
<li class="card" style="--timer: 1"><img src="img/1.jpg" alt=""></li>
<li class="card" style="--timer: 2"><img src="img/2.jpg" alt=""></li>
<li class="card" style="--timer: 3"><img src="img/3.jpg" alt=""></li>
<li class="card" style="--timer: 4"><img src="img/4.jpg" alt=""></li>
<li class="card" style="--timer: 5"><img src="img/3.jpg" alt=""></li>
<li class="card" style="--timer: 6"><img src="img/2.jpg" alt=""></li>
<li class="card" style="--timer: 7"><img src="img/1.jpg" alt=""></li>
<li class="card" style="--timer: 8"><img src="img/2.jpg" alt=""></li>
<li class="card" style="--timer: 9"><img src="img/3.jpg" alt=""></li>
</ul>
</div>
</section>
Let's create CSS.
The --num
variable determines the total images.
The --wd
variable determines width of card
div.
* {
margin: 0;
padding: 0;
}
:root {
--num: 9; /* total images */
--wd: 130; /* width of card element */
/* --gap: 20px; */
}
body {
background-color: #e4e7ee;
}
section {
width: clamp(480px, 80%, 90vw);
margin: 0 auto;
}
.carousel {
display: flex;
align-items: flex-start;
height: 100vh;
overflow: hidden;
/* masking left and right like fading effect */
mask-image: linear-gradient(to right, transparent, #000 5% 95%, transparent);
}
.carousel .gallery {
list-style-type: none;
display: flex;
align-items: center;
width: 100%;
height: 450px;
position: relative;
perspective: 40em;
}
.carousel .gallery .card {
width: 130px;
height: auto;
position: absolute;
transform-style: preserve-3d;
left: 100%;
animation: slide 9s linear infinite, scaleEffect 9s ease-in-out infinite;
animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1));
transition: transform 0.25s ease-in-out;
}
.carousel .gallery .card img {
width: 100%;
border-radius: 5px;
box-shadow: 0px 0px 16px #cecece;
/* images reflection */
-webkit-box-reflect: below 0px linear-gradient(to bottom, rgba(0, 0, 0, 0.0), rgba(0, 0, 0, 0.4));
}
Animation Explanation used in css .carousel .gallery .card
:
slide 9s linear infinite:
Moves elements in a sliding motion, lasting 9 seconds, repeating infinitely with a constant speed.
scaleEffect 9s ease-in-out infinite: Applies a scaling effect over 9 seconds with a smooth acceleration and deceleration, repeating infinitely.
animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1)):
Staggers animations by computing a delay based on each element’s --timer
value, ensuring synchronized but sequential transitions.
.carousel .gallery .card {
width: 130px;
height: auto;
position: absolute;
transform-style: preserve-3d;
left: 100%;
animation: slide 9s linear infinite, scaleEffect 9s ease-in-out infinite;
animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1));
transition: transform 0.25s ease-in-out;
}
Slide Animation Explanation for below CSS
@keyframes slide: Defines an animation that moves an element horizontally.
from { left: 100%; }: Starts the element from the rightmost position (fully outside the viewport).
to { left: calc(-1 * var(--wd) * 1px); }: Moves the element leftward by --wd pixels, shifting it completely out of view.
This animation is typically used for seamless scrolling effects, such as a continuously moving carousel or ticker.
@keyframes slide {
from {
left: 100%;
}
to {
/* Moves the element leftward by --wd pixels, shifting it completely out of view. */
left: calc(-1 * var(--wd)* 1px);
}
}
Scale Effect Animation Explanation for below CSS
@keyframes scaleEffect: Defines a scaling animation with grayscale and layering effects.
0%, 25%, 75%, 100%: The element remains at its normal scale (scale(1)), has a lower stacking order (z-index: 0), and is fully grayscaled (grayscale(1)).
50%: The element scales up to twice its size (scale(2), moves to the foreground (z-index: 10), and becomes fully colored (grayscale(0)).
This animation creates a pulsating zoom effect, making elements dynamically pop out and fade back in.
@keyframes scaleEffect {
0%,
25%,
75%,
100% {
transform: scale(1);
z-index: 0;
filter: grayscale(1);
}
50% {
transform: scale(2);
z-index: 10;
filter: grayscale(0);
}
}
In the GIF below, you can see a scaling effect applied to the center image, along with a medium scaling effect on the two adjacent images.
Result
If you want only the center image to be scaled, simply modify the scaleEffect in the CSS below.
Replace values in `@keyframes scaleEffect:
`0%, 25%, 75%, 100% with 0%, 40%, 60%, 100%.
Then you can see below output.
Finally lets go with 3D Carousel.
I've already set perspective: 40em; in .carousel .gallery
and transform-style: preserve-3d;
in .carousel .gallery .card
. Now, we'll only modify scaleEffect
again. So, let's replace@keyframes scaleEffect
once more.
@keyframes scaleEffect {
0%, 25%, 75%, 100% {
transform: scale(1) rotateY(0deg);
z-index: 0;
filter: grayscale(1);
}
35% {
transform: scale(1.25) rotateY(-45deg);
z-index: 5;
filter: grayscale(1);
}
50% {
transform: scale(2) rotateY(0deg);
z-index: 10;
filter: grayscale(0);
}
65% {
transform: scale(1.25) rotateY(45deg);
z-index: 5;
filter: grayscale(1);
}
}
Result
Our 3D Carousel is complete! However, you can still experiment with different transform effects by making slight adjustments to the scaleEffect
.
Lets create COVERFLOW
@keyframes scaleEffect {
0%, 40%, 60%, 100% {
transform: scale(1) rotateY(-90deg);
z-index: 0;
filter: grayscale(1);
}
50% {
transform: scale(2) rotateY(0deg);
z-index: 10;
filter: grayscale(0);
}
}
COVERFLOW Result
Changing the transform value in coverflow code from -90 to -180 gives the below output.
transform: scale(1) rotateY(-180deg);
Now that we've made enough edits, there's just a small tweak left. If you want each image to scale one by one from left to right instead of just the center image, follow these steps:
- Comment out the "
mask
" effect and "overflow: hidden
" in ".carousel
". - Add "
margin-left: 50px;
" in ".carousel .gallery
". - Comment out "
position: absolute, left: 100%,
" in ".carousel .gallery .card
" and add "margin:0 20px;
" for gaps between images.
This will produce the output shown below. If needed, make further adjustments to match your requirements and leave the scrollEffect as it is with whatever animation you like from above scrollEffects
.carousel {
/* overflow: hidden; */
/* mask-image: linear-gradient(to right, transparent, #000 5% 95%, transparent); */
}
.carousel .gallery {
margin-left: 50px;
}
.carousel .gallery .card {
/* position: absolute; */
/* left: 100% */
margin: 0 20px;
}
Images zooming from left to right
Images zooming from left to right with its two adjacent images
Images flipping from left to right
Last but not least. Its already responsive!
If you still want to resize images for different screens you can add media query.
/* responsive */
@media only screen and (max-width: 768px) {
.carousel .gallery .card {
width: calc(var(--wd) / 2 * 1px);
}
}
Thank you!
Click here to view Working Demos
This content originally appeared on DEV Community and was authored by Prahalad S

Prahalad S | Sciencx (2025-02-01T10:48:20+00:00) 3D Infinite Carousel/Coverflow Slider in Pure CSS with reflection!. Retrieved from https://www.scien.cx/2025/02/01/3d-infinite-carousel-coverflow-slider-in-pure-css-with-reflection/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.