The pearl chain displays a journey as a chain of points connected by lines. Each point represents a stop. It shows the progress of the journey with the current position, as well as disruptions, walking sections and uncertain sections. It can be used horizontally or vertically.
This component consists of a main element and its parts. Use the parts only within the element they belong to.
sbb-pearl-chain Parts – only within sbb-pearl-chain:
sbb-pearl-chain-node
The <sbb-pearl-chain> component visualizes a journey as a chain of points connected by lines, typically used to
display the stops of a public-transport connection along with its progress.
Place a <sbb-pearl-chain-node> for every stop of the journey inside the <sbb-pearl-chain>, in the order they
occur. <sbb-pearl-chain> connects them with lines automatically, following the DOM order.
Consumers can slot the nodes alongside any other content (times, station names, icons, ...) and lay everything out
however they prefer (e.g. table, flexbox, css-grid). The <sbb-pearl-chain> will draw the lines that connect the nodes.
<!-- Example of a horizontal layout using a flex container-->
<sbb-pearl-chain>
<div style="display: flex;">
<sbb-pearl-chain-node type="start"></sbb-pearl-chain-node>
<span style="flex: 1;"></span>
<sbb-pearl-chain-node type="stop"></sbb-pearl-chain-node>
<span style="flex: 1;"></span>
<sbb-pearl-chain-node type="end"></sbb-pearl-chain-node>
</div>
</sbb-pearl-chain>
<!-- Example of a vertical layout using a table -->
<sbb-pearl-chain>
<table>
<tr>
<td>
<time datetime="2026-04-10T10:00:00">
<span class="sbb-screen-reader-only">Departure: </span>10:00
</time>
</td>
<td>
<sbb-pearl-chain-node type="start" departure="..."></sbb-pearl-chain-node>
</td>
<td>Bern</td>
</tr>
<tr>
<td>
<time datetime="2026-04-10T12:00:00">
<span class="sbb-screen-reader-only">Departure: </span>12:00
</time>
</td>
<td>
<sbb-pearl-chain-node type="stop" arrival="..." departure="..."></sbb-pearl-chain-node>
</td>
<td>Olten</td>
</tr>
<tr>
<td>
<time datetime="2026-04-10T15:00:00">
<span class="sbb-screen-reader-only">Arrival: </span>15:00
</time>
</td>
<td>
<sbb-pearl-chain-node type="end" arrival="..."></sbb-pearl-chain-node>
</td>
<td>Zürich HB</td>
</tr>
</table>
</sbb-pearl-chain>
Setting arrival/departure on the <sbb-pearl-chain-node> elements allows the <sbb-pearl-chain> to display the current
progress of the journey with a pulsing dot marking the current position.
For testing or demo purposes, the current time can be overridden using the now property of <sbb-pearl-chain>.
<sbb-pearl-chain>
<sbb-pearl-chain-node type="start" departure="2026-04-10T10:30:00"></sbb-pearl-chain-node>
<sbb-pearl-chain-node
type="stop"
arrival="2026-04-10T10:50:00"
departure="2026-04-10T10:55:00"
></sbb-pearl-chain-node>
<sbb-pearl-chain-node type="end" arrival="2026-04-10T11:30:00"></sbb-pearl-chain-node>
</sbb-pearl-chain>
<sbb-pearl-chain> adapts its bullets depending on whether the nodes are laid out horizontally or vertically, so it looks correct in both horizontal and vertical layouts without any explicit configuration.
<sbb-pearl-chain> re-renders automatically when:
<sbb-pearl-chain-node> is added or removed;IntersectionObserver triggers, e.g. when the pearl-chain becomes visible.Changes that are not detected automatically (e.g. a layout change caused by a CSS property) require a manual update.
In this case, call the requestUpdate() method on the <sbb-pearl-chain> element.
document.querySelector('sbb-pearl-chain').requestUpdate();
The <sbb-pearl-chain> does not position the nodes: distributing them proportionally to the journey's duration is up to the consumer.
The calculateNodeWeights() method helps with that: it returns, for each node in DOM order, a value between 0 (first node) and 1 (last node),
proportional to its departure time (or arrival, if there is no departure).
const chain = document.querySelector('sbb-pearl-chain');
const weights = chain.calculateNodeWeights(); // e.g. [0, 0.43, 1]
<sbb-pearl-chain> and <sbb-pearl-chain-node> have no built-in accessibility: the rendered lines and bullets
are purely decorative and not exposed to assistive technology. If the information conveyed by the pearl chain
(e.g. progress, disruptions) needs to be accessible, it must be provided separately, through accessible markup e.g. via hidden text.
This component is also available for Angular in the package @sbb-esta/lyne-angular.
SbbPearlChainElement, sbb-pearl-chain.| Name | Attribute | Privacy | Type | Default | Description |
|---|---|---|---|---|---|
nodes | - | public | readonly SbbPearlChainNodeElement[] | [] | Returns the registered sbb-pearl-chain-node elements, in DOM order. |
now | now | public | Date | A configured date which acts as the current date instead of the real current date. Only recommended for testing purposes. |
| Name | Privacy | Description | Parameters | Return | Inherited From |
|---|---|---|---|---|---|
calculateNodeWeights | public | Returns the relative position (0 for the first node, 1 for the last one) of each node, in DOM order, proportional to its departure time (or arrival if there is no departure). | number[] |
SbbPearlChainNodeElement, sbb-pearl-chain-node.| Name | Attribute | Privacy | Type | Default | Description |
|---|---|---|---|---|---|
arrival | arrival | public | Date | null | null | The arrival date/time at this node. Accepts ISO 8601 datetime strings. |
departure | departure | public | Date | null | null | The departure date/time at this node. Accepts ISO 8601 datetime strings. |
disrupted | disrupted | public | 'arrival' | 'departure' | true | null | null | Marks the node as disrupted, coloring the bullet red (if rendered). |
irrelevant | irrelevant | public | 'arrival' | 'departure' | true | null | null | Marks the node as irrelevant, coloring the bullet gray (if rendered); supersedes disrupted. |
type | type | public | 'start' | 'end' | 'stop' | 'skip' | 'commercial' | 'boarding' | 'alighting' | 'exceptional' | 'exceptional-skip' | 'exceptional-boarding' | 'exceptional-alighting' | 'stop-duty' | 'stop-on-demand' | 'boarding-on-demand' | 'alighting-on-demand' | null | null | Decides how the bullet is rendered. Defaults to _empty_ (no bullet). |
unsure | unsure | public | 'arrival' | 'departure' | true | null | null | Marks the connection as unsure, rendering the line dashed. Does not affect the bullet. |
walk | walk | public | 'arrival' | 'departure' | true | null | null | Marks the node as a walk connection. Does not affect the bullet color. |