# Uptime bar

A strip of days, one bar each, colored by whether a site or service was up, had an incident or was down, with the share up in words.

Block: `smbk-uptime-bar`. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Desktop and mobile: differ by presentation only.

## Options

| Axis | Values | Default | Meaning |
|---|---|---|---|

Parts: `smbk-uptime-bar__bars`, `smbk-uptime-bar__bar`, `smbk-uptime-bar__caption`, `smbk-uptime-bar__start`, `smbk-uptime-bar__uptime`, `smbk-uptime-bar__end`, `smbk-uptime-bar__hidden`

## Markup

```html
<div class="smbk-uptime-bar">
  <div class="smbk-uptime-bar__bars" aria-hidden="true">
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 15: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 16: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 17: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 18: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 19: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 20: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 21: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 22: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 23: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 24: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 25: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 26: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 27: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 28: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 29: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Sep 30: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 1: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 2: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 3: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 4: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 5: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 6: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 7: Up"></span>
    <span
      class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-incident"
      title="Oct 8: Incident"
    ></span>
    <span
      class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-incident"
      title="Oct 9: Incident"
    ></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 10: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 11: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 12: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 13: Up"></span>
    <span class="smbk-uptime-bar__bar smbk-uptime-bar__bar--status-up" title="Oct 14: Up"></span>
  </div>
  <p class="smbk-uptime-bar__caption" aria-hidden="true">
    <span class="smbk-uptime-bar__start">30 days ago</span>
    <span class="smbk-uptime-bar__uptime">99.9% up</span>
    <span class="smbk-uptime-bar__end">Today</span>
  </p>
  <p class="smbk-uptime-bar__hidden">30 days ago to Today: 99.9% up. Incident: Oct 8, Oct 9.</p>
</div>
```

## React

```tsx
import { UptimeBar } from './design-system/components/uptime-bar/uptime-bar.js';

<UptimeBar periods={[{ status: "up", label: "Sep 15" }, { status: "up", label: "Sep 16" }, { status: "up", label: "Sep 17" }, { status: "up", label: "Sep 18" }, { status: "up", label: "Sep 19" }, { status: "up", label: "Sep 20" }, { status: "up", label: "Sep 21" }, { status: "up", label: "Sep 22" }, { status: "up", label: "Sep 23" }, { status: "up", label: "Sep 24" }, { status: "up", label: "Sep 25" }, { status: "up", label: "Sep 26" }, { status: "up", label: "Sep 27" }, { status: "up", label: "Sep 28" }, { status: "up", label: "Sep 29" }, { status: "up", label: "Sep 30" }, { status: "up", label: "Oct 1" }, { status: "up", label: "Oct 2" }, { status: "up", label: "Oct 3" }, { status: "up", label: "Oct 4" }, { status: "up", label: "Oct 5" }, { status: "up", label: "Oct 6" }, { status: "up", label: "Oct 7" }, { status: "incident", label: "Oct 8" }, { status: "incident", label: "Oct 9" }, { status: "up", label: "Oct 10" }, { status: "up", label: "Oct 11" }, { status: "up", label: "Oct 12" }, { status: "up", label: "Oct 13" }, { status: "up", label: "Oct 14" }]} start="30 days ago" end="Today" uptime="99.9% up" caption />
```

## Stylesheet

```css
/* smbk-uptime-bar — Uptime bar. Figma "Uptime bar" 7580:263.
 * A row of bars of equal width, one per period, as tall as a small control and close together, each in the
 * color of its status: success for up, warning for an incident, danger for an outage. Under it, a caption with
 * the start at the left, the share up in the middle and the end at the right. The words carry the meaning:
 * a screen reader hears a summary with the periods that were not up, and the caption gives the share up. */

.smbk-uptime-bar {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-xs);
  min-width: 0;
}

/* The block frames the words it hides for screen readers, so they stay inside it wherever it is placed: without a
   frame they hang from the page itself and stretch it, past the end of an area that scrolls. No weight, so a parent
   that places the block keeps its say. */
:where(.smbk-uptime-bar) {
  position: relative;
}

.smbk-uptime-bar__bars {
  display: flex;
  gap: var(--smbk-space-2);
  height: var(--smbk-size-28);
}

.smbk-uptime-bar__bar {
  flex: 1 1 0;
  min-width: 0;
  border-radius: var(--smbk-radius-2);
  background: var(--smbk-color-feedback-success-icon);
}

.smbk-uptime-bar__bar--status-incident { background: var(--smbk-color-feedback-warning-icon); }
.smbk-uptime-bar__bar--status-outage { background: var(--smbk-color-feedback-danger-icon); }

.smbk-uptime-bar__caption {
  display: flex;
  justify-content: space-between;
  gap: var(--smbk-space-inline-md);
  margin: 0;
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-xs-font-family);
  font-size: var(--smbk-typography-body-xs-font-size);
  font-weight: var(--smbk-typography-body-xs-font-weight);
  line-height: var(--smbk-typography-body-xs-line-height);
  letter-spacing: var(--smbk-typography-body-xs-letter-spacing);
  text-transform: var(--smbk-typography-body-xs-text-transform);
}

.smbk-uptime-bar__uptime {
  font-variant-numeric: tabular-nums;
}

/* The summary, for screen readers only. */
/* .smbk-uptime-bar__hidden: hidden from view, kept for screen readers and the keyboard, by the shared rule in visually-hidden/visually-hidden.css. */

/* ---- high contrast (forced colors) ---- */
/* The bars keep their status colors; the summary and the caption say the same in words. */

@media (forced-colors: active) {
  .smbk-uptime-bar__bar {
    forced-color-adjust: none;
  }
}
```

## Tokens it reads

```json
{
  "space": {
    "2": {
      "$type": "dimension",
      "$value": "2px",
      "$description": "Raw space step, 2 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline."
    },
    "stack": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things stacked one above another, extra small."
      }
    },
    "inline": {
      "md": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Gap between things side by side, medium."
      }
    }
  },
  "size": {
    "28": {
      "$type": "dimension",
      "$value": "28px",
      "$description": "Raw size step, 28 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here."
    }
  },
  "radius": {
    "2": {
      "$type": "dimension",
      "$value": "2px",
      "$description": "Raw corner step, 2 px. Semantic corners (radius/control, container) point here."
    }
  },
  "color": {
    "feedback": {
      "success": {
        "icon": {
          "$type": "color",
          "$value": "{{color.green.600}}",
          "$description": "The success tone’s own icon (a check), so the tone is never shown by colour alone."
        }
      },
      "warning": {
        "icon": {
          "$type": "color",
          "$value": "{{color.orange.600}}",
          "$description": "The warning tone’s own icon (a warning sign), so the tone is never shown by colour alone."
        }
      },
      "danger": {
        "icon": {
          "$type": "color",
          "$value": "{{color.red.600}}",
          "$description": "The danger tone’s own icon (an alert sign), so the tone is never shown by colour alone."
        }
      }
    },
    "text": {
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Secondary text: descriptions, metadata."
      }
    }
  },
  "typography": {
    "body-xs": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "12px",
        "fontWeight": 400,
        "lineHeight": 1.5,
        "letterSpacing": "0px"
      }
    }
  }
}
```

## Purpose

Shows how a site or a service did over a stretch of time, a bar for each day or hour: up the whole time, an incident when it was slow or partly down, or an outage when it was down. A caption under it gives the start, the share of time up and the end. It answers "has this been reliable?" at a glance; the words answer it exactly.

## Anatomy

- The block, as wide as the space it is given.
- The bars part, a row of bar parts of equal width, one per period, oldest at the left. Each bar's status is a modifier of the part: up, incident or outage, in the success, warning and danger colors.
- The caption part: the start part at the left, the uptime part, the share up, in the middle, and the end part at the right.
- The hidden part: the summary a screen reader hears instead of the bars.

## When to use

- On a status page or a card for a site or a service, for the last 30 days or 24 hours.
- Several services one under another, each with its own uptime bar over the same days.

## When not to use

- To show how something is now. Use a [badge](badge.md).
- For a measure that is not up or down, such as response times. Use a [line chart](line-chart.md).

## Behavior

The bars share the width equally, whatever their number. The caption is optional; without it the bars stand alone and a screen reader still hears the summary. Pointing at a bar shows the browser's own tooltip, with its period and how it went (up, incident or outage); hand-written markup puts the same words in a `title` on the bar. Nothing moves and nothing takes focus.

## Accessibility
### What it does for you

- The bars and the caption are hidden from screen readers, which hear one summary instead: the start, the end and the share up, then the periods with an incident and those with an outage, named by their labels.
- The share up is in words under the bars, so the colors are never the only way to tell how it went.
- Nothing about it takes focus.
- In high contrast mode the bars keep their colors; the summary says the same in words.

### What you must do

- Give each period a label a reader understands, such as "Oct 12".
- A page can write its own summary where the default does not fit.
- In markup written by hand, put the summary in the hidden part and hide the bars and the caption.

### How to test

- With a screen reader, the bars and the caption are skipped and one summary is read: the start, the end, the share up, and the periods with an incident or an outage by their labels. Without a caption, the summary is still read.
- Tab through the page: focus never lands on the uptime bar.
- In a forced-color mode, the bars keep their colors and the summary says the same in words.

## Usage rules

### Do

- Say what it measures above it, such as "Website uptime".
- Give the share up with the precision that matters, such as "99.9% up".
- Give the same span to every uptime bar on a page.

### Don't

- Rely on the red and amber bars to say what went wrong. Say it in words where the reader can act on it.
- Show more bars than fit at two pixels each; show hours for a day and days for a month.
