Custom:button-card insert state or attribute into CSS

Question:

Is it possible to inject state or state attribute into CSS? I want to show both the icon animation and have the gradient background linked to an attribute, in this case the battery level of my vacuum. Any ideas as to how I can achieve this?

For example this works for card gradient background in vanilla button with card-mod but doesn’t in button-card. Using {{state_attr('vacuum.dustin', 'battery_level')}}% in place of set percentage.

Working code for vanilla button with card mod (but can’t animate icon):

type: button
icon: mdi:robot-vacuum
entity: sensor.dustin_battery
name: battery level background gradient
show_state: true
show_icon: true
card_mod:
  style: |
    ha-card {
      --ha-card-background: linear-gradient(0deg, rgba(46.7,46.7,46.7,1) 0%,
         rgba(46.7,46.7,46.7,1) {{state_attr('vacuum.dustin', 'battery_level')}}%,
         rgba(92,24,215,1) 100%)
    }

image

This works fine with hardcoded percentage @ 50%, see image:

type: custom:button-card
icon: mdi:robot-vacuum
extra_styles: |
  @keyframes charge {
    75%  {color: cyan;}
styles:
  icon:
    - animation: charge 5.25s ease-in infinite
  card:
    - background: >-
        linear-gradient(0deg, rgba(46.7,46.7,46.7,1) 0%,
        rgba(46.7,46.7,46.7,1) 50%,
        rgba(92,24,215,1) 100%)

charging static background

This does not work:

type: custom:button-card
icon: mdi:robot-vacuum
extra_styles: |
  @keyframes charge {
    75%  {color: cyan;}
styles:
  icon:
    - animation: charge 5.25s ease-in infinite
  card:
    - background: >-
        linear-gradient(0deg, rgba(46.7,46.7,46.7,1) 0%,
        rgba(46.7,46.7,46.7,1) {{state_attr('vacuum.dustin', 'battery_level')}}%,
        rgba(92,24,215,1) 100%)

Thanks in advance.

Nice idea!


  card:
    - background: >
        [[[ return "linear-gradient(0deg, rgba(46.7,46.7,46.7,1) 0%,
        rgba(46.7,46.7,46.7,1)" +
        states['sensor.your_sensor_entity_id'].attributes.battery_level + "%,
        rgba(92,24,215,1) 100%)" ]]]

returns:

1 Like

Thanks, I’ll test that out. I think I did try it that way but missed the ‘+’ :man_facepalming:.

Cintax on reddit helped me out with card-mod so I’ve gotten it working that way. It allowed me to consolidate a bunch of conditional cards into the one. I’m not sure if I need to change the icon & icon colour with every state but found that it inherited from the previous state if I didn’t.

WIP:
cleaning new

- type: button
  tap_action:
    action: navigate
    navigation_path: /lovelace-newtest/vacuum
  icon: mdi:robot-vacuum
  show_state: true
  show_icon: true
  card_mod:
    style: |
      ha-card {
        --ha-card-background: linear-gradient(0deg, var(--card-background-color) 0%, 
            var(--card-background-color) {{state_attr('vacuum.dustin', 'battery_level')}}%,
            var(--paper-listbox-background-color) 0%
          );
      }
      @keyframes charge {
        75% { color: cyan; }
      }
      @keyframes pause {
        75% { color: grey; }
      }
      @keyframes cleaning {
        0% { transform: rotate(0) translate(0); }
        5% { transform: rotate(0) translate(0, -5px); }
        10% { transform: rotate(0) translate(0, 2px); }
        15% { transform: rotate(0) translate(0); }
        /* Turn left */
        20% { transform: rotate(30deg) translate(0); }
        25% { transform: rotate(30deg) translate(0, -5px); }
        30% { transform: rotate(30deg) translate(0, 2px); }
        35% { transform: rotate(30deg) translate(0); }
        40% { transform: rotate(0) translate(0); }
        /* Turn right */
        45% { transform: rotate(-30deg) translate(0); }
        50% { transform: rotate(-30deg) translate(0, -5px); }
        55% { transform: rotate(-30deg) translate(0, 2px); }
        60% { transform: rotate(-30deg) translate(0); }
        70% { transform: rotate(0deg) translate(0); }
        /* Staying still */
        100% { transform: rotate(0deg); }
      }

      @keyframes returning {
        0% { transform: rotate(0); }
        25% { transform: rotate(30deg); }
        50% { transform: rotate(0); }
        75% { transform: rotate(-30deg); }
        100% { transform: rotate(0); }
      }

      @keyframes blink {
        0% {
          opacity: 0;
        }
        100% {
          opacity: 1;
        }
      }

      {% if is_state('vacuum.dustin', 'docked') %}
        :host {
          --card-mod-icon: mdi:robot-vacuum;
          --card-mod-icon-color: var(--primary-text-color);
        }
        {% if is_state('sensor.dustin_charged', 'false') %}
          :host {
            --card-mod-icon: mdi:robot-vacuum;
            --card-mod-icon-color: var(--primary-text-color);
          }
          ha-state-icon {
            animation: charge 5.25s ease-in infinite;
          }
        {% endif %}
      {% elif is_state('vacuum.dustin', 'paused') %}
        :host {
          --card-mod-icon: mdi:pause;
          --card-mod-icon-color: var(--primary-text-color);
        }
        ha-state-icon {
          animation: pause 1s linear infinite;
        }
      {% elif is_state('vacuum.dustin', 'error') %}
        :host {
          --card-mod-icon: mdi:robot-vacuum;
          --card-mod-icon-color: red;
        }
        ha-state-icon {
          animation: blink 1s linear infinite;
        }
      {% elif is_state('vacuum.dustin', 'cleaning') %}
        :host {
          --card-mod-icon: mdi:robot-vacuum;
          --card-mod-icon-color: var(--primary-text-color);
        }
        ha-state-icon {
          animation: cleaning 5s linear infinite;
        }
      {% elif is_state('vacuum.dustin', 'returning') %}
        :host {
          --card-mod-icon: mdi:robot-vacuum;
          --card-mod-icon-color: var(--primary-text-color);
        }
        ha-state-icon {
          animation: returning 5s linear infinite;
        }
      {% elif is_state('vacuum.dustin', 'unavailable') %}
        :host {
          --card-mod-icon: mdi:robot-vacuum;
          --card-mod-icon-color: var(--sidebar-icon-color);
        }
      {% endif %}