Using attr to set css variable inline that work with CSP

Viewed 1637

I was thinking how I can use css variables without using inline styles. I thought that I can use this:

[data-color] {
    --color: attr(data-color color, green);
}
* {
    color: var(--color, blue);
}
<div data-color="red">hello</div>

It seems that attr work only in pseudo selectors (and probably only on content: property), but MDN attr page says:

The attr() CSS function is used to retrieve the value of an attribute of the selected element and use it in the stylesheet. It can also be used on pseudo-elements, in which case the value of the attribute on the pseudo-element's originating element is returned.

There is even demo but it don't work in Chrome on Linux, so it's of no use to me. It even don't work in Firefox on Linux.

Is there any other way to use css variables without inline styles and without writing dynamic <style></style> and nonce?

3 Answers

Not yet. In the same link you can read:

Note: The attr() function can be used with any CSS property, but support for properties other than content is experimental, and support for the type-or-unit parameter is sparse.

Still no browser support the attr() for properties different than content and also no support for the type-or-unit.

Worth to note that you can use attr() inside a CSS variable but it need to be later used with content. CSS variables is only an intermediate so we don't evaluate the support based on the variable but based on the property that will use the variable.

[data-color] {
  --color: attr(data-color);
}

*::before {
  content: var(--color, "default");
  color:blue;
}
<div data-color="red">hello</div>

An interesting use of the CSS attr property, but as the question states, the support for it outside of the pseudo element property is sparse see for example https://developer.mozilla.org/en-US/docs/Web/CSS/attr

It's actually slightly worse than that because if you have:

* {
    color: var(--color, blue);
}
[data-color] {
    --color: green;
    --color: attr(data-color);
}
<div data-color="red">hello</div>

similar to in the question but separated out to be more explicit. The --color: attr(data-color) does not flag a warning and get ignored and the green used. Instead it is accepted and --color set to the string. It's as if the browser sort of recognises the attr and that it should do something with it but doesn't actually do it fully.

For everyone who still want to manage CSS variable on HTML you can do it like that:

* {
    color: var(--color, blue);
}
<div style="--color: red">hello</div>
<div>hello</div>

Related