Components
Timeline
A list of events in chronological order along a line: dots, icons or avatars, colours and sizes, vertical or horizontal, on one side or alternating.
-
Version 1.0 released
Stable APIs for every component, the engine and the plugins.
-
Release candidate
Feature freeze, and a public call for testing.
-
First public beta
Forty components and the docs site.
<ol class="timeline max-w-md">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"></span>
<div class="timeline-content">
<time class="timeline-time" datetime="2026-10-07">7 October 2026</time>
<h3 class="timeline-title">Version 1.0 released</h3>
<p class="timeline-description">Stable APIs for every component, the engine and the plugins.</p>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker"></span>
<div class="timeline-content">
<time class="timeline-time" datetime="2026-08-14">14 August 2026</time>
<h3 class="timeline-title">Release candidate</h3>
<p class="timeline-description">Feature freeze, and a public call for testing.</p>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker"></span>
<div class="timeline-content">
<time class="timeline-time" datetime="2026-05-02">2 May 2026</time>
<h3 class="timeline-title">First public beta</h3>
<p class="timeline-description">Forty components and the docs site.</p>
</div>
</li>
</ol>
Markup#
- An
<ol class="timeline">of<li class="timeline-item">: a list in order, which is what screen readers announce. It is CSS only, with no behaviour. - Each item has a
.timeline-markerand a.timeline-content. Inside the content,.timeline-time(a<time datetime>),.timeline-titleand.timeline-descriptionare all optional; any other markup works too. - The line to the next item is drawn for you, and stops at the last item.
- Newest first or oldest first is up to you: the timeline shows items in the order they are written.
Markers#
An empty .timeline-marker is a dot. .timeline-marker-primary, -success,
-warning, -danger and -info colour it, and .timeline-marker-outline
makes it hollow.
Default
Primary
Success
Warning
Danger
Info
Default
Primary
Success
Warning
Danger
Info
<ol class="timeline">
<li class="timeline-item"><span class="timeline-marker"></span><div class="timeline-content"><p class="timeline-title">Default</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-primary"></span><div class="timeline-content"><p class="timeline-title">Primary</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-success"></span><div class="timeline-content"><p class="timeline-title">Success</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-warning"></span><div class="timeline-content"><p class="timeline-title">Warning</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-danger"></span><div class="timeline-content"><p class="timeline-title">Danger</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-info"></span><div class="timeline-content"><p class="timeline-title">Info</p></div></li>
</ol>
<ol class="timeline">
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline"></span><div class="timeline-content"><p class="timeline-title">Default</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline timeline-marker-primary"></span><div class="timeline-content"><p class="timeline-title">Primary</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline timeline-marker-success"></span><div class="timeline-content"><p class="timeline-title">Success</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline timeline-marker-warning"></span><div class="timeline-content"><p class="timeline-title">Warning</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline timeline-marker-danger"></span><div class="timeline-content"><p class="timeline-title">Danger</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline timeline-marker-info"></span><div class="timeline-content"><p class="timeline-title">Info</p></div></li>
</ol>
Put an icon, a number or an image in the marker and it becomes a circle; the line and the first line of text
centre on it. Plain circles have a border; the colours fill them, and .timeline-marker-outline draws a
coloured ring instead.
-
Pull request merged
feat(ui): timeline component
-
3 commits pushed
Alternating layout, sizes and docs.
-
Review requested from Sam
-
Comment
"Looks good: could the dots line up with the first line of text?"
<ol class="timeline max-w-md">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Pull request merged</h3>
<p class="timeline-description">feat(ui): timeline component</p>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><circle cx="12" cy="12" r="3"/><line x1="3" x2="9" y1="12" y2="12"/><line x1="15" x2="21" y1="12" y2="12"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">3 commits pushed</h3>
<p class="timeline-description">Alternating layout, sizes and docs.</p>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><img src="../../../images/avatar-1.svg" alt="" /></span>
<div class="timeline-content">
<h3 class="timeline-title">Review requested from Sam</h3>
<time class="timeline-time" datetime="2026-10-06T16:20">Yesterday at 4:20 pm</time>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-outline timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Comment</h3>
<p class="timeline-description">"Looks good: could the dots line up with the first line of text?"</p>
</div>
</li>
</ol>
Progress and the current step#
For a process (an order, a deployment, an application), colour the steps that are done, mark the current item with
aria-current="step", which adds a ring and tells screen readers where it is, and leave the rest as outline
markers. Numbers work as markers too.
-
Order placed
-
Packed
-
Out for delivery
Arriving today between 1 and 3 pm.
-
Delivered
- 1
Create an account
Done
- 2
Verify your email
Check your inbox
- 3
Invite your team
<ol class="timeline">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Order placed</h3>
<time class="timeline-time" datetime="2026-10-03T09:12">3 Oct, 9:12 am</time>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5M12 22V12"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Packed</h3>
<time class="timeline-time" datetime="2026-10-04T14:40">4 Oct, 2:40 pm</time>
</div>
</li>
<li class="timeline-item" aria-current="step">
<span class="timeline-marker timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2"/><path d="M15 18H9"/><path d="M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14"/><circle cx="17" cy="18" r="2"/><circle cx="7" cy="18" r="2"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Out for delivery</h3>
<p class="timeline-description">Arriving today between 1 and 3 pm.</p>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-outline"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title text-muted-foreground">Delivered</h3>
</div>
</li>
</ol>
<ol class="timeline">
<li class="timeline-item"><span class="timeline-marker timeline-marker-primary">1</span><div class="timeline-content"><h3 class="timeline-title">Create an account</h3><p class="timeline-description">Done</p></div></li>
<li class="timeline-item" aria-current="step"><span class="timeline-marker timeline-marker-outline timeline-marker-primary">2</span><div class="timeline-content"><h3 class="timeline-title">Verify your email</h3><p class="timeline-description">Check your inbox</p></div></li>
<li class="timeline-item"><span class="timeline-marker">3</span><div class="timeline-content"><h3 class="timeline-title text-muted-foreground">Invite your team</h3></div></li>
</ol>
Rich content#
The content takes any markup: a card, an alert, buttons.
-
Deploy failed
Build step exited with code 1Cannot find module "htmx-ui/timeline". View logs -
Deploy started
main · 02e12f4
docs: 0.2.0 changelog and contributor guides
<ol class="timeline w-full max-w-lg">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-danger"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4M12 17h.01"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Deploy failed</h3>
<time class="timeline-time" datetime="2026-10-07T10:05">10:05 am</time>
<div class="alert alert-danger mt-2">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6M9 9l6 6"/></svg>
<div class="alert-title">Build step exited with code 1</div>
<div class="alert-description">Cannot find module "htmx-ui/timeline". <a href="#content">View logs</a></div>
</div>
</div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Deploy started</h3>
<time class="timeline-time" datetime="2026-10-07T10:03">10:03 am</time>
<div class="card mt-2 gap-2 p-4 text-sm">
<p class="m-0 font-mono text-xs text-muted-foreground">main · 02e12f4</p>
<p class="m-0">docs: 0.2.0 changelog and contributor guides</p>
</div>
</div>
</li>
</ol>
Opposite content#
A .timeline-opposite in every item goes on the other side of the line, right-aligned in a column
--timeline-opposite wide (6rem): dates, times or amounts that read down one edge.
-
Keynote
Main hall
-
Building with htmx 4
Room 2
-
Lunch
<ol class="timeline max-w-md">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"></span>
<div class="timeline-content"><h3 class="timeline-title">Keynote</h3><p class="timeline-description">Main hall</p></div>
<time class="timeline-opposite" datetime="09:00">9:00 am</time>
</li>
<li class="timeline-item">
<span class="timeline-marker"></span>
<div class="timeline-content"><h3 class="timeline-title">Building with htmx 4</h3><p class="timeline-description">Room 2</p></div>
<time class="timeline-opposite" datetime="10:30">10:30 am</time>
</li>
<li class="timeline-item">
<span class="timeline-marker"></span>
<div class="timeline-content"><h3 class="timeline-title">Lunch</h3></div>
<time class="timeline-opposite" datetime="12:00">12:00 pm</time>
</li>
</ol>
Alternating#
.timeline-alternate puts the line in the middle and the items on either side of it in turn, with the
.timeline-opposite, if any, across from each one. On narrow screens (below the sm breakpoint)
it falls back to one side, so nothing gets squeezed.
-
Idea
A component library for htmx with no React and no build step for users.
-
First components
Buttons, inputs, dialogs and tabs, styled with Tailwind v4.
-
Docs site
Built with its own engine, with search and versioned docs.
-
Version 1.0
Stable, with a scaffolder for bun, npm, pnpm and yarn.
<ol class="timeline timeline-alternate w-full max-w-2xl">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M12 3l1.9 5.8L20 11l-6.1 2.2L12 19l-1.9-5.8L4 11l6.1-2.2z"/><path d="M19 3v4M17 5h4"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Idea</h3>
<p class="timeline-description">A component library for htmx with no React and no build step for users.</p>
</div>
<time class="timeline-opposite" datetime="2025-11">November 2025</time>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="m16 18 6-6-6-6M8 6l-6 6 6 6"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">First components</h3>
<p class="timeline-description">Buttons, inputs, dialogs and tabs, styled with Tailwind v4.</p>
</div>
<time class="timeline-opposite" datetime="2026-01">January 2026</time>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2zM22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Docs site</h3>
<p class="timeline-description">Built with its own engine, with search and versioned docs.</p>
</div>
<time class="timeline-opposite" datetime="2026-04">April 2026</time>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"/></svg></span>
<div class="timeline-content">
<h3 class="timeline-title">Version 1.0</h3>
<p class="timeline-description">Stable, with a scaffolder for bun, npm, pnpm and yarn.</p>
</div>
<time class="timeline-opposite" datetime="2026-10">October 2026</time>
</li>
</ol>
Horizontal#
.timeline-horizontal lays the items out in a row, each at least --timeline-min (10rem) wide,
scrolling sideways when they don't fit. A .timeline-opposite goes above the line.
-
Week 1
Plan
Scope and estimates
-
Week 2
Design
Mockups signed off
-
Weeks 3–5
Build
In progress
-
Week 6
Launch
<ol class="timeline timeline-horizontal w-full">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Plan</h3><p class="timeline-description">Scope and estimates</p></div>
<span class="timeline-opposite">Week 1</span>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Design</h3><p class="timeline-description">Mockups signed off</p></div>
<span class="timeline-opposite">Week 2</span>
</li>
<li class="timeline-item" aria-current="step">
<span class="timeline-marker timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="m16 18 6-6-6-6M8 6l-6 6 6 6"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Build</h3><p class="timeline-description">In progress</p></div>
<span class="timeline-opposite">Weeks 3–5</span>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-outline"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title text-muted-foreground">Launch</h3></div>
<span class="timeline-opposite">Week 6</span>
</li>
</ol>
With .timeline-alternate, horizontal items go above and below the line in turn. The markers stay in one row whatever sits above them.
-
Kick-off
-
Alpha
Internal testing
-
Beta
-
Release candidate
Feature freeze
-
1.0
<ol class="timeline timeline-horizontal timeline-alternate w-full">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"></span>
<div class="timeline-content"><time class="timeline-time" datetime="2026-01">Jan</time><h3 class="timeline-title">Kick-off</h3></div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"></span>
<div class="timeline-content"><time class="timeline-time" datetime="2026-03">Mar</time><h3 class="timeline-title">Alpha</h3><p class="timeline-description">Internal testing</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"></span>
<div class="timeline-content"><time class="timeline-time" datetime="2026-05">May</time><h3 class="timeline-title">Beta</h3></div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"></span>
<div class="timeline-content"><time class="timeline-time" datetime="2026-08">Aug</time><h3 class="timeline-title">Release candidate</h3><p class="timeline-description">Feature freeze</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker timeline-marker-success"></span>
<div class="timeline-content"><time class="timeline-time" datetime="2026-10">Oct</time><h3 class="timeline-title">1.0</h3></div>
</li>
</ol>
Line style#
.timeline-dashed and .timeline-dotted change the line, vertical or horizontal.
Dashed
Second
Third
Dotted
Second
Third
<ol class="timeline timeline-dashed">
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline"></span><div class="timeline-content"><p class="timeline-title">Dashed</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline"></span><div class="timeline-content"><p class="timeline-title">Second</p></div></li>
<li class="timeline-item"><span class="timeline-marker timeline-marker-outline"></span><div class="timeline-content"><p class="timeline-title">Third</p></div></li>
</ol>
<ol class="timeline timeline-dotted">
<li class="timeline-item"><span class="timeline-marker"></span><div class="timeline-content"><p class="timeline-title">Dotted</p></div></li>
<li class="timeline-item"><span class="timeline-marker"></span><div class="timeline-content"><p class="timeline-title">Second</p></div></li>
<li class="timeline-item"><span class="timeline-marker"></span><div class="timeline-content"><p class="timeline-title">Third</p></div></li>
</ol>
Sizes#
.timeline-sm and .timeline-lg scale the markers, the text and the spacing together.
-
Small
Signed up
-
Email sent
Welcome
-
Profile
Completed
-
Default
Signed up
-
Email sent
Welcome
-
Profile
Completed
-
Large
Signed up
-
Email sent
Welcome
-
Profile
Completed
<ol class="timeline timeline-sm">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Small</h3><p class="timeline-description">Signed up</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Email sent</h3><p class="timeline-description">Welcome</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Profile</h3><p class="timeline-description">Completed</p></div>
</li>
</ol>
<ol class="timeline">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Default</h3><p class="timeline-description">Signed up</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Email sent</h3><p class="timeline-description">Welcome</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Profile</h3><p class="timeline-description">Completed</p></div>
</li>
</ol>
<ol class="timeline timeline-lg">
<li class="timeline-item">
<span class="timeline-marker timeline-marker-primary"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Large</h3><p class="timeline-description">Signed up</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Email sent</h3><p class="timeline-description">Welcome</p></div>
</li>
<li class="timeline-item">
<span class="timeline-marker"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></span>
<div class="timeline-content"><h3 class="timeline-title">Profile</h3><p class="timeline-description">Completed</p></div>
</li>
</ol>
With htmx#
A timeline is a list, so loading more events is appending items. Here a button at the end fetches the next page and
replaces itself with it (hx-swap="outerHTML"), the response being more
<li class="timeline-item">s and a new button:
<ol class="timeline">
<li class="timeline-item">…</li>
<li class="timeline-item">
<span class="timeline-marker"></span>
<div class="timeline-content">
<button class="btn btn-outline btn-sm" hx-get="/activity?page=2"
hx-target="closest li" hx-swap="outerHTML">Load older</button>
</div>
</li>
</ol>
Customising#
Every measurement is a custom property on .timeline; set them with Tailwind's arbitrary properties or your own CSS.
| Property | Description |
|---|---|
--timeline-dot | Dot size (0.75rem). |
--timeline-icon | Circle size for icon, text and image markers (2rem). |
--timeline-line | Line thickness (2px). |
--timeline-gap | Between the marker and the content (0.75rem). |
--timeline-space | Between items (1.5rem). |
--timeline-opposite | Width of the .timeline-opposite column, vertical (6rem). |
--timeline-min | Narrowest item, horizontal (10rem). |
Reference#
| Class / attribute | Description |
|---|---|
.timeline | The list: an <ol>. |
.timeline-item | One event: an <li>. aria-current="step" rings its marker. |
.timeline-marker | Empty: a dot. With an icon, text or image: a circle. |
.timeline-marker-primary / -success / -warning / -danger / -info | Marker colours. |
.timeline-marker-outline | A hollow marker, in its colour. |
.timeline-content | The event: .timeline-time, .timeline-title, .timeline-description, or anything. |
.timeline-opposite | Across the line from the content. |
.timeline-alternate | Items on both sides of the line in turn. |
.timeline-horizontal | Items in a row. |
.timeline-dashed / .timeline-dotted | Line style. |
.timeline-sm / .timeline-lg | Sizes. |