Steps & timeline

Where you are in a sequence, and - turned vertical - what has already happened. One component: a timeline is a stepper where every step is done.

Reference

sk-steps

An ordered list, because the order is the meaning: "3 of 5" comes out of the markup rather than out of a number someone remembered to type into the label. The state is never carried by colour alone - a done step draws a check, the current one is heavier and ringed, and a future one shows its number - so the sequence still reads in greyscale, which is the situation a screenshot or a printed receipt is in.

<ol class="sk-steps" aria-label="Checkout">
  <li class="sk-step" data-state="done">
    <span class="sk-step-marker" aria-hidden="true">…</span>
    <span class="sk-step-content">…</span>
  </li>
  <li class="sk-step" data-state="current" aria-current="step">…</li>
  <li class="sk-step">…</li>
</ol>
AttributeTypeDefaultNotes
data-state"done" | "current"todoA done step also fills the connector to the next one, which is what makes the row read as a progress bar with stops.
aria-current"step"-On the current step. Same attribute as the sidebar and the tabs, with "step" instead of "page".
data-orientation"vertical"horizontalThe timeline. Same markup, same connector rule, stacked.
sk-step-markerwrapper-aria-hidden: the number is position, which the list already announces, and the check is the state, which data-state and the title already carry.

Examples

Stepper

Narrow the preview past 40rem: the labels come off and the markers stay, except on the current step. "3 of 5" and which are done is most of the value.

  1. Cart
  2. Delivery
  3. Payment
  4. Confirm
  1. Account Name and email
  2. Workspace Invite your team
  3. First project Import or start fresh
Show markup
<div class="sk-flex sk-flex-col sk-gap-7">
  <ol class="sk-steps" aria-label="Checkout">
    <li class="sk-step" data-state="done">
      <span class="sk-step-marker" aria-hidden="true">
        <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M20 6 9 17l-5-5">
          </path>
        </svg>
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          Cart
        </span>
      </span>
    </li>
    <li class="sk-step" data-state="done">
      <span class="sk-step-marker" aria-hidden="true">
        <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M20 6 9 17l-5-5">
          </path>
        </svg>
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          Delivery
        </span>
      </span>
    </li>
    <li class="sk-step" data-state="current" aria-current="step">
      <span class="sk-step-marker" aria-hidden="true">
        3
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          Payment
        </span>
      </span>
    </li>
    <li class="sk-step">
      <span class="sk-step-marker" aria-hidden="true">
        4
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          Confirm
        </span>
      </span>
    </li>
  </ol>
  <ol class="sk-steps" aria-label="Onboarding">
    <li class="sk-step" data-state="done">
      <span class="sk-step-marker" aria-hidden="true">
        <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M20 6 9 17l-5-5">
          </path>
        </svg>
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          Account
        </span>
        <span class="sk-step-note">
          Name and email
        </span>
      </span>
    </li>
    <li class="sk-step" data-state="current" aria-current="step">
      <span class="sk-step-marker" aria-hidden="true">
        2
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          Workspace
        </span>
        <span class="sk-step-note">
          Invite your team
        </span>
      </span>
    </li>
    <li class="sk-step">
      <span class="sk-step-marker" aria-hidden="true">
        3
      </span>
      <span class="sk-step-content">
        <span class="sk-step-title">
          First project
        </span>
        <span class="sk-step-note">
          Import or start fresh
        </span>
      </span>
    </li>
  </ol>
</div>

Timeline

Vertical, everything done. The note becomes the timestamp.

  1. Queued 09:41
  2. Dependencies restored 09:41 - 18s
  3. Tests passed 09:42 - 3m 04s
  4. Deploying 09:45
  5. Live
Show markup
<ol class="sk-steps" data-orientation="vertical" aria-label="Build 412">
  <li class="sk-step" data-state="done">
    <span class="sk-step-marker" aria-hidden="true">
      <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M20 6 9 17l-5-5">
        </path>
      </svg>
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Queued
      </span>
      <span class="sk-step-note">
        09:41
      </span>
    </span>
  </li>
  <li class="sk-step" data-state="done">
    <span class="sk-step-marker" aria-hidden="true">
      <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M20 6 9 17l-5-5">
        </path>
      </svg>
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Dependencies restored
      </span>
      <span class="sk-step-note">
        09:41 - 18s
      </span>
    </span>
  </li>
  <li class="sk-step" data-state="done">
    <span class="sk-step-marker" aria-hidden="true">
      <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M20 6 9 17l-5-5">
        </path>
      </svg>
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Tests passed
      </span>
      <span class="sk-step-note">
        09:42 - 3m 04s
      </span>
    </span>
  </li>
  <li class="sk-step" data-state="current" aria-current="step">
    <span class="sk-step-marker" aria-hidden="true">
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Deploying
      </span>
      <span class="sk-step-note">
        09:45
      </span>
    </span>
  </li>
  <li class="sk-step">
    <span class="sk-step-marker" aria-hidden="true">
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Live
      </span>
    </span>
  </li>
</ol>

Failed run

The state vocabulary stops at done and current on purpose - a failed step is a Dot or a Badge in the step's own content, because "failed" is about the thing that ran, not about where the reader is in the list.

  1. Build 1m 02s
  2. Test
  3. Deploy
Show markup
<ol class="sk-steps" data-orientation="vertical" aria-label="Pipeline">
  <li class="sk-step" data-state="done">
    <span class="sk-step-marker" aria-hidden="true">
      <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M20 6 9 17l-5-5">
        </path>
      </svg>
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Build
      </span>
      <span class="sk-step-note">
        1m 02s
      </span>
    </span>
  </li>
  <li class="sk-step" data-state="current" aria-current="step">
    <span class="sk-step-marker" aria-hidden="true">
      <svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path d="M18 6 6 18">
        </path>
        <path d="m6 6 12 12">
        </path>
      </svg>
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Test
      </span>
    </span>
  </li>
  <li class="sk-step">
    <span class="sk-step-marker" aria-hidden="true">
    </span>
    <span class="sk-step-content">
      <span class="sk-step-title">
        Deploy
      </span>
    </span>
  </li>
</ol>