Pure CSS Timed Cards Opening
The Pure CSS Timed Cards Carousel displays multiple cards that slide horizontally across the screen at fixed intervals.
Each card includes:
- Title
- Description
- Image
- Optional button
- Auto-expanding animation
- Timed text reveal
- Reflection + blend modes
Each card uses a CSS variable --timer to control staggered animation timing.
HTML Structure
<!-- responsive coming soon
-->
<span class="hamburger">☰</span>
<section>
<div class="carousel">
<ul class="gallery">
<li class="card" style="--timer: 1; ">
<h2>Moments in Motion</h2>
<p>Experience the world as it moves — where every frame tells a story of life in motion.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/silhouette-twilight-forest-landscape-background_1308-69379.jpg"
alt="">
</li>
<li class="card" style="--timer: 2">
<h2>Through the Lens</h2>
<p>A glimpse into the unseen beauty captured by the eye of imagination.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/flat-design-forest-landscape_23-2149162735.jpg"
alt="">
</li>
<li class="card" style="--timer: 3">
<h2>Wanderlust Chronicles</h2>
<p>Embark on a journey through breathtaking landscapes and untold adventures.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/natural-landscape-wallpaper-video-conferencing_23-2148651571.jpg"
alt="">
</li>
<li class="card" style="--timer: 4">
<h2>Adventure Awaits</h2>
<p>Step into the wild and discover nature’s finest hidden gems.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/natural-landscape-wallpaper-video-conferencing_23-2148651572.jpg"
alt="">
</li>
<li class="card" style="--timer: 5">
<h2>Footprints Around the World</h2>
<p>Every step tells a story — from the dunes to the valleys beyond the horizon.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/flat-design-adventure-background_23-2149059266.jpg"
alt="">
</li>
<li class="card" style="--timer: 6">
<h2>Dreams in Color</h2>
<p>A vibrant collection of landscapes painted by light, nature, and emotion.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/gradient-adventure-background_23-2149048608.jpg"
alt="">
</li>
<li class="card" style="--timer: 7">
<h2>Canvas of Emotions</h2>
<p>Where every hue, shade, and line reflects the pulse of the natural world.</p>
<!-- <button>View More</button> -->
<span></span>
<img src="https://img.freepik.com/free-vector/flat-design-forest-landscape_23-2149162734.jpg"
alt="">
</li>
<li class="card" style="--timer: 8">
<h2>The Story of Us</h2>
<p>A timeless tale of connection — between people, nature, and the places we call home.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/hand-drawn-mountain-landscape_23-2149156633.jpg"
alt="">
</li>
<li class="card" style="--timer: 9">
<h2>Moments of Magic</h2>
<p>Capture the beauty of fleeting instants that linger forever in our hearts.</p>
<!-- <button>View More</button> --><span></span>
<img src="https://img.freepik.com/free-vector/gradient-winter-solstice-illustration_23-2149201708.jpg"
alt="">
</li>
</ul>
</div>
</section>
How the Timing System Works
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
Animation Sequence Logic:
✔ Phase 1 — Card enters
- Card slides in from right
- Title and paragraph are hidden
- Image is dimmed
✔ Phase 2 — Card becomes active
- Card enlarges (scaleEffect)
- Title grows to 50px (scaleText)
- Description fades in (paraText)
- Button becomes visible (button optional)
✔ Phase 3 — Card exits
- Text fades out
- Card shrinks
- Image fades to 0
- Card slides out left
- Then the next card begins.
CSS
* {
margin: 0;
padding: 0;
}
:root {
--num: 9;
/* number of images */
--wd: 130;
/* width of card div, in px */
--gap: 20px;
/* gap between cards */
--duration: 27s;
/* total animation duration */
}
body {
background-color: #000000;
font-family: "Poppins", sans-serif;
}
section {
width: 100%;
margin: 0 auto;
}
.carousel {
display: flex;
align-items: flex-start;
height: 100vh;
overflow: hidden;
/* mask-image: linear-gradient(to bottom, transparent, #000 5%, #000 80%, transparent); */
justify-content: center;
width: 100%;
}
.carousel .gallery {
list-style-type: none;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: relative;
}
.carousel .gallery .card {
width: calc(var(--wd) / 1.2 * 1px);
height: auto;
position: absolute;
left: 100%;
animation: slide var(--duration) linear infinite,
scaleEffect var(--duration) ease-in-out infinite;
/* Stagger cards using --timer (should be 1 to 9 for your HTML cards) */
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
}
.carousel .gallery .card h2 {
position: absolute;
font-weight: 800;
z-index: 2;
top: 100px;
font-size: 20px;
transform: translate(0px, 100px);
color: white;
left: 0;
width: 130px;
text-transform: uppercase;
animation: scaleText var(--duration) ease-in-out infinite;
/* Stagger cards using --timer (should be 1 to 9 for your HTML cards) */
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
transition: transform 0.5s ease;
mix-blend-mode: overlay;
}
.carousel .gallery .card p {
opacity: 1;
z-index: 2;
position: absolute;
top: 350px;
font-weight: 200;
color: white;
transform: translate(0px, 200px);
animation: paraText var(--duration) ease-in-out infinite;
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
transition: transform 0.5s ease;
mix-blend-mode: overlay;
}
.carousel .gallery .card img {
width: 100%;
border-radius: 5px;
filter: brightness(0.7);
transform: translate(130px, 100px);
border: 1pt dashed #bcbcbc;
animation: moveImg var(--duration) ease-in-out infinite;
/* Stagger cards using --timer (should be 1 to 9 for your HTML cards) */
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
-webkit-box-reflect: below 0px
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4));
transition: transform var(--duration) s ease;
}
button {
background: transparent;
padding: 15px;
color: white;
text-align: center;
text-transform: uppercase;
border: 0;
border-radius: 20px;
position: absolute;
top: 270px;
mix-blend-mode: color-dodge;
border: 0.05rem dashed white;
opacity: 0;
z-index: 2;
transform: translate(130px, 200px);
animation: button var(--duration) ease-in-out infinite;
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
transition: transform 0.5s ease;
}
.carousel .gallery .card h2:before {
content: "";
width: 10px;
height: 5px;
background: rgb(192, 192, 192);
position: absolute;
top: 0;
left: 0;
z-index: 2;
opacity: 1;
transform-origin: left;
/* important */
animation: loader var(--duration) ease-in-out infinite;
animation-delay: calc(
var(--duration) * ((var(--timer) - 1) / var(--num) - 1)
);
}
.hamburger {
color: #ffffff;
position: fixed;
right: 2%;
top: 2%;
font-size: 30px;
font-weight: lighter;
}
@keyframes slide {
0% {
left: 100%;
}
/* scroll 1s, pause 5s per card (≈1.85% scroll, 9.26% pause per cycle) */
1.85% {
left: calc(100% - (1 * (100% + var(--wd) * 1px) / var(--num)));
}
11.11% {
left: calc(100% - (1 * (100% + var(--wd) * 1px) / var(--num)));
}
12.96% {
left: calc(100% - (2 * (100% + var(--wd) * 1px) / var(--num)));
}
22.22% {
left: calc(100% - (2 * (100% + var(--wd) * 1px) / var(--num)));
}
24.07% {
left: calc(100% - (3 * (100% + var(--wd) * 1px) / var(--num)));
}
33.33% {
left: calc(100% - (3 * (100% + var(--wd) * 1px) / var(--num)));
}
35.18% {
left: calc(100% - (4 * (100% + var(--wd) * 1px) / var(--num)));
}
44.44% {
left: calc(100% - (4 * (100% + var(--wd) * 1px) / var(--num)));
}
46.29% {
left: calc(100% - (5 * (100% + var(--wd) * 1px) / var(--num)));
}
55.55% {
left: calc(100% - (5 * (100% + var(--wd) * 1px) / var(--num)));
}
57.4% {
left: calc(100% - (6 * (100% + var(--wd) * 1px) / var(--num)));
}
66.66% {
left: calc(100% - (6 * (100% + var(--wd) * 1px) / var(--num)));
}
68.51% {
left: calc(100% - (7 * (100% + var(--wd) * 1px) / var(--num)));
}
77.77% {
left: calc(100% - (7 * (100% + var(--wd) * 1px) / var(--num)));
}
79.62% {
left: calc(100% - (8 * (100% + var(--wd) * 1px) / var(--num)));
}
88.88% {
left: calc(100% - (9 * (100% + var(--wd) * 1px) / var(--num)));
}
90.73% {
left: calc(-1 * var(--wd) * 1px);
font-size: 40px;
}
100% {
left: calc(-1 * var(--wd) * 1px);
}
}
@keyframes scaleEffect {
0%,
80% {
width: 130px;
z-index: 0;
opacity: 1;
margin-left: 520px;
}
81%,
100% {
width: calc(100% + 260px);
margin-left: -130px;
z-index: -1;
opacity: 1;
}
}
@keyframes scaleText {
0%,
80% {
font-size: 14px;
transform: translate(0px, 100px);
width: 130px;
left: 0;
top: 120px;
}
81%,
88.88% {
font-size: 50px;
width: auto;
left: 15%;
top: 370px;
opacity: 1;
transform: translate(65px, 100px);
}
61%,
87% {
transform: translate(0px, 100px);
}
88.89%,
100% {
opacity: 0;
transform: translate(0px, 100px);
}
}
@keyframes paraText {
0%,
60% {
font-size: 1rem;
transform: translate(0px, 200px);
width: 130px;
left: 15%;
top: 350px;
opacity: 0;
}
61%,
87% {
font-size: 2rem;
width: 30%;
left: 15%;
top: 350px;
opacity: 1;
transform: translate(0px, 200px);
}
88%,
100% {
opacity: 0;
transform: translate(130px, 200px);
}
}
@keyframes button {
0%,
80% {
transform: translate(0px, 200px);
left: 15%;
top: 500px;
opacity: 0;
}
81%,
88.88% {
left: 15%;
top: 500px;
opacity: 1;
}
88.89%,
100% {
opacity: 0;
transform: translate(130px, 200px);
}
}
@keyframes loader {
0%,
70% {
transform: scaleX(0);
opacity: 1;
left: -200%;
top: 300%;
background:orange;
}
71% {
transform: scaleX(50);
opacity: 1;
left: -200%;
top: 300%;
background:orange;
}
78%,
100% {
transform: scaleX(0);
opacity: 0;
left: -200%;
top: 300%; background:black;
}
}
@keyframes moveImg {
0%,
88% {
transform: translate(0px, 100px);
opacity: 1;
mix-blend-mode: overlay;
z-index: 0;
}
99%,
100% {
opacity: 0;
z-index: -1;
transform: translate(0px, 100px);
}
}

Top comments (0)