Using the CSS attr() Function for Smarter Styling

The CSS attr() function pulls values directly from HTML attributes into your styles—but it’s no longer limited to just displaying text content. Starting with Chrome 133, attr() can now parse typed values and work with any CSS property, opening up powerful new styling patterns with minimal JavaScript.
Key Takeaways
- The modern attr() function works with any CSS property, not just content
- Type parsing allows conversion of attribute values into proper CSS data types
- Chrome 133+ supports the expanded attr() syntax with fallback values
- Feature detection ensures graceful degradation in unsupported browsers
Traditional attr() Usage: Limited but Useful
For years, the CSS attr() function has been a handy tool for extracting HTML attribute values, but with one major limitation: it only worked with the content
property and always returned strings.
/* Classic attr() - display href as text */
a:empty::before {
content: attr(href);
}
This traditional usage remains valuable for displaying attribute values as text—think tooltips showing URLs or data attributes in pseudo-elements. But that’s where its usefulness ended.
The Modern attr() Revolution
The upgraded CSS attr() function transforms how we handle dynamic styling. Instead of being confined to the content
property, you can now use attr() with any CSS property and parse values into specific data types.
Basic Syntax
attr(<attr-name> <attr-type>?, <fallback-value>?)
The function accepts three parameters:
- attr-name: The HTML attribute to read
- attr-type: How to parse the value (optional)
- fallback-value: Default if attribute is missing (optional)
Type Parsing: Beyond Strings
The real power of the modern CSS attr() function lies in type parsing. You can now convert attribute values into proper CSS data types:
Color Values
<div class="card" data-color="#3b82f6">Blue Card</div>
.card {
background-color: attr(data-color type(<color>), gray);
}
The type(<color>)
declaration tells the browser to parse the attribute as a color value. If the attribute is missing or invalid, it falls back to gray.
Numeric Values with Units
<p data-size="18">Adjustable text</p>
p {
font-size: attr(data-size px, 16px);
}
Here, the CSS attr() function appends px
to the numeric value. You can also use other units like rem
, em
, or %
.
Custom Identifiers
One of the most powerful applications uses <custom-ident>
for dynamic CSS property values:
<div class="card" id="card-1">First Card</div>
<div class="card" id="card-2">Second Card</div>
.card {
view-transition-name: attr(id type(<custom-ident>), none);
}
This automatically assigns unique view-transition-name
values based on element IDs—perfect for view transitions without repetitive CSS.
Discover how at OpenReplay.com.
Supported Data Types
The modern CSS attr() function supports numerous data types:
<string>
(default)<color>
<number>
<length>
<percentage>
<angle>
<time>
<custom-ident>
<integer>
<transform-function>
Note: For security reasons, <url>
values aren’t supported except as strings in the content
property.
Real-World Applications
Dynamic Theming
<section data-theme-color="#1e293b" data-theme-spacing="2">
<h2>Themed Section</h2>
</section>
section {
background-color: attr(data-theme-color type(<color>), white);
padding: attr(data-theme-spacing rem, 1rem);
}
Responsive Grid Layouts
<div class="grid" data-columns="3">
<!-- Grid items -->
</div>
.grid {
display: grid;
grid-template-columns: repeat(attr(data-columns type(<integer>), 1), 1fr);
}
Browser Support and Feature Detection
The modern CSS attr() function capabilities are currently experimental, with full support only in Chrome 133+ and other Chromium-based browsers. Always use feature detection:
@supports (width: attr(x type(*))) {
/* Modern attr() supported */
.element {
color: attr(data-color type(<color>), black);
}
}
@supports not (width: attr(x type(*))) {
/* Fallback styles */
.element {
color: black;
}
}
For JavaScript detection:
if (CSS.supports("width", "attr(x type(*))")) {
// Modern attr() is available
}
Best Practices
- Always provide fallbacks: The second parameter ensures your styles work even when attributes are missing
- Use semantic attribute names:
data-font-size
is clearer thandata-fs
- Consider performance: While powerful, excessive attr() usage can impact rendering performance
- Validate attribute values: Ensure your HTML attributes contain valid CSS values for the expected type
Common Pitfalls
Watch out for these issues when using the CSS attr() function:
- Unit mismatches:
font-size: attr(data-size)
fails without units - Invalid type parsing: Ensure attribute values match the declared type
- Inheritance quirks: attr() values compute on the element where they’re used, not where they’re defined
Conclusion
The modern CSS attr() function bridges the gap between HTML and CSS, enabling truly dynamic styling without JavaScript. While browser support is still growing, its potential for component-based design systems and data-driven layouts makes it worth adopting with proper fallbacks. As more browsers implement these features, attr() will become an essential tool for writing cleaner, more maintainable stylesheets.
FAQs
Yes, you can use attr() to set custom property values. For example, --theme-color: attr(data-color type(color), blue) works in supported browsers. This allows for powerful cascading and inheritance patterns.
When type parsing fails, the browser treats it as if the attribute doesn't exist and uses the fallback value. If no fallback is provided, the property declaration becomes invalid and is ignored.
Each attr() function requires the browser to read HTML attributes and parse them during style calculation. While modern browsers optimize this process, excessive use on frequently updated elements could impact rendering performance.
Use feature detection with @supports or CSS.supports() to provide fallback styles. Consider using CSS custom properties set via JavaScript as an alternative for unsupported browsers while maintaining similar functionality.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..