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

Styling custom:numberbox-card:

code
type: entities
entities:
  - type: section
    label: colored icon (2 options)
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        :host {
          --paper-item-icon-color: red;
        }
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        state-badge {
          color: cyan;
        }
  - type: section
    label: colored text
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    secondary_info: last-changed
    card_mod:
      style: |
        .grid-content.grid-left {
          color: red;
        }
        .grid-content.grid-right {
          color: magenta;
        }
        .grid-content.grid-left .secondary {
          color: cyan;
        }
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    secondary_info: default color
    card_mod:
      style: |
        .grid-content.grid-left {
          color: red;
        }
        .grid-content.grid-left .secondary {
          color: initial;
        }
  - type: section
    label: colored buttons, value & unit
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        .body .padr {
          color: red;
        }
        .body .padl {
          color: cyan;
        }
        .body .cur-num {
          color: orange;
        }
  - type: section
    label: colored value & opaque unit (diff.colors)
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        .body .cur-num {
          color: orange;
        }
        .body .cur-unit {
          color: cyan;
          opacity: 1;
        }
  - type: section
    label: spacings
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        .body .padr {
          padding-right: 32px;
        }
        .body .padl {
          padding-left: 32px;
        }
        .body .cur-unit {
          margin-left: 32px;
        }
  - type: section
    label: Full width
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    icon: false
    name: false
    card_mod:
      style: |
        .body .cur-box {
          display: grid;
          grid-template-columns: 1fr 10fr 1fr;
          place-items: center;
        }
  - type: section
    label: Bordered row
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    name: Bordered row
    border: true
    card_mod:
      style: |
        :host {
          --ha-card-box-shadow: 5px 5px 8px red, 10px 10px 8px green, 5px 5px 8px blue;
        }

Changed “on-edit” color:
zserfvt

Summary
type: entities
entities:
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        .body .cur-num {
          color: cyan;
        }
        .body .upd {
          color: magenta;
        }
        .body .cur-unit {
          color: red;
        }

Vertically aligned buttons:
image

code
type: horizontal-stack
title: 1 column
cards:
  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: start;
            }
            .body .padr {
              padding-left: 0px;
            }
            .body .padl {
              padding-left: 0px;
            }
  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: center;
            }
  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: end;
            }
            .body .padr {
              padding-right: 0px;
            }
            .body .padl {
              padding-right: 0px;
            }

Vertical spacing for buttons:
image

code
type: horizontal-stack
title: 1 column, vertical spacing
cards:
  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: center;
            }
  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: center;
            }
            .body .padl {
              padding-bottom: 0px;
            }
            .body .padr {
              padding-top: 0px;
            }
  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: center;
            }
            .body .padl {
              padding-bottom: 32px;
            }
            .body .padr {
              padding-top: 32px;
            }

Horizontal alignment for buttons & values:
image

code
type: entities
entities:
  - type: custom:numberbox-card
    entity: input_number.test_number
    name: Threshold 1
  - type: custom:numberbox-card
    entity: input_number.test_number_2
    name: Threshold 2
  - type: custom:numberbox-card
    entity: input_number.test_number_3
    name: Threshold 3
card_mod:
  style:
    numberbox-card:
      $: |
        ha-card .body .cur-num-box {
          display: grid;
          width: 50px;
          text-align: center;
        }

Custom secondary_info:
Update 03.01.22: since ver. 3.2 it is possible to specify a plain text for secondary_info, so this trick is not required any more - at least for making a custom secondary_info. Note that conditional content in "secondary-info" is still possible only by using card-mod & “:before” method.
image

code
type: entities
entities:
  - type: custom:numberbox-card
    entity: input_number.wait_period_before_alarm_1_xiaomi_roborock_s50_mop_check
    name: Threshold 1
    secondary_info: last-changed
    card_mod:
      style: |
        .grid-content.grid-left .info .secondary ha-relative-time {
          color: transparent;
        }
        .grid-content.grid-left .info .secondary::before {
          color: orange;
          content: "Warning";
        }
  - type: custom:numberbox-card
    entity: input_number.wait_period_before_alarm_2_xiaomi_roborock_s50_mop_check
    name: Threshold 2
    secondary_info: last-changed
    card_mod:
      style: |
        .grid-content.grid-left .info .secondary ha-relative-time {
          color: transparent;
        }
        .grid-content.grid-left .info .secondary::before {
          color: red;
          content: "Critical\A Danger";
          white-space: pre;
        }

How to disable buttons:
image

code
type: entities
title: Locked control
entities:
  - entity: input_boolean.test_boolean
    name: Lock input_number
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    tap_action: none
    card_mod:
      style: |
        .body .padl {
          {% if is_state('input_boolean.test_boolean','on') %}
            color: var(--disabled-text-color);
          {% endif %}
        }
        .body .padr {
          {% if is_state('input_boolean.test_boolean','on') %}
            color: var(--disabled-text-color);
          {% endif %}
        }
        :host {
          {% if is_state('input_boolean.test_boolean','on') %}
            pointer-events: none;
          {% endif %}
        }

How to disable whole row (a case with a toggle button):
image

image

code
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    toggle_entity: input_boolean.test_boolean_2
    card_mod:
      style:
        ha-entity-toggle $:
          ha-switch $: |
            .mdc-switch .mdc-switch__thumb input {
              {% if is_state('input_boolean.test_boolean','on') %}
                pointer-events: none;
              {% endif %}
            }
          .: |
            ha-switch {
              {% if is_state('input_boolean.test_boolean','on') %}
                --switch-unchecked-button-color: var(--disabled-text-color);
                --switch-checked-button-color: var(--disabled-text-color);
              {% endif %}
            }
        .: |
          .padl {
            {% if is_state('input_boolean.test_boolean','on') %}
              color: var(--disabled-text-color);
            {% endif %}
          }
          .padr {
            {% if is_state('input_boolean.test_boolean','on') %}
              color: var(--disabled-text-color);
            {% endif %}
          }
          :host {
            {% if is_state('input_boolean.test_boolean','on') %}
              pointer-events: none;
              color: var(--disabled-text-color);
              --paper-item-icon-color: var(--disabled-text-color);
            {% endif %}
          }
          .grid-content {
            {% if is_state('input_boolean.test_boolean','on') %}
              color: var(--disabled-text-color);
            {% endif %}
          }

Colored background:
By default the background is not transparent.
There are a few ways to make it transparent as well as to change a color:

code
type: entities
title: background
card_mod:
  style: |
    ha-card {
      background: orange;
    }
entities:
  - type: section
    label: default
  - entity: sun.sun
  - type: custom:numberbox-card
    entity: input_number.test_parrots
  - type: section
    label: colored background
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        ha-card {
          background: pink;
        }
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        .grid {
          background: pink;
        }
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        :host {
          --ha-card-background: pink;
        }
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        ha-card {
          --ha-card-background: pink;
        }
  - type: section
    label: transparent background
  - type: custom:numberbox-card
    entity: input_number.test_parrots
    card_mod:
      style: |
        ha-card {
          background: transparent;
        }

Changing a size of “plus” & “minus” icons:
May be achieved by specifying an "--mdc-icon-size" variable.
To decrease the size for both icons:
image

code
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body {
              --mdc-icon-size: 10px;
            }

To decrease the size for one icon only:
изображение

code
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padr {
              --mdc-icon-size: 8px;
            }

To increase the size a user must be aware of top & bottom padding - otherwise the row may be higher than other rows; the row’s height should not be higher than 40px - i.e the icons’ height should not be higher than 40px.
Check this example:
изображение

code
type: horizontal-stack
cards:
  - type: entities
    entities:
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padr {
              --mdc-icon-size: 8px;
            }
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padl {
              --mdc-icon-size: 8px;
            }
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padl {
              --mdc-icon-size: 40px;
            }
      - type: section
  - type: entities
    entities:
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
      - type: section

Here is how to fix the row’s height by setting zero "padding-top" & "padding-bottom":
изображение

code
type: horizontal-stack
cards:
  - type: entities
    entities:
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padr {
              --mdc-icon-size: 8px;
            }
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padl {
              --mdc-icon-size: 8px;
            }
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padl {
              --mdc-icon-size: 40px;
              padding-top: 0px;
              padding-bottom: 0px;
            }
      - type: section
  - type: entities
    entities:
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
      - type: section
      - type: custom:numberbox-card
        entity: input_number.test_parrots
      - type: section

Another solution (simpler & more elegant) was provided by the author of this card here:
scale both icons:

      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body ha-icon {
              transform: scale(2);
            }

scale one icon:

      - type: custom:numberbox-card
        entity: input_number.test_parrots
        card_mod:
          style: |
            .body .padl {
              transform: scale(2);
            }

This method does not require changing paddings!


More examples are described here.

4 Likes

Thank you so much - I didn’t know how to bring the elements together, and I had my indents all wrong

I’ve got it to rotate when my switch is on (thank you for the other examples), but the color won’t change conditionally, yet it will change when I use it with an entitities card.

What causes this to change? Is it the way the glance card works?

e.g. this changes the icon color and rotates it:

entities:
  - entity: switch.night_light
    icon: mdi:fan
    style:
      hui-generic-entity-row:
        $: |
          state-badge {
              {% if is_state('switch.night_light', 'on') %}
              color: green;
              animation: rotation 1.5s linear infinite;
              {% endif %}
          }
          @keyframes rotation {
            0% {
              transform: rotate(0deg);
            }
            100% {
              transform: rotate(360deg);
            }
          }

yet this doesn’t turn the icon green… It’s completely lost me as to why that doesn’t work

type: glance
entities:
  - entity: switch.night_light
    icon: mdi:fan
    tap_action:
      action: toggle
    card_mod:
      style: |
        state-badge {
          {% if is_state('switch.night_light', 'on') %}
            color: green;
            animation: rotation 1.5s linear infinite;
          {% endif %}
          }
          @keyframes rotation {
            0% {
              transform: rotate(0deg);
            }
            100% {
              transform: rotate(359deg);
            }
          }
show_name: false

Read here again this part:


That means that you should:

ahhhh… this was it - it also would explain why when I turned on the switch that the icon ever so briefly flashed green, then went to yellow.

Thank you so much for your patience and help on this - I’ve made a lot of notes as to where I was going wrong by my misinterpretation …

You’re welcome, learn it step by step))

Regarding styling numberbox-card - there is an issue on GitHub:

If you try styling the card as a separate card (not inside Entities card) - there is a problem: the numberbox-card already has the ha-card element, but:

  • card-mod styling does not work;
  • there are errors in Code Inspector when you are using mod-card (the only way to style the card since ha-card does not work) - kind of “mod-card cannot be used with cards which have ha-card element”.

Hi i’m trying hard to vertically center the battery percentage to the phone image on its left with no success.

chrome_LzxQI6ISUT

Here’s the YAML of the glance card I’m using (sorry if it’s a mess, I’m not a pro lol):

type: glance
show_name: false
show_state: true
style:
  div.entity:
    $: |
      state-badge {
        width: 75px;
        height: 75px;
        margin: 4px;
        background-color: rgba(47, 189, 79, 0.4)
      }
  .: |
    div.entity {
      margin-bottom: 0px;
    }
    div.entities {
      padding: 8px 8px 8px 8px;
    }
    div.entities.no-header {
      padding-top: 8px;
      padding-bottom: 0;
    }
    ha-card {
      box-shadow: none;
      backdrop-filter: blur(20px) saturate(150%);
    }
entities:
  - entity: person.carlo
    image: /local/carlo.png
    style: |
      div {
        display: table;
        white-space: pre;
        line-height: 0.5;
        padding: 8px 0 16px 0;
        align-items:center;
        vertical-align: middle;
      }
      div::after {
        content: "\a" url(/local/cellphone-charging_18px_padded.png) "{{ states('sensor.iphone_di_carlo_battery_level') }}%";
        font-size: 12px;
      }
  - entity: person.martina
    image: /local/marty.png
    style: |
      div {
        display: table;
        white-space: pre;
        line-height: 0.5;
        padding: 8px 0 16px 0;
        align-items:center;
        vertical-align: middle;
      }
      div::after {
        content: "\a" url(/local/cellphone-charging_18px_padded.png) "{{ states('sensor.iphone_di_martina_battery_level') }}%";
        font-size: 12px;
      }

Any help will be much appreciated!

Thank you.

very small steps in my case…

EDIT: had a typo… if anyone cares, this code produces this card, with rotating fan, for AC control and visual status :slight_smile:

image

title: Sewing Room
mode: vertical
cards:
  - type: custom:simple-thermostat
    entity: climate.sewing_room_air_conditioner
    step_layout: row
    show_header: false
    name: study
    control: false
  - type: custom:stack-in-card
    mode: horizontal
    cards:
      - type: glance
        show_name: false
        state_color: false
        entities:
          - entity: switch.sewing_room_zone
            icon: mdi:fan
            tap_action:
              action: toggle
            card_mod:
              style: |
                state-badge {
                  {% if is_state('switch.sewing_room_zone', 'on') %}
                    color: green;
                    animation: rotation 1.5s linear infinite;
                  {% endif %}
                  }
                  @keyframes rotation {
                    0% {
                      transform: rotate(0deg);
                    }
                    100% {
                      transform: rotate(359deg);
                    }
                  }
      - type: custom:mini-graph-card
        entities:
          - entity: sensor.sewing_room
            name: Temperature
            smoothing: true
            show_fill: true
          - entity: sensor.sewing_target_temp
            name: Target
            smoothing: true
          - entity: switch.sewing_room_zone
            y_axis: secondary
            color: orange
            show_line: false
            show_points: false
            show_legend: false
            aggregate:func: max
            smoothing: false
        hours_to_show: 24
        points_per_hour: 4
        line_width: 2
        font_size: 90
        animate: true
        show:
          name: false
          icon: false
          state: false

Were you referring there to this change where one should explicity use a card_mod: section?

  - entity: binary_sensor.internet_connection
    card_mod:
      style:

I did some updates over the weekend and only tonight I noticed my badge icon colours not working anymore, similar to the user you replied to. I’ve searched quite a bit, but I’m struggling to find an answer. I’ve tried to retrace my steps.

This used to work:

  - entity: binary_sensor.internet_connection
    card_mod:
      style:
        ha-state-label-badge:
          $:
            ha-label-badge:
              $:
                .value: |
                  ha-icon {
                    color: {{ "var(--state-icon-active-color)" if is_state(config.entity, 'on') }} !important;
                  }

The one change I made was the one referred to in the README, which is to include card-mod in the frontend section to get the performance improvements (I’ve installed via HACS):

frontend:
  themes: !include_dir_merge_named themes
  extra_module_url:
    - /local/custom.js
    - /hacsfiles/lovelace-card-mod/card-mod.js

I’ve removed the old module definition from resources:, I’ve cleared my cache and checked that I can reach card-mod.js via the browser, so that all seems to be working fine.

I don’t know what I’m missing and would appreciate any help.

HA is changing, I am trying to keep my posts updated - see this post, it was updated a month ago.
If you open Code Inspector you will see that there is no ha-icon element an the value anymore.

Here are your solutions:
1st - your example, does not work
2nd, 3rd - from the post,
4th - one more, new solution.
image

type: custom:badge-card
badges:
  - entity: binary_sensor.net_is_available_internet
    card_mod:
      style:
        ha-state-label-badge:
          $:
            ha-label-badge:
              $:
                .value: |
                  ha-icon {
                    color: {{ "var(--state-icon-active-color)" if is_state(config.entity, 'on') }} !important;
                  }
  - entity: binary_sensor.net_is_available_internet
    card_mod:
      style: |
        :host {
          --label-badge-text-color: magenta;
        }
  - entity: binary_sensor.net_is_available_internet
    card_mod:
      style:
        ha-state-label-badge:
          $:
            ha-label-badge:
              $: |
                .badge-container .label-badge .value {
                  color: red;
                }
  - entity: binary_sensor.net_is_available_internet
    card_mod:
      style:
        ha-state-label-badge:
          $: |
            ha-state-icon {
              color: cyan;
            }

Please, for everyone:
These posts were made for a GOOD START, not to replace a self-learning and self-exploration )).

1 Like

incredible work man… really impressive
thank you for the example…

about custom:numberbox-card…
I tried to change with card-mod the default red value when I press + o -.
If I try to color the unit, this value will be always colored… but I can’t change only the “set value”… i’m trying to have default color and a var-primary-color when press + o -.
can anyone try to do that?
thank you again

Hi everyone! I haven’t updated anything in my code but noticed today that my colors are not changing per state as they usually do. Does anyone know what I need to change to fix this? I’ve been working just fine for months

This is all within a picture-element for my floorplan dashboard:

  - type: picture-elements
    image: /local/ui/floorplan/Floors/NightNoOne.png
    style: |
        ha-card:first-child {
          background: rgba(42, 46, 48, 1)
        }
          ha-card {
          --my-icon-color: {% if states('sensor.garbage_waste')|int <= 1 %} #A36733 {% else %} darkgrey {% endif %}
          }
          ha-card {
          --my-recycle-color: {% if states('sensor.recycling')|int <= 1 %} #5C7AD3 {% else %} darkgrey {% endif %}
          }
          ha-card {
          --my-yard-color: {% if states('sensor.yard_waste')|int <= 1 %} #2A8059 {% else %} darkgrey {% endif %}
          } 

        - type: state-icon
          entity: sensor.recycling
          style:
            "--iron-icon-height": 1.7vw
            "--iron-icon-width": 1.7vw
            "--paper-item-icon-color": "var(--my-recycle-color)"
            align-items: center
            display: flex
            height: 3vw
            justify-content: center
            left: 56%
            margin-left: "-1.5vw"
            margin-top: "-1.5vw"
            top: 5%
            transform: scale(1.2)
            width: 3vw
          tap_action:
            action: none

Se the updated post, section “Changed “on-edit” color”.

Disable a door control conditionally:
image

type: entities
title: Locked cover
entities:
  - entity: input_boolean.test_boolean
    name: Lock the door
  - entity: cover.garage_door
    tap_action:
      action: none
    card_mod:
      style: |
        :host {
          {% if is_state('input_boolean.test_boolean','on') %}
            color: var(--disabled-text-color);
            --paper-item-icon-color: var(--disabled-text-color);
            pointer-events: none;
          {% endif %}
        }

And similarly for other input controls, like for:


More examples are described here.

great man, so many thanks… of course it works…

now i’m triyng to spacing up and down the “+” and “-” in this setting:

  - type: entities
    entities:
      - type: custom:numberbox-card
        entity: input_number.test_parrots
        name: false
        icon: false
        card_mod:
          style: |
            .body .cur-box {
              display: grid;
              place-items: center;
            }

i don’t really understand how I can use padding and .body .cur-box

Hi Ildar, would you mind taking a look at my post? It’s a small thing I need to adjust but it’s driving me crazy, maybe you can help me! Thank you.

Working with ::after is not a small issue & it is better to be implemented in other way.

@Ildar_Gabdullin If you have a chance, could you review my post as well? Do you know why the ha-card variable is no longer working for me? Maybe there is a new path to do what I have been.

I have a garbage sensor that counts down the days before I need to put the garbages out. Within a day of putting out, it changes the icon to the appropriate color, otherwise, it stays gray. I was accomplishing this by specifying global ha-card: --my-icon-color provided with an if statement then provided “–paper-item-icon-color”: “var(–my-icon-color)” under the state-icon type
but that is no longer working.

Any ideas?

  1. Your code is too long. You should better provide a short MWE (google it) to people to simplify the work.
  2. Please see my accumulative post for picture-elements (1st post of the thread → consolidated post → post for picture-elements), may be it will answer your questions.
  3. First what I see in you code - wrong indentations:

Use Code Inspector & see what should be changed.
Open card-mod page on GitHub, it contains some tutorials.
I am not a CSS expert too))
Probably you should play with top & bottom paddings for buttons.