v133 · css
Progress Bars
Progress bars styled entirely in CSS using attr(data-value type(<number>), 0) — no style="width:…" needed. Set the value in HTML via data-value="72"; CSS reads it as a number and uses it in calc() to drive the fill width.
Feature detection: checking…
The data-value attribute is a plain HTML attribute. CSS typed attr() interprets it as a <number> and feeds it into calc() — no JavaScript and no inline style needed.
Tasks — driven by data-value HTML attributes
Ratio bars — data-value / data-max via calc()
Live editor — adjust data-value without JavaScript
Only the data-value HTML attribute is changed; CSS attr() reads the new number and CSS calc() updates the width — no inline style, no CSS variable, no JS style manipulation.
technique comparison
| technique | HTML | CSS | JS needed? |
|---|---|---|---|
| Inline style | style="width:72%" |
none | Yes — must set inline style |
| CSS variable | style="--p:72%" |
width: var(--p) |
Yes — must set CSS variable |
| Typed attr() (Chrome 133+) | data-value="72" |
width: calc(attr(data-value type(<number>)) * 1%) |
No — pure CSS reads the data attribute |
/* Typed attr() reads a data attribute as a CSS number */
.progress-fill {
width: calc(attr(data-value type(), 0) * 1%);
/* data-value="72" → width: 72% */
}
/* Ratio: attr() on two attributes */
.progress-fill-ratio {
width: calc(
attr(data-value type(), 0) /
attr(data-max type(), 100) * 100%
);
/* data-value="340" data-max="500" → width: 68% */
}
/* Colour semantics via data-status selector */
[data-status="danger"] .progress-fill { background: red; }