🔹 Card-mod - Add css styles to any lovelace card

How to reuse a card-mod code
(these questions are asked rather often)

There are several ways:
– yaml-anchors
– include
– secret
– macros
– decluttering-card
– card-mod theme
– external js

Note: examples below are synthetic and may be not optimal, but they give a general idea of re-use.

1. yaml-anchors
Only can be used in yaml-mode dashboards.
Anchors are one file-wide: if you have same repeated code in 2 files - you will have to declare same anchor in both files.

type: entities
entities:
  - entity: sun.sun
    card_mod: &ref_card_mod
      style: |
        :host { color: red; }
  - entity: sun.sun
    card_mod: *ref_card_mod
  - entity: sun.sun
    card_mod: *ref_card_mod

2. include
Only can be used in yaml-mode dashboards.

type: entities
entities:
  - entity: sun.sun
    card_mod: !include ...../style.yaml

where “style.yaml” contains

  style: |
    :host { color: red; }

Note: one imported file may contain one snippet - you cannot place several definitions like

style: |
  :host { color: red; }

style: |
  :host { color: green; }

style: |
  :host { color: blue; }

and then select a particular snippet.

Also, you can kind of “pass a variable” to the imported code:

type: entities
entities:
  - entity: sun.sun
    SUPER_COLOR: red #up to you how to name this option
    card_mod: !include ...../style.yaml
style: |
  :host { color: {{ config.SUPER_COLOR }}; }

3. secret
Only can be used in yaml-mode dashboards.

type: entities
entities:
  - entity: sun.sun
    card_mod: !secret card_mod_red_row

where “secrets.yaml” contains

card_mod_red_row:
  style: |
    :host { color: red; }

Note: one secrets file may contain several snippets like

card_mod_red_row:
  style: |
    :host { color: red; }

card_mod_green_row:
  style: |
    :host { color: green; }

card_mod_blue_row:
  style: |
    :host { color: blue; }

Although it is more convenient than using “include” (where each imported file must contain one snippet) - I would not recommend using secrets for not-secret data, wrong approach.


4. macros
Can be used both in yaml-mode & storage-mode dashboards.

type: entities
entities:
  - entity: sun.sun
card_mod:
  style: |
    ha-card {
      color: red;
    }
    {% from 'card_mod_macros.jinja' import MY_SUPER_HEADER -%}
    {{ MY_SUPER_HEADER() }}

where “card_mod_macros.jinja” contains

{% macro MY_SUPER_HEADER() -%}
  .card-content {
    color: red;
    ... other styles
  }
{%- endmacro %}

And ofc you can pass variables into a macros:

type: entities
entities:
  - entity: sun.sun
card_mod:
  style: |
    ha-card {
      color: red;
    }
    {% from 'card_mod_macros.jinja' import MY_SUPER_HEADER -%}
    {{ MY_SUPER_HEADER('magenta') }}
{% macro MY_SUPER_HEADER(COLOR) -%}
  .card-header {
    color: {{ COLOR }};
    ... other styles
  }
{%- endmacro %}

Note: one jinja-file may contain several macros like

{% macro card_mod_colored_state(COLOR) -%}
  ...
{%- endmacro %}

{% macro card_mod_colored_icon(COLOR) -%}
  ...
{%- endmacro %}

{% macro card_mod_colored_name(COLOR) -%}
  ...
{%- endmacro %}

5. decluttering-card
Can be used both in yaml-mode & storage-mode dashboards. There are some complexities in case of storage-mode dashboards (not to be described here, check Docs & other info for decluttering-card).
Assume you want to have card-modded Entities card in many places:

type: entities
title: ...
entities: ...
card_mod: ...

Create a decluttering template for this Entity card:

my_template:
  card:
    type: entities
    ... use input variables to define options
    card_mod: ...you may use input variable here like a particular color

and use this template where it is needed:

type: vertical-stack
cards:
  - ...
  - type: custom:decluttering-card
    template: my_template
    variables:
      - ...

You can pass a card-mod code as an input variable:

my_template:
  default:
    - STYLE: 'ha-card { color: red; }'
  card:
    type: entities
    ...
    card_mod:
      style: '[[STYLE]]'
type: vertical-stack
cards:
  - ...
  - type: custom:decluttering-card
    template: my_template
    variables:
      - STYLE: 'ha-card { color: cyan; }'
      - ...

to replace a default red color by a cyan color.
Also, you can pass an additional card-mod code as an input variable:

my_template:
  default:
    - STYLE: ''
  card:
    type: entities
    ...
    card_mod:
      style: |
        ha-card {
          color: red;
        }
        [[STYLE]]
type: vertical-stack
cards:
  - ...
  - type: custom:decluttering-card
    template: my_template
    variables:
      - STYLE: '.card-header { color: cyan; }'
      - ...

to add additional styles.
These were simple examples with string-like styles; in case of dictionary-like styles & styles with jinja templates there are more peculiarities which are beyond this topic.


6. card-mod theme
Traditional card-modding is about styling a particular card / row / other element of a particular card.
Card-mod theme provides “global” styles like:
– all Entities cards
– all rows with toggles
(not to mention other UI elements not covered by traditional card-modding like “view layout”, “sidebar”, “header”, “more-info dialog”, …)
Also, it is possible to mass-style SOME elements like:
– some Entities cards
– some rows with toggles
by using classes:

type: entities
card_mod:
  class: yellow_card

where “yellow_card” class is defined as

card-mod-card-yaml: |
  .: |
    ha-card.yellow_card {
      ... add your styles
    }

Check Docs for card-mod about defining themes.


7. External js
Can be used to style all UI elements of a particular type/class.
Particular examples will be not provided, it is not about card-mod & an off-topic here.

4 Likes

is it possible to add a background color to one heading badge icon?

Starting point:
1st post → link at the bottom → Heading

i know your fantastic overview and checked this out but i couldn´t find a answer to my question. I want a background of a badge in the heading title.

that is why a said it is a starting point… Find a post about Heading.

Map card - some animations

m1

code
type: map
entities:
  - entity: ...
card_mod:
  style:
    ha-map $:
      ha-entity-marker $: |
        .marker {
          outline-style: solid;
          outline-width: 1px;
          outline-color: var(--accent-color);
          animation: resizing_outline 1s linear infinite;
        } 
        @keyframes resizing_outline {
          0% {
            outline-offset: 0;
          }
          25% {
            outline-offset: 5px;
          }
          50% {
            outline-offset: 10px;
          }
          75% {
            outline-offset: 15px;
          }
          100% {
            outline-offset: 20px;
          }
        }

m2

code
type: map
entities:
  - entity: ...
card_mod:
  style:
    ha-map $:
      ha-icon $: |
        ha-svg-icon {
          animation: resizing 1s linear infinite;
        }
        @keyframes resizing {
          0% {
            transform: scale(0.3,0.3);
          }
          25% {
            transform: scale(0.7,0.7);
          }
          50% {
            transform: scale(1,1);
          }
          75% {
            transform: scale(1.15,1.15);
          }
          100% {
            transform: scale(1.3,1.3);
          }
        }
7 Likes

that is working for me:

        .badges hui-heading-badge:nth-child(4) hui-entity-heading-badge $: |
          ha-state-icon {
            --mdc-icon-size: 20px;
            color: white;
            background: #1c1c1c !important;
            border-radius: 25px;
            padding: 10px;
          }

nice animations yes! always fun to customize the map.

let’s not use a target-lock…

btw, the shorthand for the outline also works:

  - type: map
    card_mod:
      style:
        ha-map $:
          ha-entity-marker $: |
            .marker {
              outline: solid 1px var(--warning-color);
              animation: resizing_outline 1s linear infinite;
            }
            @keyframes resizing_outline {
              0% {outline-offset: 0;}
              25% {outline-offset: 5px;}
              50% {outline-offset: 10px;}
              75% {outline-offset: 15px;}
              100% {outline-offset: 20px;}
            }

let’s see if we can add this to card-mod theming

Correct, and shorthand can include an offset too, just wanted to make it more “accessible” for people))

This “changing radius” animation can be useful to highlight some event; so the animation should be switched ON if some conditions are met - try to put a corr. logic in a theme.

yes, like

{% set activity = states('sensor.' ~ id ~ '_activity') %}
{%- elif activity in ['Automotive','Cycling','Walking'] %}

actually a great idea

would be something like

  - type: map
    card_mod:
      style:
        ha-map $:
          ha-entity-marker $: |
            .marker {
              {% set id = config.entity.entity_id.split('.')[1] %}
              {% set activity = states('sensor.' ~ id ~ '_activity') %}
              outline: solid 1px var(--warning-color);
              {% if activity in ['Automotive','Cycling','Walking'] %}
              animation: resizing_outline 1s linear infinite;
              {% endif %}
            }

not sure if the config.entity is picked up correctly though. it works if I add it for a person directly

cannot use this var
It will work if

type: map
entity: ... #fictitious option for themeing only
entities:
  ...

and if you have several in “entities” - the style must be applied to a particular marker (which is = “entity”)

yep, thx. will add some anchors then. but the mod needs to change in that case to the actual entity and not the map card

or, try the other style:

  - type: map
    card_mod:
      style:
        ha-map$: |
          {% for entity in config.entities %}
          {% set id = config.entity.entity_id.split('.')[1] %}
          {% set activity = states('sensor.' ~ id ~ '_activity') %}
            {% if activity not in ['Automotive','Cycling','Walking'] %}
              div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                animation: resizing_outline 1s linear infinite;
              }
            {% endif %}
          {% endfor %}

but need to pop in the .marker element there
hmm, not that obvious I am afraid
either in the individual entity under the entities:, or in the for loop on the map entities…

Since you introduced this method of styling the entity in config.entities, could you please help me out going a bit deep to the .marker and set the outline, as Ildar explained above? I can not find the right syntax to go deeper in that ha-entity-marker $: |

setting it globally to the map card works , the challenge lies in applying it to either a single entity, or the for loop. Both need a different path

please have a look if you can find some moment

type: map
entities:
  - entity: device_tracker.demo_home_boy
  - entity: device_tracker.demo_anne_therese
theme_mode: auto
card_mod:
  style:
    ha-map $:
      ha-entity-marker[entity-id="device_tracker.demo_home_boy"] $: |
        .marker {
          outline: solid 4px red;
          border-color: transparent !important;
        }
      ha-entity-marker[entity-id="device_tracker.demo_anne_therese"] $: |
        .marker {
          outline: solid 4px green;
          border-color: transparent !important;
        }

edit: I tried to use loop in the editor, it probably won’t work :zipper_mouth_face: In a regular template it does…

card_mod:
  style:
    ha-map$: |
      {% set entities = [
        {'entity_id': 'device_tracker.demo_home_boy', 'color': 'red'},
        {'entity_id': 'device_tracker.demo_anne_therese', 'color': 'green'}
      ] %}
      {% for entity in entities %}
        ha-entity-marker[entity-id="{{ entity.entity_id }}"] $: |
          .marker {
            outline: solid 4px {{ entity.color }};
            border-color: transparent !important;
          }
      {% endfor %}

did you also test the div:has in the loop, which made the magic happen before?

should be something like:

  - type: map
    card_mod:
      style:
        ha-map$: |
          {% for entity in config.entities %}
            div:has(> ha-entity-marker[entity-id="{{ entity }}"] $: |
              .marker) { outline: solid 4px red; }
          {% endfor %}

but no, this does not work either… the path breaks I suppose, and moving the closing ) doesnt help

with this code in card mod style it is correctly assigned… strange.

type: map
entities:
  - entity: device_tracker.demo_home_boy
  - entity: device_tracker.demo_anne_therese
theme_mode: auto
card_mod:
  style:
    ha-map$: |
      {% set color_mapping = {
        "device_tracker.demo_home_boy": "red",
        "device_tracker.demo_anne_therese": "green"
      } %}
      {% set entities = config.entities | map(attribute='entity') | list %}
      {% for entity in entities %}
      {% set color = color_mapping[entity] %}
      ha-entity-marker[entity-id="{{ entity }}"] $: |
        .marker {
          outline: solid 4px {{ color }};
          border-color: transparent !important;
        }
      {% endfor %}

figured it would be only for the auto entities, but it isnt, because this does also work straight away:

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

so the challenge is to get to the next .marker in the Dom path…

this also works btw:

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

but then we can NOT set the entities as objects, and need to do

entities:
  - person.1
  - person.2
etc

hahaha, try this:

  - type: map
    card_mod:
      style:
        ha-map $: |
          {% for entity in config.entities %}
            {% if is_state(entity,'home') %}
              div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                filter: brightness(1.75);
                outline: solid 4px red !important;
                animation: resizing_outline 1s linear infinite;
              }
            {% endif %}
          {% endfor %}
          @keyframes resizing_outline {
            0% {outline-offset: 0;}
            25% {outline-offset: 5px;}
            50% {outline-offset: 10px;}
            75% {outline-offset: 15px;}
            100% {outline-offset: 20px;}
          }

different effect. :wink:

getting closer with the activity:

  - type: map
    card_mod:
      style:
        ha-map $: |
          {% for entity in config.entities %}
            {% set id = entity.split('.')[1] %}
            {% set activity = states('sensor.' ~ id ~ '_activity') %}
            {% if activity in ['Automotive','Cycling','Walking'] %}
              div:has(> ha-entity-marker[entity-id="{{ entity }}"]) {
                filter: brightness(1.75);
                outline: solid 2px var(--warning-color);
                animation: resizing_outline 1s linear infinite;
              }
            {% endif %}
          {% endfor %}
          @keyframes resizing_outline {
            0% {outline-offset: 0;}
            25% {outline-offset: 5px;}
            50% {outline-offset: 10px;}
            75% {outline-offset: 15px;}
            100% {outline-offset: 20px;}
          }

(condition now is targeted correctly to the entity. Element still the wrong one of course)

for now I’ll settle for this

  - type: map
    card_mod:
      style:
        ha-map $: |
          {% for entity in config.entities %}
            {% set id = entity.split('.')[1] %}
            {% set activity = states('sensor.' ~ id ~ '_activity') %}
            {% if activity in ['Automotive','Cycling','Walking'] %}
              div:has(> ha-entity-marker[entity-id="{{entity}}"] ) {
                outline: solid 2px var(--warning-color);
                border-radius: 50px;
                animation: resizing_outline 1s linear infinite;
              }
            {% endif %}
          {% endfor %}
          @keyframes resizing_outline {
            0% {outline-offset: 0;}
            25% {outline-offset: 5px;}
            50% {outline-offset: 10px;}
            75% {outline-offset: 15px;}
            100% {outline-offset: 20px;}
          }

the added border-radius makes it practically identical… hurray…

(cant stand not being able to find the correct syntax to target the .marker though, and not being able to set it on an individual entity in the entities list)

Hi,

I really read tons of posts, but I still don’t get it.

I just want the title (“Piano terra - Luci”) be 10px.
I tried:

and I tried:

and many other permutations, without luck.

What am I missing?

Thank you

F.

stack cards dont have the ha-card element, and require the use of custom:mod-card

so use:

type: custom:mod-card
card:
  type: vertical-stack
  cards:

you can modify the marker for individual entities like this, but it can’t be used in Jinja loop. the problem is in the ‘$: |’ cardmod inserts into the style as a string

type: map
entities:
  - entity: device_tracker.demo_home_boy
  - entity: device_tracker.demo_anne_therese
theme_mode: auto
card_mod:
  style:
    ha-map $:
      ha-entity-marker[entity-id="device_tracker.demo_home_boy"] $: |
        .marker {
          outline: solid 4px red;
          border-color: transparent !important;
        }
      ha-entity-marker[entity-id="device_tracker.demo_anne_therese"] $: |
        .marker {
          outline: solid 4px green;
          border-color: transparent !important;
        }