šŸ”¹ Card-mod - Super-charge your themes!

@Ildar_Gabdullin @Mattias_Persson

finally I got this:

    card-mod-root-yaml: |
      paper-tab[aria-label='Presence'] ha-icon $ ha-svg-icon $: |
        path {
        {% if is_state('input_boolean.test', 'on') %}
           d: path('M16,7V3H14V7H10V3H8V7H8C7,7 6,8 6,9V14.5L9.5,18V21H14.5V18L18,14.5V9C18,8 17,7 16,7Z');
        {% else %}
           d: path('M20.84 22.73L15.31 17.2L14.5 18V21H9.5V18L6 14.5V9C6 8.7 6.1 8.41 6.25 8.14L1.11 3L2.39 1.73L22.11 21.46L20.84 22.73M18 14.5V9C18 8 17 7 16 7V3H14V7H10.2L17.85 14.65L18 14.5M10 3H8V4.8L10 6.8V3Z');
        {% endif %}
        }

to work, and have a color set for that icon under the .: | section using

        paper-tab[aria-label='Presence'] {
          color: {{state_attr('sensor.family_home','icon_color')}};
        }

so thatā€™s a start. However, and its a big caveat, it only works in Chromeā€¦ No way I can get it to show in my Safari browser or my App just yet. The app might be a cache thing, always hard to reset that. But Safari is always immediate, so a problem stillā€¦

Mattiasā€™s style does work after all, I had positioned in the wrong section:

    card-mod-root-yaml: |
      paper-tab[aria-label='Presence'] ha-icon$: |
        ha-svg-icon {
        {% if is_state('input_boolean.test', 'on') %}
           content: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='green' d='M16,7V3H14V7H10V3H8V7H8C7,7 6,8 6,9V14.5L9.5,18V21H14.5V18L18,14.5V9C18,8 17,7 16,7Z'/%3E%3C/svg%3E");
        {% else %}
           content: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='gray' d='M20.84 22.73L15.31 17.2L14.5 18V21H9.5V18L6 14.5V9C6 8.7 6.1 8.41 6.25 8.14L1.11 3L2.39 1.73L22.11 21.46L20.84 22.73M18 14.5V9C18 8 17 7 16 7V3H14V7H10.2L17.85 14.65L18 14.5M10 3H8V4.8L10 6.8V3Z'/%3E%3C/svg%3E");
        {% endif %}
        }

but, always something, this doesnt work with the color set under the .: |

If this turns out to be the only browser wide syntax to get the icon to change, I must add the color in the content, like Mattias did above for those icons I want to change.

thereā€™s another issue though,

if I change the working test config for the tab ['Presence'] to another ['Settings motion'] (which does work in the coloring templates, card_mod throw an error

hmm. not sure if this is worth the trouble pursuingā€¦ feels a bit too ,much of a hack, while the motto is weā€™re streamliningā€¦

Maybe we should try to carve out the functionality of the old Custom Header, if only for this.

@Mariusthvdb
Sorry for not answering - was busy with restoring my HA setup, many things broke after some latest updates.

Now I faced with a weird bug with card-mod-theme.

Letā€™s create this card:

type: entities
entities:
  - entity: sensor.service_unavailable_value
  - entity: zone.home
    card_mod:
      class: class-row-red
  - type: custom:fold-entity-row
    head:
      entity: sun.sun
    open: true
    card_mod:
      style: |
        div#head {
          color: red !important;
        }
    entities:
      - sun.sun
      - sun.sun
      - sun.sun

image

Note that:

  • sensor.service_unavailable_value is always unavailable;
  • class-row-red does not work w/o a card-mod-theme.

Then letā€™s create a simple card-mod-theme:

cm_minimal:

  card-mod-row-yaml: |
    .: |

      :host(.class-row-red) {
        color: red;
        --paper-item-icon-color: red;
      }

      hui-generic-entity-row .text-content {
        {% if states(config.entity) in ['unavailable','unknown'] %}
          color: var(--state-unavailable-color);
        {% endif %}
      }

Now the card looks like:
image

The theme styles are applied, the ā€œdiv#headā€ style is not applied:

Now letā€™s change a theme - remove the 2nd style:

cm_minimal:

  card-mod-row-yaml: |
    .: |

      :host(.class-row-red) {
        color: red;
        --paper-item-icon-color: red;
      }

And now the card looks like:
image

The only left theme style is applied, the ā€œdiv#headā€ style is applied too:

Why is this happening?

P.S. I reinstalled fold-entity-row, cleaned a cache with no effect.


Updated 20.02.22:
Registered an issue:

Updated 22.04.22:
Solution found and described in the issue.

I have this theme made:

I see in the developersā€™ tools that the background image is added but overridden by the primary-background-color.

Knipsel

But can not find out where this is and why?

not using the class option at all just yet, so I figure letā€™s start with something thatā€™s system wide in my config.

  card-mod-card: |
    .card-header {
      font-weight: 300;
      letter-spacing: 0px;
      /*background: radial-gradient(var(--primary-color),var(--card-background-color));*/
    }

is what I use for all my headers, and in every individual card I add:

card_mod:
  style: |
    .card-header {
      background-color: var(--background-color-off);
      color: var(--text-color-off);
      padding-top: 0px;
      padding-bottom: 0px;
      margin: 0px 0px 16px 0px;
    }

or that exact same thing, but without a margin line.

which I guess would be globalized to:

  card-mod-card: |
    .card-header(.class-header-margin) {
      font-weight: 300;
      letter-spacing: 0px;
      background-color: var(--background-color-off);
      color: var(--text-color-off);
      padding-top: 0px;
      padding-bottom: 0px;
      margin: 0px 0px 16px 0px;
    }

    .card-header(.class-header-no-margin) {
      font-weight: 300;
      letter-spacing: 0px;
      background-color: var(--background-color-off);
      color: var(--text-color-off);
      padding-top: 0px;
      padding-bottom: 0px;
    }

however, if I try to use those in my card configs like

type: entities
title: Hue motion sensor switches
state_color: true
show_header_toggle: true
card_mod:
  class: class-header-no-margin

or

type: entities
title: Hue motion sensor switches
state_color: true
show_header_toggle: true
class: class-header-no-margin

nothing happensā€¦
is there some syntax error here?
please have a look, thanks!

Hello. Iā€™m looking for help.
Iā€™m trying to change the text color in the state badge according with the sensor state but canā€™t find the solution.
Can anyone help me?
Thatā€™s my configuration, and I want when the window is open(aberta) the color of the letters change to green.
Thanks



This is not about card-mod-theme, you should ask these questions in another topic.
Your case was described here.

Thank you for your help.

@Mariusthvdb
AFAIK class is a property of a whole card - not itā€™s header.

cm_card_class:

  card-mod-card-yaml: |
    .: |
      ha-card.class-card-1.type-entities .card-header {
        background-color: grey;
        color: red;
      }
  - type: entities
    title: class-1
    card_mod:
      class: class-card-1
    entities:
      - entity: sun.sun
      - entity: sun.sun

ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ

Answering from a mobile, not sure - but just in case try adding !important

thanks Ildar, this is promising indeed!
Because I need these on more than only type: entities cards, I tested:

    card-mod-card-yaml: |
      .: |
        ha-card.class-header-margin .card-header {
          font-weight: 300;
          letter-spacing: 0px;
          background-color: var(--background-color-off);
          color: var(--text-color-off);
          padding-top: 0px;
          padding-bottom: 0px;
          margin: 0px 0px 16px 0px;
        }

        ha-card.class-header-no-margin .card-header {
          font-weight: 300;
          letter-spacing: 0px;
          background-color: var(--background-color-off);
          color: var(--text-color-off);
          padding-top: 0px;
          padding-bottom: 0px;
        }

too, and this seems to work fine.

only thing this blocks now is another default card header:

  card-mod-card: |
    .card-header {
      font-weight: 300;
      letter-spacing: 0px;
      /*background: radial-gradient(var(--primary-color),var(--card-background-color));*/
    }

so all my cards without the class now cant use this anymoreā€¦ always a challenge

Combine two styles in one card-mod-card-yaml

I dont think I follow.

what I need:

  • the 2 different classes, to set on many of my cards.
  • the default mod, which needs to be applied to all card with a header, so also the ones without any of the 2 classes above

before I used the 2 classes, the card-mod-card was active on all cards (as I want) and I set extra header mods in the individual cards verbosely. I now want to do that with the 2 classes.

I think this works:

    card-mod-card-yaml: |
      .: |
        ha-card.class-header-margin .card-header {
          background-color: var(--background-color-off);
          color: var(--text-color-off);
          padding-top: 0px;
          padding-bottom: 0px;
          margin: 0px 0px 16px 0px;
        }

        ha-card.class-header-no-margin .card-header {
          background-color: var(--background-color-off);
          color: var(--text-color-off);
          padding-top: 0px;
          padding-bottom: 0px;
        }

        ha-card .card-header {
          font-weight: 300;
          letter-spacing: 0px;
          /*background: radial-gradient(var(--primary-color),var(--card-background-color));*/
        }

which is kind of cool, and even allows me to do this now:

  - type: custom:auto-entities
    card:
      type: entities
      title: Running Automations
      card_mod: &header
        class: class-header-margin
        style: |
          .card-content {
            max-height: 400px;
            overflow-y: scroll;
          }

(set the (now generic) class, and an additional scrolling mod in the individual card). Really nice!

To make some more magic, I copy that complete set with an anchor to several cards below :wink:

This is what I was talking about - describe 2 class-card and 1 default card:

  - type: vertical-stack
    title: class-card
    cards:
      - type: entities
        title: class-1
        card_mod:
          class: class-card-1
        entities: &ref_entities
          - entity: sun.sun
          - entity: sun.sun
            card_mod:
              class: class-row-red
      - type: entities
        title: class-2
        card_mod:
          class: class-card-2
        entities: *ref_entities
      - type: entities
        title: default
        entities: *ref_entities
cm_card_class:

  card-mod-card-yaml: |
    .: |
      ha-card.class-card-1.type-entities .card-header {
        background-color: grey;
        color: red;
      }
      ha-card.class-card-2.type-entities .card-header {
        background-color: yellow;
        color: magenta;
      }
      ha-card.type-entities .card-header {
        background-color: green;
        color: cyan;
      }

  card-mod-row-yaml: |
    .: |
      :host(.class-row-red) {
        color: red;
        --paper-item-icon-color: red;
      }

1 Like

well, thats what I did in my post above yours, so yep, confirm that to be working just fine now.

even without the .type-entities

Ive updated my gist with what I use currently

After much searching I didnā€™t find any recommendations on how to do this.

The code below allows you to change the CSS of an Icon in the Lovelace Header based on a particular state.

  card-mod-theme: ios-dark-mode
  card-mod-root: |
      paper-tab[aria-label="Heating"] {
          {% if ( (states('climate.bedroomheatpump') != 'off') or (states('climate.loungeheatpump') != 'off') ) %}
          color: orange;
          {% endif %}
        	}

A couple of explanations.

The [aria-label=ā€œHeatingā€] filters the CSS to only apply to the paper-tab div that meets that attribute. You can read more on CSS attribute selection here: https://www.geeksforgeeks.org/css-attribute-selector/

The JINJA2 then tests a regular IF statement to apply the CSS

so I suddenly experienced odd behavior in 1 of my dashboards on mobile (not on desktop) where my tab icons could no longer move left/right, even though the chevrons are visible.

Turns out this template caused it:

        /* only show when on Chrome (a bit if a hack since we dont have 'this.device_id' */
        paper-tab[aria-label='Cast'] {
          {% set device = 'sensor.browser_chrome_nc' %}
          {% if states(device) in ['unavailable','unknown'] or
                is_state_attr(device,'visibility','hidden') %} display: none
          {% elif not is_state_attr(device,'path','/ui-develop/cast') %} color: blue
          {% else %} color: red
          {% endif %};
        }

even though it works perfectly in itself, showing/hiding/coloring the icon as per conditions.

which was as good as it could get, trying to show the Cast tab only on a Chrome browser. I still dont understand why it interferes with the regular app-header behavior, but it did.

If anyone could explain, please dont hold back :wink:

Hey - I have a question on card-mod and themes.

I want to apply generic CSS to any theme - but donā€™t get it done. The theme code should not be theme specific. It seem that card-mod allow only to inject CSS for a particular theme but not for all themes.

Is there any way to do this? Basically I look for a way to use this more generic:

my-awesome-theme:
  card-mod-theme: my-awesome-theme

For example:

default:
  card-mod-theme: default

ā€¦ knowing that this does not work :slight_smile:

Reason why Iā€™m asking:

I donā€™t want to copy the same CSS code into multiple themes. It should be valid for all themes.

Thanks

anything you configure in your theme:

my-awesome-theme:
  card-mod-theme: my-awesome-theme

will be injected in another theme, by adding that card-mod-theme:

frontend:
  themes:
    my_theme:
      card-mod-theme: my-awesome-theme
      # rest of the settings

you can see the card-mod-theme as 1 big anchor, but better, because it can be configured in a dedicated file.

You can even add that to a true anchor and copy it easily with any other setting you would use (but dont add to the card-mod-theme)
See below: since I have all of my themes (except the card-mod-theme) in 1 file, I copied that to all of them using:

Dark blue:

  <<: &generic
    card-mod-theme: custom-header
    ha-card-border-radius: 0px
    ha-card-box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19)
    restriction-lock-row-margin-left: calc(100% - 25px) #95%
    restriction-regular-lock-color: red
    restriction-lock-opacity: 0.8
    alert-color: red
    error-color: var(--primary-color)


All other themes
  <<: *generic

Wow - thank you so much for this fast response.

Iā€™ve already tried it and itā€™s working like a charm. This is amazing!

This really will help me a lot!

One last question that I did not yet sort out: Any chance to add this to the default theme? Or inject <<: *generic into the default theme?

no you shouldnā€™t do that.

you can however create a new theme, and leave it empty except for the generic bit.

It used to work before, but since the introduction of modes this stopped (was a bug in the first place, so never meant to be working)

Default adjusted:

  <<: *generic