'How can I use an element's data-etc attribute value for CSS property values?

I want to use multiple data attribute in single css. So is that possible.?

I had created css given blow, i want to use data-letters and data-color both in css but it is not working.

data-color will placed at background and data-letters will placed at content in css

body { font-family: sans-serif; }

[data-letters]:before {
    content: attr(data-letters);
    display: inline-block;
    font-size: 32px;
    width: 85px;
    height: 80px;
    line-height: 2.5em;
    text-align: center;
    border-radius: 50%;
    background: #95A73B;
    vertical-align: middle;
    margin-right: 1em;
    color: white;
    margin-top:  20px;
}
<p data-letters="PB" data-color="#c0227a"></p>


Solution 1:[1]

TL;DR:

You can't. No browser supports using attr() for anything except only the content: property on ::before and ::after boxes:

Backstory:

  • CSS's attr() function theoretically allows you to use any element attribute from the DOM for any CSS property value.
    • However, as of early 2022 you can only use attr() with CSS's content: property, which only applies to the ::before and ::after pseudo-elements.
    • But you can concatenate multiple attributes within content: though, e.g.:

  body { font-family: sans-serif; }

  [data-letters]:before {
    content: attr(data-letters) ' ' attr(data-color);
    display: inline-block;
    font-size: 32px;
    line-height: 2.5em;
    text-align: center;
    border-radius: 50%;
    background: #95A73B;
    vertical-align: middle;
    color: white;
  }
  <p data-letters="PB" data-color="#c0227a"></p>

...but this isn't what you're looking for.


  • Note that conceptually the attr() function in CSS returns an arbitrary text string value, rather than a "typed" value.

    • So a string "#aabbcc" is not the same thing as a CSS-color-typed value #aabbcc, which is one of the reasons why we can't do color: attr(data-color);.
    • Note that even if color: attr(data-color); was supported by browsers, it would be the equivalent of doing color: "#aabbcc" instead of color: #aabbcc, which is invalid, so it wouldn't work anyway even if it was supported.
      • Hence the need for typed values.
      • (I note that we can reuse arbitrary custom-properties with real properties regardless of their type, and custom-properties tend to feel like string values (but they aren't) and so it feels inconsistent - but let's just pretend this isn't a thing for now)
    • ...I do agree it is surprising that support for this would be straightforward to implement, and has been an open issue for over 14 years now.
  • I speculate the reason why browsers don't (yet) support attr() for other properties is because you could just set an inline style="" attribute on the element to get the same end-result (well, except for ::before and ::after, of course, as those boxes don't map 1:1 to a DOM element).

  • If you want to track implementation progress:

Alternatives

As mentioned, you can use an inline style="" attribute to set properties on a per-element basis; so if you use the inline style to set custom-properties then those custom-properties can be used by any ::before and ::after boxes' style rules without needing to set explicit style properties on their parent, like so:

  body { font-family: sans-serif; }

  [data-letters]:before {
    content: attr(data-letters);
    display: inline-block;
    font-size: 32px;
    line-height: 2.5em;
    text-align: center;
    border-radius: 50%;
    background-color: var(--my-color);
    vertical-align: middle;
    color: white;
  }

   
  <p style="--my-color: #c0227a;" data-letters="PB"></p>

   

...though I agree this is inelegant and necessarily means duplicating values in both data- attributes and inside the style="" attribute (assuming you wanted to keep the data- attributes too).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1