Workflow Intermediate

Typed attribute values without JavaScript

Reading data attributes for styling used to require JavaScript to parse dataset values and set inline styles or custom properties. Advanced attr() lets CSS read HTML attributes directly as typed values — numbers, colors, lengths, and more.

Old 10 lines
1/* JS: read data attr and set style */
2document.querySelectorAll('.bar')
3  .forEach(el => {
4    const pct = el.dataset.pct;
5    el.style.width = pct + '%';
6    el.style.setProperty(
7      '--pct', pct
8    );
9  });
10
Modern
4 lines
1.bar {
2  width: attr(
3    data-pct type(<percentage>)
4  );
5}
bars read width from data attributes
CSS
85%
HTML
92%
JS
68%
Rust
45%
width: attr(data-pct type(<percentage>))

No JavaScript bridge

Read data attributes directly in CSS without JavaScript parsing, type conversion, or custom property bridges.

Type coercion

Specify the expected type: , , , . The browser handles parsing and validation.

Fallback values

Provide a fallback if the attribute is missing or invalid: attr(data-x type(), 1rem).

Browser Support
42%
Chrome Edge Firefox 🔜
View on caniuse.com →
Types
All CSS types
<number>, <color>, etc.
Old Approach
JS dataset
el.dataset.x
Modern Approach
attr() types
attr(x type(...))

How it works

The attr() function has existed in CSS for years, but it could only return strings and was limited to the content property. To use data attributes for layout or color, you had to write JavaScript that reads el.dataset, converts the value, and sets it as an inline style or custom property.

Advanced attr() adds type coercion. You write attr(data-pct type(<percentage>)) and the browser reads the HTML attribute, parses it as a percentage, and uses it as a typed CSS value. This works with <number>, <length>, <color>, <angle>, and more. You can even provide fallbacks for missing or invalid attributes.

ESC