36 CSS Stacked Cards35 / 36
Timeline Stack
A vertical timeline with a gradient spine and milestone nodes. Hover slides each card right and pulses its node. Suited to roadmaps, company history, or changelogs.
Published Updated
The code
<div class="scd-35">
<div class="scd-35__stage">
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2021</span><h3>The Beginning</h3><p>First prototype shipped to ten beta users.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2023</span><h3>Going Public</h3><p>Launched the open platform to everyone.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2025</span><h3>Scale</h3><p>Crossed one million active accounts.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2026</span><h3>What's Next</h3><p>Reimagining the experience from scratch.</p></div></div>
</div>
</div><div class="scd-35">
<div class="scd-35__stage">
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2021</span><h3>The Beginning</h3><p>First prototype shipped to ten beta users.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2023</span><h3>Going Public</h3><p>Launched the open platform to everyone.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2025</span><h3>Scale</h3><p>Crossed one million active accounts.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2026</span><h3>What's Next</h3><p>Reimagining the experience from scratch.</p></div></div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@700&family=Schibsted+Grotesk:wght@400;500&display=swap');
.scd-35,
.scd-35 *,
.scd-35 *::before,
.scd-35 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.scd-35 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: linear-gradient(180deg,#fffaf0,#f0e8dc);
font-family: 'Schibsted Grotesk', sans-serif;
}
.scd-35__stage {
position: relative;
width: 340px;
padding-left: 40px;
}
.scd-35__stage::before {
content: '';
position: absolute;
left: 14px;
top: 10px;
bottom: 10px;
width: 3px;
background: linear-gradient(#ff8a5c,#a83279);
border-radius: 3px;
}
.scd-35__node {
position: relative;
margin-bottom: 14px;
}
.scd-35__node::before {
content: '';
position: absolute;
left: -33px;
top: 18px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
border: 3px solid #ff8a5c;
transition: transform .35s, background .35s;
}
.scd-35__card {
background: #fff;
border-radius: 14px;
padding: 16px 20px;
box-shadow: 0 8px 20px rgba(120,60,80,.12);
transition: transform .35s cubic-bezier(.3,.9,.3,1), box-shadow .35s;
cursor: pointer;
}
.scd-35__yr {
font-family: 'Bricolage Grotesque', sans-serif;
color: #a83279;
font-size: .8rem;
letter-spacing: .08em;
}
.scd-35__card h3 {
font-family: 'Bricolage Grotesque', sans-serif;
font-size: 1.1rem;
color: #2a2024;
margin: 2px 0 4px;
}
.scd-35__card p {
font-size: .85rem;
color: #6a5a60;
}
.scd-35__node:hover .scd-35__card {
transform: translateX(12px);
box-shadow: 0 14px 30px rgba(120,60,80,.2);
}
.scd-35__node:hover::before {
transform: scale(1.3);
background: #a83279;
}
@media (prefers-reduced-motion: reduce) {
.scd-35__card,
.scd-35__node::before {
transition: none !important;
}
}@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@700&family=Schibsted+Grotesk:wght@400;500&display=swap');
.scd-35,
.scd-35 *,
.scd-35 *::before,
.scd-35 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.scd-35 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: linear-gradient(180deg,#fffaf0,#f0e8dc);
font-family: 'Schibsted Grotesk', sans-serif;
}
.scd-35__stage {
position: relative;
width: 340px;
padding-left: 40px;
}
.scd-35__stage::before {
content: '';
position: absolute;
left: 14px;
top: 10px;
bottom: 10px;
width: 3px;
background: linear-gradient(#ff8a5c,#a83279);
border-radius: 3px;
}
.scd-35__node {
position: relative;
margin-bottom: 14px;
}
.scd-35__node::before {
content: '';
position: absolute;
left: -33px;
top: 18px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
border: 3px solid #ff8a5c;
transition: transform .35s, background .35s;
}
.scd-35__card {
background: #fff;
border-radius: 14px;
padding: 16px 20px;
box-shadow: 0 8px 20px rgba(120,60,80,.12);
transition: transform .35s cubic-bezier(.3,.9,.3,1), box-shadow .35s;
cursor: pointer;
}
.scd-35__yr {
font-family: 'Bricolage Grotesque', sans-serif;
color: #a83279;
font-size: .8rem;
letter-spacing: .08em;
}
.scd-35__card h3 {
font-family: 'Bricolage Grotesque', sans-serif;
font-size: 1.1rem;
color: #2a2024;
margin: 2px 0 4px;
}
.scd-35__card p {
font-size: .85rem;
color: #6a5a60;
}
.scd-35__node:hover .scd-35__card {
transform: translateX(12px);
box-shadow: 0 14px 30px rgba(120,60,80,.2);
}
.scd-35__node:hover::before {
transform: scale(1.3);
background: #a83279;
}
@media (prefers-reduced-motion: reduce) {
.scd-35__card,
.scd-35__node::before {
transition: none !important;
}
}Here's a working CSS Stacked Card from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Timeline Stack
Source: https://codefronts.com/components/css-stacked-cards/timeline-stack/
A vertical timeline with a gradient spine and milestone nodes. Hover slides each card right and pulses its node. Suited to roadmaps, company history, or changelogs.
## HTML
```html
<div class="scd-35">
<div class="scd-35__stage">
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2021</span><h3>The Beginning</h3><p>First prototype shipped to ten beta users.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2023</span><h3>Going Public</h3><p>Launched the open platform to everyone.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2025</span><h3>Scale</h3><p>Crossed one million active accounts.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2026</span><h3>What's Next</h3><p>Reimagining the experience from scratch.</p></div></div>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@700&family=Schibsted+Grotesk:wght@400;500&display=swap');
.scd-35,
.scd-35 *,
.scd-35 *::before,
.scd-35 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.scd-35 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: linear-gradient(180deg,#fffaf0,#f0e8dc);
font-family: 'Schibsted Grotesk', sans-serif;
}
.scd-35__stage {
position: relative;
width: 340px;
padding-left: 40px;
}
.scd-35__stage::before {
content: '';
position: absolute;
left: 14px;
top: 10px;
bottom: 10px;
width: 3px;
background: linear-gradient(#ff8a5c,#a83279);
border-radius: 3px;
}
.scd-35__node {
position: relative;
margin-bottom: 14px;
}
.scd-35__node::before {
content: '';
position: absolute;
left: -33px;
top: 18px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
border: 3px solid #ff8a5c;
transition: transform .35s, background .35s;
}
.scd-35__card {
background: #fff;
border-radius: 14px;
padding: 16px 20px;
box-shadow: 0 8px 20px rgba(120,60,80,.12);
transition: transform .35s cubic-bezier(.3,.9,.3,1), box-shadow .35s;
cursor: pointer;
}
.scd-35__yr {
font-family: 'Bricolage Grotesque', sans-serif;
color: #a83279;
font-size: .8rem;
letter-spacing: .08em;
}
.scd-35__card h3 {
font-family: 'Bricolage Grotesque', sans-serif;
font-size: 1.1rem;
color: #2a2024;
margin: 2px 0 4px;
}
.scd-35__card p {
font-size: .85rem;
color: #6a5a60;
}
.scd-35__node:hover .scd-35__card {
transform: translateX(12px);
box-shadow: 0 14px 30px rgba(120,60,80,.2);
}
.scd-35__node:hover::before {
transform: scale(1.3);
background: #a83279;
}
@media (prefers-reduced-motion: reduce) {
.scd-35__card,
.scd-35__node::before {
transition: none !important;
}
}
```Here's a working CSS Stacked Card from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Timeline Stack
Source: https://codefronts.com/components/css-stacked-cards/timeline-stack/
A vertical timeline with a gradient spine and milestone nodes. Hover slides each card right and pulses its node. Suited to roadmaps, company history, or changelogs.
## HTML
```html
<div class="scd-35">
<div class="scd-35__stage">
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2021</span><h3>The Beginning</h3><p>First prototype shipped to ten beta users.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2023</span><h3>Going Public</h3><p>Launched the open platform to everyone.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2025</span><h3>Scale</h3><p>Crossed one million active accounts.</p></div></div>
<div class="scd-35__node"><div class="scd-35__card"><span class="scd-35__yr">2026</span><h3>What's Next</h3><p>Reimagining the experience from scratch.</p></div></div>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@700&family=Schibsted+Grotesk:wght@400;500&display=swap');
.scd-35,
.scd-35 *,
.scd-35 *::before,
.scd-35 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.scd-35 {
width: 100%;
min-height: 100vh;
display: grid;
place-items: center;
background: linear-gradient(180deg,#fffaf0,#f0e8dc);
font-family: 'Schibsted Grotesk', sans-serif;
}
.scd-35__stage {
position: relative;
width: 340px;
padding-left: 40px;
}
.scd-35__stage::before {
content: '';
position: absolute;
left: 14px;
top: 10px;
bottom: 10px;
width: 3px;
background: linear-gradient(#ff8a5c,#a83279);
border-radius: 3px;
}
.scd-35__node {
position: relative;
margin-bottom: 14px;
}
.scd-35__node::before {
content: '';
position: absolute;
left: -33px;
top: 18px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
border: 3px solid #ff8a5c;
transition: transform .35s, background .35s;
}
.scd-35__card {
background: #fff;
border-radius: 14px;
padding: 16px 20px;
box-shadow: 0 8px 20px rgba(120,60,80,.12);
transition: transform .35s cubic-bezier(.3,.9,.3,1), box-shadow .35s;
cursor: pointer;
}
.scd-35__yr {
font-family: 'Bricolage Grotesque', sans-serif;
color: #a83279;
font-size: .8rem;
letter-spacing: .08em;
}
.scd-35__card h3 {
font-family: 'Bricolage Grotesque', sans-serif;
font-size: 1.1rem;
color: #2a2024;
margin: 2px 0 4px;
}
.scd-35__card p {
font-size: .85rem;
color: #6a5a60;
}
.scd-35__node:hover .scd-35__card {
transform: translateX(12px);
box-shadow: 0 14px 30px rgba(120,60,80,.2);
}
.scd-35__node:hover::before {
transform: scale(1.3);
background: #a83279;
}
@media (prefers-reduced-motion: reduce) {
.scd-35__card,
.scd-35__node::before {
transition: none !important;
}
}
```How this works
A vertical timeline with a gradient spine — a single ::before pseudo-element on the timeline column, painted as a linear-gradient vertical bar. Milestone nodes sit as inline elements positioned at each event, with card content branching to the right.
Each timeline entry is a flex row: milestone dot (fixed width) + card content (flex:1). On hover of a card, it slides right via translateX(8px) and the milestone node pulses via @keyframes — a subtle bloom animation that draws the eye to the currently-focused event.
Zero JavaScript. The gradient spine + node pulse + card slide all handled by CSS.
Make it yours
- Rebrand the gradient spine from
--spine-aand--spine-bon the wrapper. - Change the milestone node style — circle (default), square, star, custom SVG.
- Adjust the card slide distance via
translateXon hover. - Tune node pulse via the
@keyframesand animation duration. - For roadmaps, add status pills (Shipped / In Progress / Planned) inside each card with distinct colours.
Gotchas — read before shipping
- Timelines should be semantic — use
<ol>or<ul>for the event list, not<div>soup. - Include ISO dates in
<time datetime="YYYY-MM-DD">elements so search engines and AI assistants can parse the timeline. - The node pulse animation must respect
prefers-reduced-motion:reduce. - On narrow viewports (<640px), collapse the timeline to a single column with the spine on the left and cards full-width.
- For company-history timelines, keep entries under 40 words each — timelines are scannable, not for long-form reading.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 45+ | 9+ | 16+ | 45+ |
CSS flex, gradients, pseudo-elements, and keyframes are universally supported.