webdevpuneet.com

Uptime Status Page — Service History Bars HTML CSS

Uptime Status Page · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

<div class="usp-card">
  <div class="usp-head">
    <div class="usp-overall" id="uspOverall">
      <span class="usp-overall-dot"></span>
      <span id="uspOverallText">All systems operational</span>
    </div>
    <span class="usp-updated">Updated just now</span>
  </div>

  <div class="usp-services" id="uspServices"></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

90-day history bars per service
Each service shows a full quarter of daily status as individual colored bars, generated from data rather than images.
Zero-JS hover tooltips
A CSS ::after pseudo-element reads each bar's data-tip attribute, avoiding a tooltip library for 90+ elements per service.
Self-consistent uptime percentage
The displayed uptime % is computed by counting the same bars shown visually, so the number and the graphic can never disagree.
Aggregated worst-status banner
The overall banner reflects the single worst service status present, with matching color and message severity.
Live-status-consistent history
The most recent history bar always matches the service's actual current status, even though earlier days are randomized.
Three-tier status system
Operational, degraded, and outage each get a distinct color used consistently across the dot, label, bars, and banner.
Compact, scan-friendly layout
Service name, current status, history, and uptime percentage all fit in a few rows per service for fast scanning.
Data-driven service list
Adding, removing, or renaming a service is a one-line change to the SERVICES array — no markup duplication required.

About this UI Snippet

Uptime Status Page — 90-Day History Bars, Hover Tooltips & Aggregated Status

Screenshot of the Uptime Status Page snippet rendered live

A public status page exists to answer one question fast — "is it just me, or is the whole service down?" — and the format every major status page (Statuspage, Better Uptime, Cachet) converges on is the same: a banner summarizing overall health, and a row of tiny colored bars per service showing recent history at a glance. This snippet builds that exact pattern in plain HTML, CSS, and vanilla JavaScript.

History bars as data, not images

Each service renders 90 thin <div> bars in a flex row, one per day, colored green/amber/red for operational/degraded/outage. genHistory() generates a randomized history that's mostly green with rare amber and red days, and the *last* bar always reflects the service's actual current status — so the simulated history stays consistent with the live status shown in the row above it. Replace genHistory() with real incident data and the rendering needs no changes.

Hover tooltips without a tooltip library

Each bar carries its day-relative label and status in a data-tip attribute, and a pure-CSS ::after pseudo-element reads it via content: attr(data-tip) on hover — no JavaScript positioning logic and no extra DOM nodes per bar, which matters here since there are 90 bars × however many services. This is the same zero-JS tooltip technique used for lightweight hint text throughout this library.

Uptime percentage, computed from the bars themselves

uptimePct() doesn't take a separate "99.9% uptime" number from anywhere — it counts how many of the 90 generated bars are operational and divides by the total. This guarantees the displayed percentage and the visual bar row can never contradict each other, which is a real bug class in hand-maintained status pages where the number and the history graphic are updated separately and drift apart.

Aggregated overall status

The top banner doesn't just say "operational" by default — updateOverall() reduces every service's status to find the *worst* one present (outage beats degraded beats operational) and reflects that exact severity in both the banner's color and its message. A single degraded service is enough to turn the whole banner amber; a single outage turns it red — exactly how users expect "is everything okay?" to be answered.

Why a status page exists separately from internal monitoring

Internal dashboards (Grafana, Datadog) are built for engineers diagnosing a problem; a public status page is built for everyone else asking one question fast. Keeping it as its own simple, low-dependency page — rather than exposing the internal monitoring tool directly — also means it can stay up and informative even during an incident that's affecting other parts of the infrastructure, which is exactly the moment a status page matters most.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA status page renders with an overall banner and five services, each with a row of 90 colored history bars.
  2. 2
    Read the overall bannerIts color and message reflect the single worst status across every service — amber for any degraded service, red for any outage.
  3. 3
    Hover a history barA tooltip shows that day's relative date and status (e.g. "12d ago · Operational") without any extra markup per bar.
  4. 4
    Check the uptime percentageEach service's footer shows a percentage computed directly from its own visible 90-day bar history.
  5. 5
    Edit the servicesChange any entry's name or status in SERVICES, then call buildServices() to regenerate the whole page including the overall banner.
  6. 6
    Connect real incident dataReplace genHistory()'s random generator with your actual per-day status history fetched from an incident/monitoring API.

Real-world uses

Common Use Cases

SaaS and API status pages
The standard public-facing status.yourcompany.com page showing real-time and historical service health.
Internal infrastructure dashboards
Show on-call engineers a quick visual history of which internal services have been flaky recently.
Incident communication pages
Pair with a changelog feed to show both current status and a written incident history.
Multi-region service health
Use each "service" row to represent a region or data center instead of a product feature.
Vendor and dependency monitoring
Track the uptime of third-party APIs and services your product depends on in one consolidated view.
Learning data-driven dashboards
A clear example of deriving every displayed number and color from the same underlying array — compare with a status dashboard for a metric-tile variant.

Got questions?

Frequently Asked Questions

Replace genHistory()'s random-status loop with a fetch to your monitoring or incident-management API, mapping each returned day to 'operational', 'degraded', or 'outage'; keep the same array shape so buildServices() and uptimePct() need no other changes.

For days with a 'degraded' or 'outage' status, attach an incident summary string and render a list of those summaries (with dates) beneath the bar row or in a separate "Past incidents" section, linking each entry back to the relevant day.

Change the DAYS constant — genHistory(), the bar rendering, and uptimePct() all derive their loop length and percentage calculation from that single value.

Wrap a fetch-and-rebuild call in setInterval (e.g. every 60 seconds), updating each service's live status from your API before calling buildServices() again, and update the "Updated just now" label with the current timestamp.

In React, keep services in state and derive history/uptime with useMemo per service, rendering bars with .map(); in Vue, use a computed services array with nested v-for; in Angular, use *ngFor with a pipe for the uptime percentage. The worst-status reduction for the overall banner ports directly into each framework.