šŸ”¹ Card-mod - Add css styles to any lovelace card

Try with this, it should do something similar to what you are searching:

card_mod:
  style:
    ha-map$: |
      {% set entities = config.entities | map(attribute='entity') | list %}
      {% for entity in entities %}
        {% if is_state(entity, 'not_home') %}
          ha-entity-marker[entity-id="{{ entity }}"] {
            filter: grayscale(1) brightness(1.75);
          }
        {% endif %}
      {% endfor %}

Edit: by the way, I have set up a docker instance and card_mod works in the same way in a map dashboard. You can use the same code as before, but removing the first part, you can iterate directly in the list because it is a list of entity ids:

card_mod:
  style:
    ha-map$: |
      {% for entity in config.entities %}
        {% if is_state(entity, 'not_home') %}
          ha-entity-marker[entity-id="{{ entity }}"] {
            filter: grayscale(1) brightness(1.75);
          }
        {% endif %}
      {% endfor %}

thanks, butā€¦

I am afraid this does not work:

title: Kaart
path: kaart
icon: mdi:map
type: panel
cards:

  - type: map
    card_mod:
      ha-map$: |
        {% set entities = config.entities | map(attribute='entity') | list %}
        {% for entity in entities %}
          {% if is_state(entity, 'not_home') %}
            ha-entity-marker[entity-id="{{ entity }}"] {
              filter: grayscale(1) brightness(1.75);
            }
          {% endif %}
        {% endfor %}
    hours_to_show: 48
    entities:
      - person.marijn
      - person.etcetc

nor does it work in an auto-entities card:

      type: custom:auto-entities
      show_empty: false
      filter:
        include:
          - domain: person
  #               entity_id: device_tracker.*composite
            not:
              state: home
            options:
              card_mod:
                style:
                  ha-map$: |
                    {% set entities = config.entities | map(attribute='entity') | list %}
                    {% for entity in entities %}
                      {% if is_state(entity, 'not_home') %}
                        ha-entity-marker[entity-id="{{ entity }}"] {
                          filter: grayscale(1) brightness(1.75);
                        }
                      {% endif %}
                    {% endfor %}

ive tried both templates in both cards

ive always tried it with variants on this:

              card_mod:
                style:
                  ha-entity-marker:
                    $: |
                      entity-picture {
                        filter: {{'grayscale(100%)' if is_state(config.entity,'not_home')
                                   else 'none'}};
                      }

as it has to target the marker checking the Dom inspector?
didnt work either, so I fell back to custom-ui, setting the picture template on the entity itself, rather than card-mod customizing the frontend.

either class marker picture or entity_picture should be targeted, both work

Letā€™s focus in map-card first, then we can try with other custom cards, but step by step. Letā€™s see what is not working in your configuration and is different to what I have.

I am seeing in the HTML that the ha-entity-marker has the entity-id parameter, so what the template is trying to do is to apply the styles to that card, so try these things:

  1. Check the ha-entity-marker element to see if it has styles on it
  2. Check card-mod element inside the shadow root of the ha-map and check what its style element has inside.
  3. If the style is empty, something is failing in the template, so do this:
card_mod:
  style:
    ha-map$: |
      {{ config.entities }}
      .test {
        color: red;
      }

And check again the content of the styles, I expect something like this:

[{'entity': 'person.marijn'}, {'entity': 'person.etcetc'}]
.test {
  color: red;
}

not really no, can you show me a screenshot of the inspector pane where you see that?

Sure, here you go:

yes! found that :wink:

Perfect, if that is the result of:

{{ config.entities }}

Then you have a list of entities instead of an array of objects like me, then just use the second code that I left for the map dashboard:

card_mod:
  style:
    ha-map$: |
      {% for entity in config.entities %}
        {% if is_state(entity, 'not_home') %}
          ha-entity-marker[entity-id="{{ entity }}"] {
            filter: grayscale(1) brightness(1.75);
          }
        {% endif %}
      {% endfor %}
1 Like

yes!
Ive changed it to ā€˜homeā€™ for now because all are home or in a zone :wink:

    card_mod:
      style:
        ha-map$: |
          {% for entity in config.entities %}
            {% if is_state(entity, 'home') %}
              ha-entity-marker[entity-id="{{ entity }}"] {
                filter: grayscale(1);
              }
            {% endif %}
          {% endfor %}

actually makes the picture in the Map panel go grayscale! very nice!

Iā€™d also love to mod a single entity on the entity itself, could that be done too?

Good trick :wink:

I donā€™t know why I have an array of objects instead of an array of entities, but the good thing is that you have it working. :+1:

I need to check that.

haha, this is still experimentalā€¦
now lets hop to that auto-entities, because that does not work.

      filter:
        include:
          - domain: person
  #               entity_id: device_tracker.*composite
            not:
              state: home
            options:
              card_mod:
                style:
                  ha-map$: |
                    {% for entity in config.entities %}
                      {% if not is_state(entity, 'home') %}
                        ha-entity-marker[entity-id="{{ entity }}"] {
                          filter: grayscale(1);
                        }
                      {% endif %}
                    {% endfor %}

could possibly take out the ā€˜ifā€™ from the template because auto-entities selects the entities. let me try

normally it would be like this

      filter:
        include:
          - domain: person
            not:
              state: home
            options:
              card_mod:
                style:
                  ha-map$: |
                    ha-entity-marker[entity-id="{{ this.entity_id }}"] {
                          filter: grayscale(1);
                        }

using this.entity_id in auto-entities, but it stays unchanged

It doesnā€™t accept styles on an entity as the pictures element card. But if you want to apply it to a single entity, just avoid making a for loop, and do it for single entity in the same template.

Because that custom card should have a different config, entities is not a config option there. Iā€™ll check what is the configuration of that custom card.

1 Like

I was reading the documentation to check what that options parameter does, and what is does is:

Map of options to apply to entity when passed to card.

You donā€™t need to send card_mod to each entity, you need to send it to the map card. Try to set the configuration here instead:

type: custom:auto-entities
card:
  type: map
  card_mod:
    style:
      ha-map$: |
        {% for entity in entities %}
          {% if not is_state(entity, 'home') %}
            ha-entity-marker[entity-id="{{ entity }}"] {
              filter: grayscale(1);
            }
          {% endif %}
        {% endfor %}
filter:
  include:
    - domain: person
      not:
        state: home

Edit: no this will not work. It will work of you add an entities to the config, but it will not get the filtered entities.

Edit 2: The filtered entities are in a configuration parameter called entities. The above code should work.

doesnā€™t work here I am afraid, Iā€™ve pasted the complete config to replace my own.

a simpler mod:

          style:
            ha-map$: |
              {% for entity in entities %}
                  ha-entity-marker[entity-id="{{ entity }}"] {
                    filter: grayscale(1);
                  }
              {% endfor %}

is unsuccessful also.

the earlier succes with the map card in the panel also stopped working. (in Safari at least, seems Chrome is a bit more stable). Even tried -webkit-filter: grayscale(1);, to no avail

I fear were back to this ā€˜solutionā€™, which is not very straightforward either, especially if I want my condition in there.
And that was the reason I fell back to custom-ui before.

update

giving it another shot with:

// Define constants for the custom-ui component
const Name = "Map styles";
const Version = "20240928";
const Description = "add Styles to Map markers";
const Url = "https://github.com/thomasloven/lovelace-card-mod/issues/224";

// Log information about the custom-ui component
console.groupCollapsed(
  `%c ${Name} ${Version} is installed \n%c ${Description} `,
  "color: gold; font-weight: bold; background: black",
  "color: white; font-weight: bold; background: steelblue"),
console.log("Readme:",Url),
console.groupEnd()

customElements.whenDefined('ha-entity-marker').then(() => {
  const EntityMarker = customElements.get('ha-entity-marker');
  const { html, css } = EntityMarker.prototype;

  // defined added style
  const newStyle = css`
  .marker {
    filter: grayscale(1)
  }`;

  const newStyles = [].concat(EntityMarker.styles, newStyle);

  Object.defineProperty(EntityMarker, 'styles',        {value: newStyles, configurable: true, enumerable: false});
  Object.defineProperty(EntityMarker, 'elementStyles', {value: newStyles, configurable: true, enumerable: false});
});

as js module (still without template, just to test if this sets the grayscale at all).

which it seems to be doing.

now how to get that template in there, and reference the entity state

Letā€™s do the same that we did before, check what is rendered inside the card-mod style element with this:

type: custom:auto-entities
card:
  type: map
  card_mod:
    style:
      ha-map$: |
        {{ config.entities }}
        .test {
          color: red;
        }
filter:
  include:
    - domain: person
      not:
        state: home

Safari is known by its issues with filters and it seems that it doesnā€™t like to apply the filters to a custom element. Apply the filter in the parent div of the ha-entity-marker.

div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
  filter: grayscale(1) brightness(1.75);
}

like

    - type: custom:auto-entities
      card:
        type: map
        card_mod:
          style:
            ha-map$: |
              {% for entity in entities %}
                  div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                    filter: grayscale(1) brightness(1.75);
                  }
              {% endfor %}
      filter:
        include:
          - domain: person
            not:
              state: home

no effect, markers remain untouched,

this however does seem to stick in Safari:

    - type: map
      entities:
        - person.marijn
      card_mod:
        style:
          ha-map$: |
            {% for entity in config.entities %}
              {% if is_state(entity, 'home') %}
                div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                  filter: grayscale(1) brightness(1.75);
                }
              {% endif %}
            {% endfor %}

Maybe the challenge left is to get it to work in the auto-entitiesā€¦ Ill try it as option on the entity

Yep, I made a mistake before, it should be config.entities instead of entities.

Do what I recommend before, try to render the config.entities with a test style below and show me what is rendered inside the style element. Depending on the shape of your object the code should be changed slightly.

yes, I did change to config.entities:

- title: Map mods
  path: map_mods
  icon: mdi:map
  badges:
  cards:

# This mod is functional
    - type: map
      entities:
        - person.marijn
      card_mod:
        style:
          ha-map$: |
            {% for entity in config.entities %}
              {% if is_state(entity, 'home') %}
                div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                  filter: grayscale();
                }
              {% endif %}
            {% endfor %}

# This exact same mod is not functional on the auto-entities filtered entities
    - type: custom:auto-entities
      card:
        type: map
# these explicit entities are modded
#         entities:
#           - person.marijn
        card_mod:
          style:
            ha-map$: |
              {% for entity in config.entities %}
                {% if is_state(entity, 'home') %}
                  div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                    filter: grayscale();
                  }
                {% endif %}
              {% endfor %}
      filter:
        include:
          - domain: person

I believe I did that here

but let me check once more

    - type: custom:auto-entities
      card:
        type: map
        card_mod:
          style:
            ha-map$: |
              {{ config.entities }}
              .test {
                color: red;
              }

results in

so that would be promising after all

so changing that to

        card_mod:
          style:
            ha-map$: |
              {% for e in config.entities %}
                ha-entity-marker[entity-id="{{ e }}"]) {
                  filter: grayscale();
                }
              {% endfor %}

does make the mod show in inspector:

but does nothing in the Map cardā€¦

No, I mean only config.entities without the rest of the code. If the template fails, nothing is rendered.

Yep, now you have an array of objects like me. Then change the for loop by the code that I gave you at the beginning:

1 Like

that results in the same outcome in Inspector as I posted above, seems successful, but does not get applied to the Map card Markers:

but check this:

        card_mod:
          style:
            ha-map$: |
              {% set entities = config.entities | map(attribute='entity') | list %}
              {% for entity in entities %}
                {% if not is_state(entity, 'not_home') %}
                 div:has(>  ha-entity-marker[entity-id="{{ entity }}"]) {
                    filter: grayscale(1) brightness(1.75);
                  }
                {% endif %}
              {% endfor %}

the additional div:has() makes it work!