Layout Advanced

Data-driven layouts without JavaScript charts

Small dashboards often pull in a charting library just to draw a few bars. Typed attr() lets CSS read numbers from data-* attributes and size blocks directly so you can skip the JavaScript chart layer.

Modern
CSS-driven chart
1.bar {
2  block-size: 1.5rem;
3  background: var(--accent);
4  inline-size:
5    attr(data-pct percentage);
6}
7<!-- HTML -->
8<div class="bar" data-pct="47%"></div>
9<div class="bar" data-pct="82%"></div>
Old JS-driven chart
1/* JavaScript sets a --pct variable for each bar */
2.bar {
3  block-size: 1.5rem;
4  inline-size: calc(1% * var(--pct));
5  background: var(--accent);
6}
7// JS
8bars.forEach(bar => {
9  bar.style.setProperty("--pct", bar.dataset.pct);
10});
Widely available Since 2015 99% global usage

This feature is well established and works across many devices and browser versions. It has been available across browsers since 2015.

Safe to use without fallbacks.

4+
2+
3.1+
12+

Note: The attr() function can be used with any CSS property, but support for using attr() with typed values on properties other than content is experimental. The pattern on this page should be treated as progressive enhancement.

typed attr() reads bar width from data-pct
In Chromium, bars use attr(data-pct percentage). Other browsers keep the fallback width.
Search
82%
Docs
64%
API
47%
Blog
29%
Kinsta

Your first month is free

Managed WordPress hosting for faster sites.

Learn more
⚑

Less glue JavaScript

Instead of copying numbers from data-* attributes into custom properties, CSS reads them directly. You keep the data in one place and let layout respond to it.

✦

Inline dashboards

Typed attr() works well for tiny in-context charts: value bars in cards, capacity meters, or progress indicators. No charting library, no canvas, no SVG boilerplate.

∞

Progressive enhancement

The feature ships first in Chromium browsers. You can gate the behavior behind @supports and keep a custom property based fallback for all other engines.

Key Change
Data in attributes
CSS reads numbers directly
Old Approach
JS sets custom properties
DOM writes for every bar
Modern Approach
attr() typed values
Data β†’ layout with no JS

How it works

The classic bar chart pattern stores a number in a data-* attribute and then copies that value into a --pct custom property with JavaScript. Layout runs off the custom property, not the data itself, so you end up with two sources of truth.

Typed attr() extends the long-standing attr() function so it can return non-string values. In this pattern a bar reads attr(data-pct percentage) and uses the result directly for its inline-size, which keeps the data in the markup and lets CSS do the math.

Note: attr() is widely supported when used with content, but using attr() on other properties with typed values is still experimental. Support for this pattern is currently limited to Chromium-based browsers, so treat it as progressive enhancement only and keep a custom property or fixed-size fallback for everyone else.

New CSS drops.

Join 600+ readers who've survived clearfix hacks.

ESC