Fill color for <svg> does not work

Hi,
I have a template node and want to change the fill color of a svg icon. Therefor I have the following code.

<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 -960 960 960" width="32" >
    <path fill="{{msg.color}}" d="M400-585 272-713q38-23 80.5-35t87.5-12q5 0 10 .5t10 .5q-29 32-44.5 73T400-600v15Zm313 313-88-88q35 2 68-5.5t63-24.5q-5 32-15.5 61.5T713-272ZM552-520l128-360h80l128 360h-76l-28-80H656l-28 80h-76Zm122-134h92l-46-146-46 146ZM537-220 220-537q-10 23-15 47.5t-5 49.5q0 100 70 170t170 70q25 0 49.5-5t47.5-15ZM791-80l-57 57-138-138q-36 20-75 30.5T440-120q-134 0-227-93t-93-227q0-42 10.5-81t30.5-75L14-743l57-57L791-80ZM379-378Z" />
</svg>

Unfortunately this doesn't work, the color of the icon doesn't change to green e.g. when I inject msg.color = "green".
Instead this work, but I like to understand why:

<style>
    #STYLE_1 path {
        fill: {{msg.color}};
    }
</style>

<svg id="STYLE_1" xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 -960 960 960" width="32" >
    <path d="M400-585 272-713q38-23 80.5-35t87.5-12q5 0 10 .5t10 .5q-29 32-44.5 73T400-600v15Zm313 313-88-88q35 2 68-5.5t63-24.5q-5 32-15.5 61.5T713-272ZM552-520l128-360h80l128 360h-76l-28-80H656l-28 80h-76Zm122-134h92l-46-146-46 146ZM537-220 220-537q-10 23-15 47.5t-5 49.5q0 100 70 170t170 70q25 0 49.5-5t47.5-15ZM791-80l-57 57-138-138q-36 20-75 30.5T440-120q-134 0-227-93t-93-227q0-42 10.5-81t30.5-75L14-743l57-57L791-80ZM379-378Z" />
</svg>

The problem is, that copying such a template will mean much more adaption effort since I need to make the name unique in order to get it working in case I have more than one of such templates. Therefor the first solution can be used out of the box without manual adaption effort.

Does anybody know why the first way doesn't work?

The first method doesn't work because Node-RED's template node doesn't directly support binding attributes like fill within the SVG element. It's not able to dynamically change the SVG attribute based on the value of msg.color . The second method using CSS works because it applies the style to the SVG using an ID selector, which is supported by Node-RED's template node.

Thanks for the quick reply. So I thought changing it to this will reduce the adaption effort as well, but setting the ID dynamically doesn't work either. Any idea how to get this working?
I pass in the node id which in fact is unique, this looks similar to 22a1e4a43f772235. When inspecting with developer tools inside my chrome browser, I see this Id got replaced, however it doesn't show up the desired color.

<style>
    #{{msg.id}} path {
        fill: {{msg.color}};
    }
</style>
<svg id="{{msg.id}}" xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 -960 960 960" width="32" >
    <path d="M400-585 272-713q38-23 80.5-35t87.5-12q5 0 10 .5t10 .5q-29 32-44.5 73T400-600v15Zm313 313-88-88q35 2 68-5.5t63-24.5q-5 32-15.5 61.5T713-272ZM552-520l128-360h80l128 360h-76l-28-80H656l-28 80h-76Zm122-134h92l-46-146-46 146ZM537-220 220-537q-10 23-15 47.5t-5 49.5q0 100 70 170t170 70q25 0 49.5-5t47.5-15ZM791-80l-57 57-138-138q-36 20-75 30.5T440-120q-134 0-227-93t-93-227q0-42 10.5-81t30.5-75L14-743l57-57L791-80ZM379-378Z" />
</svg>

Set a class in the template settings and use that class as the selector.

Can you share an example how this will look like?

This allow you to identify this specific template.

image

I already have a global css template defined, but I didnā€˜t know how to define the mentioned class and access it within the svg id property.
Maybe a stupid question but I am not that fimilar to html/css.

You setup CSS.

You add a class name to the template.

If you want to make dynamic runtime changes, you send a msg with .classname set.

This way, you can keep your presentation CSS separate and centralised and anywhere you want to use the class, just apply the class.

An example: My template nodes are ignoring my relations - #4 by Steve-Mcl

Another example: How to use pay load in one text output trigger color applied to another? - #2 by Steve-Mcl

Yet another: The colour in/on this isn't changing. (CSS) - #2 by Steve-Mcl

A (somewhat in-depth) chat about it (some useful tips and info): Dashboard Button Node - </>Class Field not working - #19 by Steve-Mcl (read from there down)

2 Likes

@Steve-Mcl thanks for the links. I am struggling with the correct selector. I set my classname in a function like that:

if (msg.payload === false)
{
    msg.classname = "white-svg";
    msg.payload = "M 480 -180 q -66 0 -113 -47 t -47 -113 H 200 q -33 0 -56.5 -23.5 T 120 -420 q 0 -140 92 -241.5 T 440 -778 v -122 h 80 v 122 q 136 15 228 116.5 T 840 -420 q 0 33 -23.5 56.5 T 760 -340 H 640 q 0 66 -47 113 t -113 47 Z M 200 -420 h 560 q 0 -116 -82 -198 t -198 -82 q -116 0 -198 82 t -82 198 Z m 280 160 q 33 0 56.5 -23.5 T 560 -340 H 400 q 0 33 23.5 56.5 T 480 -260 Z m 0 -80 Z"; 
}
else
{
    msg.classname = "yellow-svg";
    msg.payload = "M 480 -180 q -66 0 -113 -47 t -47 -113 H 200 q -33 0 -56.5 -23.5 T 120 -420 q 0 -140 92 -241.5 T 440 -778 v -122 h 80 v 122 q 136 15 228 116.5 T 840 -420 q 0 33 -23.5 56.5 T 760 -340 H 640 q 0 66 -47 113 t -113 47 Z M 200 -420 h 560 q 0 -116 -82 -198 t -198 -82 q -116 0 -198 82 t -82 198 Z m 280 160 q 33 0 56.5 -23.5 T 560 -340 H 400 q 0 33 23.5 56.5 T 480 -260 Z m 0 -80 Z M 440 -20 v -120 h 80 v 120 h -80 Z m -246 -126 L 138 -204 L 224 -288 L 280 -232 L 194 -146 Z M 766 -143 l -84 -86 l 56 -56 l 86 86 l -58 56 Z";
}

In my global stylesheet I have tried 2 selectors:

    .white-svg .nr-dashboard-template svg {
          fill: white !important;
          }
     .yellow-svg .nr-dashboard-template svg {
          fill: #FEA500 !important;
          }

and

    .white-svg md-card>svg {
          fill: white !important;
          }
     .yellow-svg md-card>svg {
          fill: #FEA500 !important;
          }

but both aren't working. Any ideas what I am doing wrong in terms of the selector?
The svg is directly placed inside a template node.

if you put $('.white-svg .nr-dashboard-template svg') into the browsers console does it select the SVG?

Nope, it return not available. And if a select the svg tag and click copy selector I do not get something realy useful #Erdgeschoss_Zimmer_Benno_cards > md-card:nth-child(12) > svg.

I dont have dashboard installed - show me a screenshot of the SVG with its parents expanded upto the top most item

first, correct your function - it should be msg.className = "white-svg" (note the className not classname)

next, as explained in the link ealier, instead of using !important, be more specific

e.g.

<style>
    .nr-dashboard-theme .nr-dashboard-template.white-svg svg path {
        fill: white;
    }
    .nr-dashboard-theme .nr-dashboard-template.yellow-svg svg path {
        fill: #FEA500;
    }
</style>

If that doesnt work, try setting the fill of the path to "currentFill" or "currentColor" or removing the fill attribute from the path altogether. As a last resort, add !important

I wasn't aware that the props are case sensitiv, corrected and used your intended style without !important and it work like a charme. Many thanks!

For future readers

  • JavaScript is 100% case sensitive :slight_smile:
    • basically msg.payload is NOT the same as Msg.payload
    • just as msg.classname is NOT the same as msg.className
  • CSS and HTML are not (mostly)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.