5

I am looking to use an HTML data attribute to assign a value to a CSS property.

Essentially my HTML is like this:

<div class='dynamic-color' data-assigned-color='red'>lorem ipsum</div>
<div class='dynamic-color' data-assigned-color='blue'>lorem ipsum</div>
<div class='dynamic-color' data-assigned-color='green'>lorem ipsum</div>

And I want my CSS to be something like:

.dynamic-color {
    color: [data-assigned-color];
}

My current working solution is:

.dynamic-color[data-assigned-color='red'] {
    color:red;
}
...

However, there are several issues with this.

  1. when users add values through the UI to the database, then I also need to update the CSS
  2. Highly repetitive code

NOTE: I am using LESS so a LESS or pure CSS solution is good.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Nathan Koop
  • 24,803
  • 25
  • 90
  • 125
  • 1
    you have to use javascript for this or just use a style attribute. – Daniel A. White Dec 15 '14 at 16:39
  • 1
    CSS3 `attr()` was designed specifically for this purpose, but it's not implemented anywhere. See http://stackoverflow.com/questions/8769786/css3s-attr-doesnt-work-in-major-browsers/8769922#8769922 – BoltClock Dec 15 '14 at 16:39
  • has Daniel said you, you must use javascript/jquery to change css properties by the moment. – Zander Dec 15 '14 at 16:41
  • 1
    also attr's documentation here: https://developer.mozilla.org/en-US/docs/Web/CSS/attr?redirectlocale=en-US&redirectslug=CSS%2Fattr Personally, what I would do is just use a style attribute. – Adam D. Ruppe Dec 15 '14 at 16:42

2 Answers2

6

At the moment, this is not fully possible without JavaScript.

When fully supported, you will be able to use data-attribute like this:

.dynamic-color {
  color: attr(data-assigned-color);
}

As an alternative, have you considered something as simple as:

CSS

Set default colour options once in your stylesheet.

.red{color:red !important;}
.blue{color:blue !important;}
.green{color:green !important;}

HTML

Add/remove class as required to alter text colour. (I'm not sure what backend you are using but this could be done with your javascript or code behind).

<div class="dynamic-color red" data-assigned-color="red">lorem ipsum</div>

BROWSER SUPPORT

While attr() is supported in most browsers for the content property, CSS Values and Units. Level 3 adds the ability to use attr() on any CSS property, and to use it for non-string values (e.g. numbers, colors).

FIREFOX (Partial support)

https://developer.mozilla.org/en-US/docs/Web/CSS/attr

EDGE (Under consideration)

https://developer.microsoft.com/en-us/microsoft-edge/platform/status/csslevel3attrfunction/

CHROME (Partial Support)

The attribute selector can be used but I would recommend testing your code on all target browsers before using it in production.

Personally I would stick with JavaScript for the time being.

DreamTeK
  • 32,537
  • 27
  • 112
  • 171
  • 1
    You could also do this similar idea with an attribute selector instead of a class: `[data-assigned-color="red"] { color: red !important; }` then you don't have to modify the html. But it'd still be a lengthy stylesheet. – Adam D. Ruppe Dec 15 '14 at 17:14
  • What do you mean by ``When fully supported you will be able to use data-attribute like this`` ? Is there any roadmap for a such feature? – themihai Mar 05 '18 at 20:05
  • @themihai see my notes above :) – DreamTeK Mar 06 '18 at 08:36
  • 1
    @DreamTeK Sorry, but I couldn't resist. I was wondering why for a God sake the green color doesn't work. It's because you'we got "green!improtant -impROtant! I was laughing at myself. Please, change, someone might have the same problem. OMG... But thanks a lot - it's what I wanted. – Igor Beuermann Mar 27 '23 at 14:50
  • @IgorBeuermann Sorry, that made me laugh. :D Thanks for pointing it out. I have amended it. – DreamTeK Mar 28 '23 at 08:44
0

Try jQuery for this:

$('.dynamic-color').click(function() {
  $(this).css('background', $(this).attr('data-assigned-color'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='dynamic-color' data-assigned-color='red'>lorem ipsum</div>
<div class='dynamic-color' data-assigned-color='blue'>lorem ipsum</div>
<div class='dynamic-color' data-assigned-color='green'>lorem ipsum</div>

As the comment below suggests, You can add a pure inline CSS solution like this:

<div class='dynamic-color' style="background:red;">lorem ipsum</div>
<div class='dynamic-color' style="background:blue;">lorem ipsum</div>
<div class='dynamic-color' style="background:green;">lorem ipsum</div>

Try using the style attribute instead of the data-assigned-color attribute.

Ian Hazzard
  • 7,661
  • 7
  • 34
  • 60
  • 1
    This fits what the OP asked for, but I'd like to question the premise: why is `data-assigned-color` + javascript better than a `style="color: color;"` attribute? You'd want to filter the color value to a whitelist but then it would work even with JS disabled and is still readable (especially with a good DOM library) – Adam D. Ruppe Dec 15 '14 at 16:45
  • @AdamD.Ruppe, I could have done it that way, but I try not to change much of the original code. I can add an alternative way without the `data-assigned-color`. – Ian Hazzard Dec 15 '14 at 16:51
  • This is good, unfortunately, my problem is a bit more complicated than the question implies. I need to do some LESS transformations on the color before it's displayed, darken, gradients etc... – Nathan Koop Dec 15 '14 at 16:58
  • 3
    hmm, I doubt LESS transformations would work on an attribute anyway since the dynamic attribute value wouldn't be available to the less compiler when the asset is generated. You could do similar transformations on the server though and make the appropriate style attributes. – Adam D. Ruppe Dec 15 '14 at 17:13
  • @Nathan >I need to do some LESS transformations... - This is just impossible, at the compile time Less has no knowledge of your HTML. Period. (So for the transformations you also need to use some scripts - see [comments and codepen there](http://stackoverflow.com/a/25476970/2712740)). – seven-phases-max Dec 16 '14 at 00:49