Timeline
A sequence of events laid along a rail.
Basic
Each event is a .timeline__item holding a .timeline__marker on the rail and a .timeline__body beside it. The rail line draws itself between markers and stops at the last one. It is pure layout with no JS; status rides an author-set data-state and intent rides a .timeline__marker--* modifier. An empty marker paints a dot on the rail. Use an <ol> for the root so the order carries to screen readers.
Icon and avatar markers
Drop an icon inside a marker for a system event or an avatar for a person. Every marker is the same size, so they line up however you mix them; bump --timeline-marker-size on the root to scale them together. Avatars and images sit on the rail directly, without the tinted ring an icon marker gets.
Status
Set data-state on an item to show where it sits in a process. A complete step fills its marker and keeps the rail solid, current rings the marker and dashes the rail leaving it, and pending mutes the marker and dashes the rest.
Time at the bottom
The body is a plain stack, so the time sits wherever you place it. Lead with the title and drop .timeline__time to the last line when it reads better as a caption. The marker aligns to the first line.
Marker colors
Add a .timeline__marker--* modifier to color a marker for a fixed meaning. Color is separate from status, so a marker can carry an intent color whether or not the item has a data-state. For a one-off color, set --timeline-marker-color on the item instead.
Alternate
Add .timeline--alternate to center the rail and place events on either side of it. It needs room, so on a narrow screen it folds back to the standard left rail. Status and marker content work the same way.
Customization
These variables retune .timeline without touching component CSS. Set them on the timeline, a parent scope, or :root. The marker color also reads on a single .timeline__item, which is how the intent modifiers and a one-off override work. For a neutral activity feed, set --timeline-marker-color to var(--color-muted-foreground) on the root.
Geometry
| Variable | Use |
|---|---|
--timeline-marker-size | Marker size; every marker is a circle of this size and one value scales them all |
--timeline-dot-size | Diameter of the dot shown when a marker is empty |
--timeline-connector-width | Thickness of the rail line |
--timeline-connector-gap | Space between a marker and the line at both ends of each segment |
--timeline-connector-style | Rail line style; solid by default, the current and pending states switch it to dashed |
--timeline-gutter | Space between the rail and the event body |
--timeline-gap | Vertical space between events |
Paint
| Variable | Use |
|---|---|
--timeline-marker-color | Marker fill, dot, and tint; the intent modifiers set this and an item-level override wins for one row |
--timeline-marker-color-emphasis | Glyph colour inside a tinted marker; intents set it from --color-<intent>-emphasis for AA contrast |
--timeline-marker-ring | Ring color around a current marker |
--timeline-marker-ring-size | Static halo thickness on a current marker |
--timeline-ping-duration | How long one ping of a current marker takes; dropped under reduced motion |
--timeline-connector-color | Rail line color |