A more powerful CSS attr() function
The attr()
function reads the value of a HTML attribute and allows you to use it in CSS. Values defined in markup can be used within a stylesheet. The attr()
function is used most commonly with data-
attributes but it can access any HTML attribute. Currently, use of the attr()
function is limited to the content
property, meaning it can be used with ::before
, ::after
and ::marker
, and is limited to string values.
<ul>
<li data-mark="💥">item 1</li>
<li data-mark="✨">item 2</li>
<li data-mark="🦖">item 3</li>
</ul>
li::marker {
content: attr(data-mark);
}
Fallback value
attr()
supports a fallback value:
h1:before {
content: attr(data-mark, "✨");
}
This will be used as the default value when the data attribute is not included on the element in your HTML. This has been supported since Firefox 119, Safari Technology Preview 208, and in Chrome Canary (behind a flag).
See the Pen attr() fallback by Ollie Williams (@cssgrid) on CodePen.
(Safari does not yet support the content
property for ::marker
so the list part of the above demo does not work in Safari.)
attr()
for more than string values
In the latest W3C CSS Values and Units specification, the attr()
function can be used to specify any kind of value, not just strings, and can be used as the value for any CSS property, not just content
.
[data-bg] {
background-color: attr(data-bg type(<color>));
}
<div data-bg="blue"></div>
To test out the following functionality, open Chrome Canary from terminal with the --enable-features=CSSAdvancedAttrFunction
flag (its due to ship in Chrome 133).
/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --enable-features=CSSAdvancedAttrFunction
See the Pen attr function doesn't work... by Ollie Williams (@cssgrid) on CodePen.
You can combine this new power with fallback values:
div {
background-color: attr(data-bg type(<color>), pink);
}
See the Pen Untitled by Ollie Williams (@cssgrid) on CodePen.
Here’s an example using the maxlength
attribute of an input
to set the width:
See the Pen maxlength attribute for width with attr() by Ollie Williams (@cssgrid) on CodePen.
You can set the value of a CSS variable using the attr()
function:
See the Pen setting CSS variable with data attribute attr by Ollie Williams (@cssgrid) on CodePen.
If you lose the data-
prefix, the HTML will no longer pass validation (but it will still work in all browsers).
Data attributes are easy to update from JavaScript:
someElement.dataset.bg = "purple";
Sadly, it seems that attr()
can’t be used in conjunction with the url()
function, so code such as the following will not work:
img {
float: left;
shape-outside: url(attr(src type(<url>)));
}
While there’s been a lot of developer interest in attr()
, some may be asking: how is this better than inline styles? Or utility classes? How is <div data-bg="blue">
superior to <div class="bg-blue">
or <div style="background-color: blue;">
?
A utility class needs to have an explicit value set in a stylesheet. The value of an attr()
function can be set to any arbitrary color, any arbitrary size, etc. Much of what you can do with the attr()
function can be achieved with an inline CSS variable. However, a Content Security Policy might block inline styles. Inline styles are often avoided because they can only be overridden with !important
.