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

Yes, it sticks it at the top and stays there when your scroll the page. In my setup I have hidden the HA header bar completely (which thankfully works with new released Kiosk Mode module). And then I use my own statusbar that sticks to the top of my screen.

And at the bottom of my screen I created another horizontal stack with button-cards, to use as the navigation bar to each tab. Which uses bottom variable, making it stick at the bottom.

For that you need mod-card, otherwise you canā€™t make a stack card sticky as you know. This has worked for me since ever I used it like 2 years ago. But since the latest HA update, it doesnā€™t work anymore. Seeing as how sticky is just a CSS variable, I think we just need to use a different path in card-mod.

nice, I never had that, and it indeed seems very useful. I do still use the main view icons in the header bar, but have a dashboard menu stack, so I can always have a direct link to those, without having to slide I the menu from the left. We all have our use case :wink:

would be great if we could fine the correct element again.

As for the icon change, with has been broken since 3.1.5ā€¦ or maybe I need another element for that too?

I think there are more stuff going on with card-mod, I also noticed this line in console You may not be getting optimal performance out of card-mod. while I do have it loaded as a front_end plugin. There is a github ticket for here as well: Performance warning is always showing on 2023.4.0b5 Ā· Issue #267 Ā· thomasloven/lovelace-card-mod (github.com)

I wonder if the performance notice is just a bug that it says that, or it actually isnā€™t loaded properly as a front_end module anymore for better performance.

Edit: @Mariusthvdb sticky element was broken due to Kiosk Mode module. I always used to hide my header with card-mod theme. However, since that was broken I decided to try the new Kiosk Mode at teh same time as when I upgraded everything else. Disabling Kiosk Mode, fixes sticky cards again.

Btw, I see this warning even if a view w/o card-mod styles is open.
Win+Chrome.

yes. I am back to using my edited 3.1.4 + fix ā€¦ see: 3.2.2 does not change icon in views via card-mod-theme Ā· Issue #268 Ā· thomasloven/lovelace-card-mod Ā· GitHub

still seeing the warning, but at least all my icons change as they should (and my header classes work :wink: )

btw, the only change there was the original:

querySelector("app-drawer-layout partial-panel-resolver, mwc-drawer partial-panel-resolver")

hack as we found in the #beta, so not any further change after that

Using global macros

HA 2023.4 introduced Macros feature which may also be used for card-mod.

Consider this simple case:
ā€“ some CO2 value is displayed in many places on cards of different types;
ā€“ you want to colorize this info dependingly on the value (like ā€œgreen if < 500 ppm, ā€¦ā€).

Note: a similar output for an icon may be achieved by Custom UI.

Earlier we had to repeat same logic for every card.
Now we can use a global macro like this simple one:

{% macro test_color_co2(input_COLOR_CO2) -%}
  {%- if input_COLOR_CO2 | int <= 500 -%}
    color: green !important;
  {%- elif input_COLOR_CO2 | int <= ... -%}
    color: orange !important;
  {%- elif input_COLOR_CO2 | int <= ... -%}
    color: red !important;
  {%- else -%}
    color: magenta !important;
  {%- endif -%}
{%- endmacro %}

Then this macro is used for every card:

  - type: entities
    entities:
      - entity: sensor.xiaomi_cg_1_co2
        card_mod:
          style: |
            :host {
              {% from 'test_macro.jinja' import test_color_co2 -%}
              {{ test_color_co2(states(config.entity)) }}
            }
  ...
  - type: entity
    entity: sensor.xiaomi_cg_1_co2
    card_mod:
      style: |
        .info {
          {% from 'test_macro.jinja' import test_color_co2 -%}
          {{ test_color_co2(states(config.entity)) }}
        }
  ...
  - type: button
    entity: sensor.xiaomi_cg_1_co2
    show_name: true
    show_icon: false
    show_state: true
    card_mod:
      style: |
        .state {
          {% from 'test_macro.jinja' import test_color_co2 -%}
          {{ test_color_co2(states(config.entity)) }}
        }

image
This simple example demonstrates how a complex logic may be defined in one place and then used in many places.

5 Likes

Been experimenting with that same feature yes! Very nice, thanks for the write up Ildar.

My main usage would be the power sensors coloring along with their wattage

I do have a worry though, since this is all Jinja templates. They are evaluated in the backend. Server side. First of all, that might not be good for the efficiency . Secondly, if used heavily , I wonder if this wonā€™t slowdown the Frontend.

Ofc it wonā€™t make a difference if you already had these templates in many cards, and now only change to this import.

However, adding this to a new dashboardā€¦ I am truly worried/interestedā€¦.

One specific ask: personally I would only have these macros spit out the color, and keep the key word color: inside the card_mod style. This way you can easily see what your are doing without going to the templates folder and check

Sure, but imagine a more complex case: you need to style more than one property. In the simplest case like described above - yes, your alternative seems to be more descriptive.

Imho, it would not make it any more cluttered with more than the 1 mod. compare your example:

with this:

  - type: entity
    entity: sensor.battery_signal_strength
    card_mod:
      style: |
        .info 
         color:  {
                      {% from 'customize_macros.jinja' import signal_strength_color -%}
                      {{ signal_strength_color(states(config.entity)) }}
                 }

and use something like:

{% macro signal_strength_color(entity_id) %}
  {% if states(entity_id) >= -50) %} darkgreen
  {% elif states(entity_id) >= -60) %} green
  {% elif states(entity_id) >= -67) %} lightgreen
  {% elif states(entity_id) >= -70) %} gold
  {% elif states(entity_id) >= -80) %} orange
  {% else %} red
  {% endif %}
{% endmacro %}

or shorter:

{% macro signal_strength_color(entity_id) %}
  {% set state = states(entity_id) %}
  {% if state >= -50) %} darkgreen
  {% elif state >= -60) %} green
  {% elif state >= -67) %} lightgreen
  {% elif state >= -70) %} gold
  {% elif state >= -80) %} orange
  {% else %} red
  {% endif %}
{% endmacro %}

have to test some further, but I feel the actual card would be better readable, and the same goes for the custom_template macro definition.

this would be a nice one too:

{% macro battery_color(entity_id) %}
  {% set state = states(entity_id) %}
  {% if state in ['unavailable','unknown'] %} steelblue
  {% elif state > 75) %} green
  {% elif state > 50) %} gold
  {% elif state > 25) %} orange
  {% elif state > 10) %} brown
  {% else %} red
  {% endif %}
{% endmacro %}

:wink:

1 Like

Probably we are talking about different things.
The alternative way ā€œcolor: {{calling macro}}ā€ is absolutely good, but if you need to style like color and background - then you have to place both properties inside a macro.
And there is another case - assume you need to style several properties located on different paths, then these paths are defined inside a macro.

yes, that is correct. For both of these scenarios, I would personally prefer to take the customization out of the path and element. It just makes it much more readable.

the different paths scenario would even be more illustrative of that, because you could simply throw in the same macro in all of these different paths. As long as your card_mod itself describes these correctly (as they do now). It would benefit most!

of course, this is all not yet taking into account the impact this might have on the system/Frontend. Maybe it wont hurt, but I fear it does.
I say that because dumping the jinja templates in the new Profiler logs with

service: profiler.dump_log_objects
data:
  type: RenderInfo

shows all of these jinja templates are registered there too. it might be interesting to see what happens with adding macros to the frontend. since we can not rate limit them like we can in the backend, they might go crazy :wink:

I stopped believing in ā€œRaspberry Pi 4ā€ is enough for HA" more than 2 years ago(((.
We have to use powerful setups anyway, even w/o card-mod.
Or may be I am just a complete noob.

yes, thats a bit of a minimum viable product specification indeedā€¦

consider the fact that my mere card-mod-theme classes already show renders=12168 in the profilerā€¦

Hey all,

I have tried to mod the mini graph card and I want the name color in white but itā€™s look more to grey s.o any ideas?

Here the code

type: custom:mini-graph-card
entities:
  - entity: sensor.wohnzimmer_temperatur_sensor_temperature
    name: Wohnzimmer Temperature
color_thresholds:
  - value: 0
    color: '#87CEFA'
  - value: 18
    color: '#FFA500'
  - value: 25
    color: '#FF6347'
hours_to_show: 6   
points_per_hour: 5
line_width: 5
font_size: 80
height: 70
decimals: 0
name: Living Room
font_size_header: 10
animate: true
show:
  labels: false
  name: true
  icon: false
  state: true
  legend: false
  fill: fade
  icon_adaptive_color: true
card_mod:
  style: |
    .name {
        align-items: center;
        background: var(--black);
        color: white !important;
        border-radius: 26px;
        padding: 10px 10px;
        position: relative !important;
        top: 45px;
    }     
    .states {
        position: relative !important;
        top: -50px;
        left: 10px;
        font-weight: normal !important;
    }  

image

Try defining ā€œopacity: 1ā€.

1 Like

Like this, btw you donā€™t have to use ā€œ!importantā€ if itā€™s not relevant for the property/value use case.

type: custom:mini-graph-card
entities:
  - entity: sensor.temp_woonkamer
    color: red
color_thresholds:
  - value: 0
    color: '#87CEFA'
  - value: 18
    color: '#FFA500'
  - value: 25
    color: '#FF6347'
hours_to_show: 6
points_per_hour: 5
line_width: 5
font_size: 80
height: 70
decimals: 0
name: Woonkamer
font_size_header: 10
animate: true
show:
  labels: false
  name: true
  icon: false
  state: true
  legend: false
  fill: fade
  icon_adaptive_color: true
card_mod:
  style: |
    .ellipsis {
        opacity: 1 !important;
    }
    .name {
        align-items: center;
        background: black;
        color: white;
        border-radius: 26px;
        padding: 10px 10px;
        position: relative;
        top: 45px;
    }     
    .states {
        position: relative;
        top: -50px;
        left: 10px;
        font-weight: normal !important;
    }

1 Like

Thx both. It works

Cheers

Iā€™m trying to add a media player that is sticky to the bottom of the page. I only want this to show if the player is playing, so I guess the best thing for this is to have it in a conditional card.

I can get the player sticky, but not if I put it in a conditional card.

My code:

type: media-control
entity: media_player.kitchen_display
card_mod:
  style: |
    ha-card {
      --ha-card-background: lightgrey !important;
      border-radius: 0px !important;
      box-shadow: none !important;
    }            
    .card-content {
      padding: 0  !important;
      margin: 0 !important;
    }
    :host {
      z-index: 999 !important;
      position: sticky !important;
      position: -webkit-sticky !important;
      bottom: 0 !important;
    }

Sure you can, I know I have for over 2 years now :wink: If you put it inside a conditional-card, you need to wrap it in a mod-card (mod-card is an option of card-mod), because conditional-card doesnā€™t have a card-element. Itā€™s explained pretty well in the ReadMe:

If youā€™re having troubles, search for mod-card in this thread and youā€™ll find plenty of examples of others using it.

My media-player is more complex as itā€™s inside a condtional-card, which is inside a swipe-card, which is inside a vertical-stack. And that is wrapped inside mod-card, which works. So it should definitely work if you only use conditional-card.

Didnā€™t get any suggestions on how to get this to work with card_mod. Iā€™ll post the work around below. It not as elegant as the card_mod, but it works. Added a color line with a template to change the icon color:

color: >-
      {% if is_state('binary_sensor.htpc_2', 'on')%} yellow {%else%} #44739e
      {%endif%}

This code below worked for months to change the active-state icon color on a template-entity-row, but it no longer works. Not aware of anything changing in HA, maybe chrome updated? Tried other browsers with same result.

The template for ā€œentity-stateā€ is providing the correct state and the card-mod for line spacing is still working, but the icon isnā€™t changing color. Any ideas?

type: entities
entities:
  - type: custom:template-entity-row
    entity: binary_sensor.htpc_2
    icon: mdi:server-network
    state: >-
      {% if is_state('binary_sensor.htpc_2', 'unavailable')%} Off {% else %}
      {{states('binary_sensor.htpc_2') | capitalize}} {%endif%}
    active: '{{ is_state("binary_sensor.htpc_2", "on") }}'
    card_mod:
      style: |
        div#wrapper { 
          min-height:  10px; 
          }
        div#wrapper {
          height:  25px; 
          }
        :host {
         --paper-item-icon-active-color: yellow;
         --state-unavailable-color: #44739e; 
        }