Anatomy
- 1 Label — names the measured quantity.
- 2 Value text — a percentage or a custom measurement with units.
- 3 Track — the full minimum-to-maximum range.
- 4 Fill — the normalized current measurement. A native meter carries the accessible value; the visual track is hidden from assistive technology.
Options
Variants
Variants change presentation only. The component does not calculate thresholds or infer whether a value is good or bad.
Sizes
Range and value text
Container scaling
Use the Scale switch beside Light/Dark in the preview above, or set data-scale="small|medium|large" on a containing element. Font size, line height, spacing and radii inherit that context. A local size="sm" remains smaller within the chosen context; it does not cancel the container scale. Track/indicator dimensions and border widths keep their existing local-size behavior.
The default context is medium. Nested containers can replace the inherited context explicitly, without multiplying the parent context again. Brand and light/dark mode remain independent. The current adopters are Status Light, Meter and Progress Bar; existing components have not been migrated implicitly.
Table of options
| Custom Element | Nunjucks | Values and defaults |
|---|---|---|
label | label | Names the measurement. Custom Element default: Meter; macro default: Storage used. Supply a meaningful label. |
value | value | A finite number. Custom Element default: 0; macro default: 72. Clamped to the range. |
min | min | Lower bound. Default: 0. |
max | max | Upper bound. Default: 100. |
value-text | valueText | Optional measurement text, such as 72 of 200 GB. Defaults to the rounded normalized percentage. |
variant | variant | default, positive, notice or negative. Default: default. |
size | size | md (default) or sm, relative to container scale. |
Behaviors
Normalized measurement
The fill represents (value − min) / (max − min). A value of 72 in a 0–200 range fills 36% of the track.
Range boundaries
Finite values below min or above max are clamped. A value of zero stays zero. Meter has no indeterminate state.
Read-only updates
Changing observed attributes replaces the displayed measurement. Meter emits no component-specific change event and does not accept keyboard or pointer input.
For the Custom Element, invalid or non-finite numeric input falls back to the corresponding default. If max is not greater than min, max becomes min + 1. If the resulting range cannot be represented, it resets to 0–100. Supply finite numeric arguments to the macro and set bounds deliberately rather than depending on recovery behavior.
Usage guidelines
Do
Name the quantity and include units when percentages alone would be ambiguous.
Don't
Do not use Meter for a task in progress. Use Progress Bar for uploading or processing.
Choose bounds that have meaning for the measurement. Explain any notice or negative condition in text; do not expect the fill color to explain a threshold.
Content standards
- Name the measured quantity, for example “Storage used”.
- Add units and a denominator when useful: “72 of 200 GB”.
- Update value text together with the numeric value; a stale custom label would describe a different measurement.
- Localize units and number formatting in the consuming application.
Keyboard interactions
Meter is read-only, has no keyboard commands and is not a tab stop. Use a separate input or slider when people need to change the value.
Accessibility
- A native
<meter>exposes its accessible name, min, max and value. value-textalso becomesaria-valuetextso the measurement can be expressed with units.- The styled proxy track has
aria-hidden="true"; the native meter remains in the accessibility tree. - The label and measurement text carry meaning alongside any color treatment.
- Updates are not live announcements by default. Add a surrounding announcement region only when the workflow requires it.
Implementation
import "ui-foundations/elements/ui-meter";
<uif-meter id="storage-meter" label="Storage used" min="0" max="200"
value="72" value-text="72 of 200 GB"></uif-meter>
const meter = document.querySelector("#storage-meter");
meter.setAttribute("value", "84");
meter.setAttribute("value-text", "84 of 200 GB");
For server-rendered, static HTML without Custom Element JavaScript:
{% import "macros/ui.njk" as uif %}
{{ uif.meter(label="Storage used", min=0, max=200, value=72,
valueText="72 of 200 GB", variant="default", size="md") }}
The macro emits the label, native <meter> and hidden-from-AT visual proxy. Include ui-foundations/core.css and ui-foundations/ui.css for the token-driven presentation. Pass explicit values in consumer code; the macro defaults are a documentation example.
The scale belongs to the container, not to the component's size attribute:
<div data-scale="large">
<uif-meter size="sm" label="Storage used" value="60"></uif-meter>
</div>
Theming
Use the brand and mode switches in the preview above. Visual values come from the pattern's --uif-meter-* slots and existing Semantic roles. Labels use semantic content color. An inward outline keeps colored markers or fills discernible across light and dark surfaces.
Set data-brand="a", "b" or "c" and data-mode="light" or "dark" on the root element. Consumers own activation of these contexts. See Design Tokens.
Tokens
Use container scale and local size for typography and spacing. The table lists component overrides.
| Token |
|---|
--uif-meter-border-radius |
--uif-meter-fill-background-default |
--uif-meter-fill-background-negative |
--uif-meter-fill-background-notice |
--uif-meter-fill-background-positive |
--uif-meter-font-family |
--uif-meter-font-weight |
--uif-meter-gap |
--uif-meter-label-color-default |
--uif-meter-track-background-default |
--uif-meter-track-height-md |
--uif-meter-track-height-sm |
--uif-meter-value-color-default |
Design checklist
The browser checks cover specific Runtime behavior and contrast pairs; they do not certify complete accessibility or live design parity.