How to Use the CSS attr() Function with Content

This article provides a comprehensive overview of the CSS attr() function, focusing on how it works in tandem with the content property to retrieve values from HTML attributes. You will learn the core syntax, how the browser processes attribute values via pseudo-elements, common real-world use cases such as print stylesheets and dynamic tooltips, and current browser support limitations.


What Is the attr() Function?

The attr() function in CSS is used to retrieve the value of an attribute of the selected HTML element and use it directly within your stylesheet. While modern CSS specifications aim to expand attr() to support colors, lengths, and numbers across various properties, its primary and most widely supported implementation is restricted to returning strings within the content property of the ::before and ::after pseudo-elements.

How attr() Pulls Attribute Text

The browser handles attr() by matching the specified attribute name against the DOM node of the element being styled. When a pseudo-element is generated, the content property evaluates attr(attribute-name) and replaces the function call with the raw text string contained in that HTML attribute.

The basic syntax is:

element::after {
  content: attr(attribute-name);
}

If the specified attribute does not exist on the target element, the function returns an empty string, meaning no content will be rendered.

Practical Examples

A classic use case for attr() is printing web pages, where users cannot click links. You can extract the href attribute from anchor tags and display the destination URL alongside the link text.

HTML:

<a href="https://example.com">Visit Example</a>

CSS:

@media print {
  a[href]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #555;
  }
}

2. Building Lightweight Tooltips with data-* Attributes

You can pull custom metadata using HTML data-* attributes to create interactive tooltips without JavaScript.

HTML:

<button class="tooltip" data-tip="Save changes to your profile">Save</button>

CSS:

.tooltip {
  position: relative;
}

.tooltip:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: 125%;
  left: 50%;
  transform: translateX(-50%);
  background-color: #333;
  color: #fff;
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  font-size: 12px;
}

3. Responsive Data Tables

For mobile layouts, tables can be collapsed into block-level elements where column headers are injected directly from data attributes on table cells.

HTML:

<td data-label="Account Balance">$1,250.00</td>

CSS:

@media (max-width: 600px) {
  td::before {
    content: attr(data-label) ": ";
    font-weight: bold;
  }
}

Limitations

  • Restricted Target Elements: The attr() expression only reads attributes from the element generating the pseudo-element. It cannot traverse the DOM to read attributes from parent or sibling elements.
  • String-Only Data Type Support: In baseline CSS implementations, attr() can only be interpreted as a CSS <string>. It cannot currently be passed into properties like width, color, or font-size as a unit or color value in standard, cross-browser production code.
  • Dynamic Updates: If JavaScript updates the HTML attribute via setAttribute(), the attr() value reflected in the CSS content property will update automatically, as it references the live DOM attribute state. However, it does not read JavaScript object properties that differ from the HTML attribute itself.