Dot

A state marker. Anywhere a row, a record or a service has a state and there is no room for a badge: a status column, a service list, a nav item with unread items, a step that is running.

Reference

sk-dot

Its colour comes from --sk-{status}-vivid, the 500 step, which exists for graphics. It used to be sk-badge[data-dot] and therefore took the badge's TEXT colour - the 700 step, darkened so small type clears 4.5:1 - which rendered warning as brown and danger as maroon.

<span class="sk-dot-row">
  <span class="sk-dot" data-status="success"></span>
  Operational
</span>
AttributeTypeDefaultNotes
data-status"info" | "success" | "warning" | "danger"neutral
data-size"sm" | "lg"md6 / 8 / 10px.
data-busy"true"-Spins a ring around the dot. Its own keyframes, not Spinner's - a spinner is an indeterminate wait, a busy dot is a state marker that happens to move, and a list of them wants to be calmer.
data-hollow"true"-A ring instead of a fill, for a state that has not started.
data-motion"essential"-Emitted with data-busy. Exempts the spin from the blanket reduced-motion reset, which would otherwise freeze it - a stopped indicator conveys nothing.
sk-dot-rowwrapper-Dot plus label, aligned and 24px tall.

Examples

Statuses

Never on its own. The vivid greens and ambers cannot clear 3:1 against white without becoming the muddy colours this replaced, so a dot always has a label beside it - visible here, visually hidden in a dense table.

Neutral - no state of its owninfosuccesswarningdanger
Show markup
<div class="sk-flex sk-flex-col sk-gap-1">
  <span class="sk-dot-row">
    <span class="sk-dot" aria-hidden="true">
    </span>
    Neutral - no state of its own
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="info" aria-hidden="true">
    </span>
    info
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="success" aria-hidden="true">
    </span>
    success
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="warning" aria-hidden="true">
    </span>
    warning
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="danger" aria-hidden="true">
    </span>
    danger
  </span>
</div>

States

Hollow for not started, amber and spinning for in flight, a fill for finished. Amber-for-running is the CI convention, and it is the same amber as warning on purpose - what separates a running job from a degraded service is the motion, not the hue, which is also why a busy dot keeps its ring rather than swapping shape.

Not startedNot startedIn progressIn progressDoneDoneFailedFailed
Show markup
<div class="sk-flex sk-flex-col sk-gap-1">
  <span class="sk-dot-row">
    <span class="sk-dot" data-hollow="true">
      <span class="sk-visually-hidden">
        Not started
      </span>
    </span>
    Not started
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="warning" data-busy="true" data-motion="essential">
      <span class="sk-visually-hidden">
        In progress
      </span>
    </span>
    In progress
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="success">
      <span class="sk-visually-hidden">
        Done
      </span>
    </span>
    Done
  </span>
  <span class="sk-dot-row">
    <span class="sk-dot" data-status="danger">
      <span class="sk-visually-hidden">
        Failed
      </span>
    </span>
    Failed
  </span>
</div>

Sizes

The ring and its stroke both scale with the dot, so the proportion holds.

sm - 6pxnot startedrunningdonedegradeddown
md - 8pxnot startedrunningdonedegradeddown
lg - 10pxnot startedrunningdonedegradeddown
Show markup
<div class="sk-flex sk-flex-col sk-gap-4">
  <div class="sk-flex sk-items-center sk-gap-5">
    <code class="sink-row-label">
      sm - 6px
    </code>
    <span class="sk-dot" data-size="sm" data-hollow="true">
      <span class="sk-visually-hidden">
        not started
      </span>
    </span>
    <span class="sk-dot" data-status="warning" data-size="sm" data-busy="true" data-motion="essential">
      <span class="sk-visually-hidden">
        running
      </span>
    </span>
    <span class="sk-dot" data-status="success" data-size="sm">
      <span class="sk-visually-hidden">
        done
      </span>
    </span>
    <span class="sk-dot" data-status="warning" data-size="sm">
      <span class="sk-visually-hidden">
        degraded
      </span>
    </span>
    <span class="sk-dot" data-status="danger" data-size="sm">
      <span class="sk-visually-hidden">
        down
      </span>
    </span>
  </div>
  <div class="sk-flex sk-items-center sk-gap-5">
    <code class="sink-row-label">
      md - 8px
    </code>
    <span class="sk-dot" data-hollow="true">
      <span class="sk-visually-hidden">
        not started
      </span>
    </span>
    <span class="sk-dot" data-status="warning" data-busy="true" data-motion="essential">
      <span class="sk-visually-hidden">
        running
      </span>
    </span>
    <span class="sk-dot" data-status="success">
      <span class="sk-visually-hidden">
        done
      </span>
    </span>
    <span class="sk-dot" data-status="warning">
      <span class="sk-visually-hidden">
        degraded
      </span>
    </span>
    <span class="sk-dot" data-status="danger">
      <span class="sk-visually-hidden">
        down
      </span>
    </span>
  </div>
  <div class="sk-flex sk-items-center sk-gap-5">
    <code class="sink-row-label">
      lg - 10px
    </code>
    <span class="sk-dot" data-size="lg" data-hollow="true">
      <span class="sk-visually-hidden">
        not started
      </span>
    </span>
    <span class="sk-dot" data-status="warning" data-size="lg" data-busy="true" data-motion="essential">
      <span class="sk-visually-hidden">
        running
      </span>
    </span>
    <span class="sk-dot" data-status="success" data-size="lg">
      <span class="sk-visually-hidden">
        done
      </span>
    </span>
    <span class="sk-dot" data-status="warning" data-size="lg">
      <span class="sk-visually-hidden">
        degraded
      </span>
    </span>
    <span class="sk-dot" data-status="danger" data-size="lg">
      <span class="sk-visually-hidden">
        down
      </span>
    </span>
  </div>
</div>

A service list

The everyday use: one state per row, in a column of its own.

OperationalAPI Operational 99.99%
OperationalWeb Operational 99.98%
DegradedSearch Degraded 97.10%
ReindexingExports Reindexing
DownWebhooks Down 84.30%
Show markup
<div class="sk-card">
  <div class="sk-card-body">
    <div class="sk-flex sk-flex-col sk-gap-3">
      <div class="sk-flex sk-items-center sk-gap-3">
        <span class="sk-dot" data-status="success">
          <span class="sk-visually-hidden">
            Operational
          </span>
        </span>
        <span class="sk-flex-1 sk-min-w-0">
          API
        </span>
        <span class="sink-caption">
          Operational
        </span>
        <span class="sink-caption sk-tabular">
          99.99%
        </span>
      </div>
      <div class="sk-flex sk-items-center sk-gap-3">
        <span class="sk-dot" data-status="success">
          <span class="sk-visually-hidden">
            Operational
          </span>
        </span>
        <span class="sk-flex-1 sk-min-w-0">
          Web
        </span>
        <span class="sink-caption">
          Operational
        </span>
        <span class="sink-caption sk-tabular">
          99.98%
        </span>
      </div>
      <div class="sk-flex sk-items-center sk-gap-3">
        <span class="sk-dot" data-status="warning">
          <span class="sk-visually-hidden">
            Degraded
          </span>
        </span>
        <span class="sk-flex-1 sk-min-w-0">
          Search
        </span>
        <span class="sink-caption">
          Degraded
        </span>
        <span class="sink-caption sk-tabular">
          97.10%
        </span>
      </div>
      <div class="sk-flex sk-items-center sk-gap-3">
        <span class="sk-dot" data-status="warning" data-busy="true" data-motion="essential">
          <span class="sk-visually-hidden">
            Reindexing
          </span>
        </span>
        <span class="sk-flex-1 sk-min-w-0">
          Exports
        </span>
        <span class="sink-caption">
          Reindexing
        </span>
      </div>
      <div class="sk-flex sk-items-center sk-gap-3">
        <span class="sk-dot" data-status="danger">
          <span class="sk-visually-hidden">
            Down
          </span>
        </span>
        <span class="sk-flex-1 sk-min-w-0">
          Webhooks
        </span>
        <span class="sink-caption">
          Down
        </span>
        <span class="sink-caption sk-tabular">
          84.30%
        </span>
      </div>
    </div>
  </div>
</div>

In a table

Dense, and the reason the dot exists at all - a badge in every row of a status column is far too loud.

Service State Uptime
API Operational 99.99%
Web Operational 99.98%
Search Degraded 97.10%
Exports Reindexing -
Webhooks Down 84.30%
Show markup
<div class="sk-table-wrap">
  <table class="sk-table" data-density="compact" data-hoverable="true">
    <thead>
      <tr>
        <th scope="col">
          Service
        </th>
        <th scope="col">
          State
        </th>
        <th scope="col" data-numeric="true">
          Uptime
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          API
        </td>
        <td>
          <span class="sk-dot-row">
            <span class="sk-dot" data-status="success" aria-hidden="true">
            </span>
            Operational
          </span>
        </td>
        <td data-numeric="true">
          99.99%
        </td>
      </tr>
      <tr>
        <td>
          Web
        </td>
        <td>
          <span class="sk-dot-row">
            <span class="sk-dot" data-status="success" aria-hidden="true">
            </span>
            Operational
          </span>
        </td>
        <td data-numeric="true">
          99.98%
        </td>
      </tr>
      <tr>
        <td>
          Search
        </td>
        <td>
          <span class="sk-dot-row">
            <span class="sk-dot" data-status="warning" aria-hidden="true">
            </span>
            Degraded
          </span>
        </td>
        <td data-numeric="true">
          97.10%
        </td>
      </tr>
      <tr>
        <td>
          Exports
        </td>
        <td>
          <span class="sk-dot-row">
            <span class="sk-dot" data-status="warning" data-busy="true" data-motion="essential" aria-hidden="true">
            </span>
            Reindexing
          </span>
        </td>
        <td data-numeric="true">
          -
        </td>
      </tr>
      <tr>
        <td>
          Webhooks
        </td>
        <td>
          <span class="sk-dot-row">
            <span class="sk-dot" data-status="danger" aria-hidden="true">
            </span>
            Down
          </span>
        </td>
        <td data-numeric="true">
          84.30%
        </td>
      </tr>
    </tbody>
  </table>
</div>

Inline with text

The dot is vertically centred on the line rather than sitting on the baseline.

The build is running and should finish shortly.

Everything else is operational.

Show markup
<div class="sk-flex sk-flex-col sk-gap-3">
  <p>
    The build is
    <span class="sk-dot-row">
      <span class="sk-dot" data-status="warning" data-busy="true" data-motion="essential" aria-hidden="true">
      </span>
      running
    </span>
    and should finish shortly.
  </p>
  <p>
    Everything else is
    <span class="sk-dot-row">
      <span class="sk-dot" data-status="success" aria-hidden="true">
      </span>
      operational
    </span>
    .
  </p>
</div>