Air Quality Index Gauge — Free EPA AQI Semicircle Gauge

Air Quality Index Gauge · Charts · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Real EPA breakpoints
50/100/150/200/300 — the actual AQI category boundaries.
Standard AQI colors
Green through maroon, matching official EPA category colors.
Six-arc SVG gauge
Each band drawn as its own proportionally sized colored arc.
Animated needle sweep
Spring-eased rotation across the full 0–500 semicircle.
Per-band health advisory
Real short-form guidance text for each category.
Slider and presets
Drag freely or jump to one value per band instantly.
Single source of truth
One BANDS table drives color, label, angle, and advisory.
Zero dependencies
Pure SVG and CSS, no charting library.

About this UI Snippet

Air Quality Index Gauge — Real EPA Breakpoints, Colors, and Advisories

Screenshot of the Air Quality Index Gauge snippet rendered live

This gauge uses the actual US EPA Air Quality Index scale — the same six categories, breakpoints, and colors published in the EPA's AQI technical documentation — not an invented 0-100 approximation. Drag the slider or click a preset and every part of the UI (needle angle, readout color, band name, health advisory) derives from the same real breakpoint table.

The real EPA breakpoints

The BANDS array encodes the actual six AQI categories: Good (0-50, green #22c55e), Moderate (51-100, yellow #eab308), Unhealthy for Sensitive Groups (101-150, orange #f97316), Unhealthy (151-200, red #ef4444), Very Unhealthy (201-300, purple #a855f7), and Hazardous (301+, maroon #7f1d1d). bandFor(aqi) walks the table and returns the first band whose max the value doesn't exceed — the same lookup logic any real AQI display uses, just applied to a value you control with a slider instead of a live sensor feed.

One SVG arc, six colored segments

The gauge is a single semicircular SVG built from six separate <path> arcs, each stroked in its band's exact color and sized proportionally to that band's real point range — the Good segment is visually narrower than Hazardous's open-ended range gets represented as a fixed final wedge, matching how AQI scales are conventionally drawn. A single needle <line> rotates from -90° (0 AQI) to +90° (500 AQI) via transform: rotate(), animated with a spring-like cubic-bezier transition so moving the slider sweeps the needle smoothly across the full 500-point scale.

A health advisory per band, not just a color

Each band carries the real short-form advisory language associated with that AQI category — from "little or no risk" at Good to "everyone is more likely to be affected" at Hazardous — so the gauge communicates what the number actually means, not just what color it is. Pair this with a weather widget or weather forecast card for a complete environmental conditions dashboard.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to verify the AQI breakpoint values and colors against the EPA's official AQI technical documentation, and to explain how the needle's rotation formula ((aqi / 500) * 180 - 90) maps the 0-500 AQI scale onto a 180-degree semicircle. It's also useful for reasoning about the gauge construction — ask why each band is drawn as a separate SVG arc segment rather than one continuous gradient stroke, and what tradeoffs that makes for getting hard color boundaries exactly at the real breakpoints versus a smoother but less accurate gradient. For extensions, ask it to wire the gauge up to a real air-quality API (like AirNow or OpenWeatherMap's air pollution endpoint) with polling, add a small history sparkline beneath the gauge showing the last 24 hours, or add a second gauge for PM2.5 concentration alongside the overall AQI. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an "air quality index gauge" in plain HTML, CSS, and JavaScript (inline SVG, no charting library) using the real US EPA Air Quality Index scale.

Requirements:
- Use the actual EPA AQI breakpoints and standard category colors: Good 0-50 (green), Moderate 51-100 (yellow), Unhealthy for Sensitive Groups 101-150 (orange), Unhealthy 151-200 (red), Very Unhealthy 201-300 (purple), Hazardous 301+ (maroon). Get these boundaries and colors exactly right — do not invent different thresholds.
- Render a semicircular gauge as inline SVG, built from six separate arc <path> elements (one per band) each stroked in its band's real color, sized proportionally to that band's point range within the 0-500 scale the gauge represents.
- A single needle line element that rotates via a CSS transform: rotate() to point at the current AQI value, mapped linearly across the semicircle (0 AQI at one end, 500 AQI at the other), animated with a smooth easing transition whenever the value changes.
- A range slider (0-500) that updates the AQI value live as it's dragged, plus a row of preset buttons that jump directly to a representative value within each of the six bands.
- A big numeric AQI readout and a text label showing the current band name, both colored to match the active band, plus a short health advisory paragraph beneath the gauge that changes to that band's real short-form EPA guidance text (e.g. "little or no risk" for Good, up through "everyone is more likely to be affected" for Hazardous).
- Structure the code so a single function (e.g. update(aqiValue)) is the one place that looks up the correct band from an AQI value and updates the needle angle, readout color, band label, and advisory text — so the same function could later be driven by a live air-quality API instead of the slider.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSThe gauge renders at AQI 42 — Good.
  2. 2
    Drag the sliderThe needle sweeps and the readout updates live, 0–500.
  3. 3
    Click a presetJump straight to a representative value for each band.
  4. 4
    Read the advisoryThe health message below updates per real EPA band.
  5. 5
    Cross the 50/100/150/200/300 marksWatch the color and band name change at the real breakpoints.
  6. 6
    Wire up live dataReplace the slider with a call to update(aqi) from an air-quality API.

Real-world uses

Common Use Cases

Weather dashboards
Pair with a weather widget.
Environmental monitoring apps
Show live sensor AQI with the real color scale.
Smart home displays
An air-purifier or HVAC dashboard tile.
Travel/outdoor activity apps
Advise users before outdoor plans.
Public health dashboards
Municipal or regional air-quality reporting.
City/government portals
Pair with weather forecast for a conditions page.

Got questions?

Frequently Asked Questions

Yes. The BANDS table uses the real US EPA Air Quality Index breakpoints: Good 0-50, Moderate 51-100, Unhealthy for Sensitive Groups 101-150, Unhealthy 151-200, Very Unhealthy 201-300, and Hazardous 301 and above, matching the EPA's published AQI technical documentation. The colors (green, yellow, orange, red, purple, maroon) match the official category colors used on EPA and AirNow reporting.

The gauge sweeps a 180-degree semicircle, so the needle's rotation angle is (aqi / 500) * 180 - 90, mapping AQI 0 to -90 degrees (pointing left) and AQI 500 to +90 degrees (pointing right). A CSS transition with a spring-like cubic-bezier easing animates the rotation whenever the underlying value changes, whether from the slider or a preset button.

AQI values technically extend past 500 in extreme cases, but 500 is the top of the standard reporting scale used by the EPA and AirNow, and the slider and gauge are capped there (values are clamped with Math.max/Math.min). The Hazardous arc represents 301-500 on the gauge, consistent with how the scale is conventionally visualized even though real-world Hazardous readings can occasionally exceed 500.

Yes — the slider and preset buttons are just two ways of calling the same update(aqi) function, which handles clamping the value, finding the right band, and updating the needle angle, readout, and advisory text. Call update(currentAqiFromYourApi) on whatever interval your air-quality data source refreshes, and remove or hide the slider if you don't want manual control.

Keep the numeric AQI value in component state, derive the active band by running the same breakpoint lookup against it, and bind the needle's rotate() transform, the readout color, and the advisory text to that derived band — the SVG arcs themselves are static and never need to re-render, only the needle's transform attribute and a few text/color bindings change.