demo · v130
Animated Meter
Chrome 130 lets appearance: none meters actually render, so the ::-webkit-meter-optimum-value pseudo-element is available to transition. Here, each <meter value> is nudged by a setInterval and the fill bar animates via transition: width 0.1s linear — no canvas, no custom track element required.
how it works
The key technique: set appearance: none on the <meter>, then target the Chromium-specific ::-webkit-meter-optimum-value pseudo-element with a CSS transition. Every 100 ms, JavaScript increments meter.value — the browser recomputes the pseudo-element's width, and the transition handles the smooth interpolation.
Before Chrome 130, appearance: none caused the meter to collapse to zero size. The new fallback styles preserve a usable box model, making this pattern possible without wrapper hacks.
the code
/* Chrome 130: appearance: none now falls back gracefully */
meter {
appearance: none;
width: 100%;
height: 0.6rem;
background: var(--bg-stone); /* track colour */
border: 1px solid var(--border-black);
display: block;
}
/* Remove the default Webkit bar so our background shows through */
meter::-webkit-meter-bar {
background: var(--bg-stone);
border: none;
}
/* The fill pseudo-element — add a CSS transition here */
meter::-webkit-meter-optimum-value {
background: var(--accent-emerald); /* emerald fill */
transition: width 0.1s linear; /* smooth animation */
}
meter::-webkit-meter-suboptimum-value { background: var(--accent-blue); }
meter::-webkit-meter-even-less-good-value { background: var(--accent-rose); }
/* Firefox */
meter::-moz-meter-bar {
background: var(--accent-emerald);
transition: width 0.1s linear;
}
/* JS: nudge value every 100 ms */
const tick = setInterval(() => {
if (meter.value >= targetPct) {
clearInterval(tick);
return;
}
meter.value = Math.min(meter.value + stepSize, targetPct);
}, 100);
see also
- meter element fallback styles — feature index
- <meter> with author styles — basic appearance: none comparison
- Dashboard Meters — real-world metric gauges
- ChromeStatus entry — meter element fallback styles