Logo Gerardo Perrucci - Full Stack Developer

Mastering the CSS attr() Function: Dynamic Styling with HTML Attributes

CSS attr() function

The CSS attr() function is a hidden gem that bridges HTML and CSS, allowing developers to create dynamic, data-driven designs with minimal JavaScript.

While traditionally used for simple tooltips, modern advancements have expanded its capabilities to support type-specific values, responsive design, and even theming. This article explores practical use cases, code examples, and the evolving role of attr() in modern web development.


What is the CSS attr() Function?

The attr() function retrieves the value of an HTML attribute and applies it to a CSS property. Initially limited to the content property for generated content (e.g., tooltips), CSS3 expanded its scope to support other properties and data types .

Basic Syntax

selector {
  property: attr(attribute-name type);
}
  • attribute-name: The HTML attribute to target (e.g., data-color).
  • type (optional): Specifies the data type (e.g., string, number, color). Defaults to string if omitted .

Core Use Cases & Examples

1. Tooltips with Dynamic Content

Leverage attr() with ::before/::after pseudo-elements to display metadata stored in HTML attributes.

<button data-tooltip="Save changes">Click me</button>
button {
  position: relative;
}

button::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #333;
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.3s;
}

button:hover::after {
  opacity: 1;
}

Result: Hovering the button reveals a tooltip with the text from data-tooltip .


2. Dynamic Styling Based on Attributes

Use attr() to apply styles directly from HTML attributes. For example, set text color dynamically:

<p data-color="#ff0000">Red text</p>
<p data-color="#00ff00">Green text</p>
p {
  color: attr(data-color type(<color>), blue);
}

Note: Browser support for non-content properties is still limited. Always provide fallbacks .


3. Responsive Images with srcset-Like Behavior

While srcset is standard for responsive images, attr() can simulate similar behavior in CSS for background images:

<div class="hero" data-mobile-img="mobile.jpg" data-desktop-img="desktop.jpg"></div>
.hero {
  background-image: attr(data-mobile-img url);
}

@media (min-width: 768px) {
  .hero {
    background-image: attr(data-desktop-img url);
  }
}

Limitation: This approach lacks the performance optimizations of native srcset but works for simple cases .


4. Theming with Data Attributes

Centralize theme variables in HTML for CSS consumption:

<body data-theme="dark">
  <h1>Dark Theme</h1>
</body>
body {
  --primary-color: attr(data-theme color);
}

body[data-theme='dark'] {
  --primary-color: #1a1a1a;
}

body[data-theme='light'] {
  --primary-color: #ffffff;
}

Tip: Combine with CSS variables for more robust theming .


Pros and Cons of attr()

ProsCons
Reduces JavaScript dependencies

Limited browser support for non-content properties

Simplifies dynamic contentFallbacks required for older browsers
Centralizes data in HTMLLess powerful than CSS variables for theming

When to Use attr() vs. Alternatives

  • Use attr() for:
    • Simple tooltips or labels.
    • One-off dynamic styles tied to HTML attributes.
  • Prefer CSS Variables for:
    • Complex theming or reusable values.
    • Wider browser compatibility .

Browser Compatibility

BrowserSupport (Basic)Support (Type-Aware)
Chrome✅ 4+⚠️ Experimental
Firefox✅ 2+⚠️ Experimental
Safari✅ 3.1+
Edge✅ 12+⚠️ Experimental

Data from MDN and Can I Use (2025)


Decorative quote icon

The attr() function is a testament to CSS’s evolution—blending markup and style in ways that reduce JavaScript overhead.


Final Code Example: Interactive Rating System

<div class="rating" data-score="4.5">★★★★☆</div>
.rating {
  font-size: 2rem;
  color: #ccc;
  position: relative;
}

.rating::before {
  content: '★★★★★';
  position: absolute;
  color: gold;
  width: calc(attr(data-score number) * 20%);
  overflow: hidden;
}

Result: A star rating that dynamically highlights based on data-score .

References