Picture Element card using card_mod for state-based icon rotation

I’ve got a picture-elements card configured nicely. I wanted to add custom CSS to get a fan icon rotating, so I’ve installed card-mod. Using this great post as a starting point, I can make an icon (ha-svg-icon) rotate, but I can’t make it state-based.

If I try to add a [data-state="on"] attribute selector to the ha-icon element, it applies too high up in the CSS, and only gets injected if it matches the state at page refresh.

type: picture-elements
image: /local/home.svg
elements:
  - type: state-icon
    entity: switch.fan
    icon: mdi:fan
    tap_action:
      action: toggle
    style:
      top: 17.5%
      left: 6%
    card_mod:
      style:
        state-badge:
          $:
            ha-icon[data-state="on"]:
              $: |
                ha-svg-icon {
                  animation: rotation 2s linear infinite;
                }
                @keyframes rotation {
                  0% {
                    transform: rotate(0deg);
                  }
                  100% {
                    transform: rotate(360deg);
                  }
                }

If I move the CSS up to the ha-icon, it selectively applies by state in real-time (no refresh required, red background added for testing), but it doesn’t rotate! :sob:

    card_mod:
      style:
        state-badge:
          $: |
            ha-icon[data-state="on"] {
              animation: rotation 2s linear infinite;
              background: red;
            }
            @keyframes rotation {
              0% {
                transform: rotate(0deg);
              }
              100% {
                transform: rotate(360deg);
              }
            }

What am I doing wrong? Why does the ha-icon refuse to rotate, when the ha-icon-svg is happy to?

Better use this post.
The style must be applied if some conditions are met.
What are your conditions?

Thanks @Ildar_Gabdullin.
The examples look similar enough to me, regarding rotating fan icons anyway. My condition is [data-state="on"].

I can rotate the ha-svg-icon element just fine, but it is too far down the DOM to use the data-state on ha-icon. And I can’t rotate the ha-icon.

By condition I mean smth like “states(‘some_entity’) == SMTH”.

Oh, you’re saying I should do the condition check through HA state instead of using a CSS selector for the data attribute? Ok, I’ll have a look into that tomorrow. Never tried it.

Not sure if this is any help but this is how I rotate and change colour based on state

            card_mod:
              style:
                hui-generic-entity-row:
                  $:
                    state-badge:
                      $:
                        ha-icon:
                          $: |
                            ha-svg-icon {
                              color: {{ '#FDD835' if states(config.entity) == 'on' else '#44739E'}};
                              animation:
                              {% if states(config.entity) == 'on' -%}
                                rotation 2s linear infinite;
                              {% else %} null
                              {% endif %}
                            }
                            @keyframes rotation {
                              0% {
                                transform: rotate(0deg);
                              }
                              100% {
                                transform: rotate(360deg);
                              }
                            }
1 Like

Thanks @Holdestmade, that example was great. I found some relevant doco and switched to using is_state().

Just for anyone else, you need quotes around the entity name. This is a snippet of my complete element:

type: picture-elements
image: /local/home.svg
elements:
  - type: state-icon
    entity: switch.fan
    icon: mdi:fan
    tap_action:
      action: toggle
    style:
      top: 17.5%
      left: 6%
    card_mod:
      style:
        state-badge:
          $:
            ha-icon:
              $: |
                ha-svg-icon {
                  {% if is_state('switch.fan', 'on') %}
                    animation: rotation 2s linear infinite;
                  {% endif %}
                }
                @keyframes rotation {
                  0% {
                    transform: rotate(0deg);
                  }
                  100% {
                    transform: rotate(360deg);
                  }
                }

I can’t seem to get this working, does this code still work for you?

Doesn’t work for me either… First time trying.

@i_leeder do you still use this and does it still work with current HA?

@arrikhan

I have use this peace of code for my own fan in the study

  - type: state-icon
    entity: fan.study_fan
    title: Study Fan
    tap_action:
      action: toggle
    style:
      top: 25%
      left: 88%
    card_mod:
      style:
        state-badge:
          $:
            ha-state-icon:
              $:
                ha-icon:
                  $: |
                    ha-svg-icon {
                      {% if is_state('fan.study_fan', 'on') %}
                        animation: rotation 2s linear infinite;
                      {% endif %}
                    }
                    @keyframes rotation {
                      0% {
                        transform: rotate(0deg);
                      }
                      100% {
                        transform: rotate(360deg);
                      }
                    }
1 Like

Sorry @arrikhan / @renk1, I have barely used this since I set it up. Took me a few minutes to even find where this was configured!! Anyway, apparently it doesn’t work anymore :pensive: No more rotation.

If I get time/inspiration to look into it AND I find a fix, I’ll post back.

@coenie’s code above works. All good !

if anyone is still interested :slight_smile: heres a youtube tutorial from an awsome dude " [3ATIVE VFX Studio] "
https://www.youtube.com/watch?v=0wg9bdnGD00

I have played around a bit with the code to make it display and control two separate fans with just one icon (direction,color, speed and tap etc.). As a state-icon on a picture-elements card in a hui-element card in a fold-entity-row on an entities-card.

entities:
  - type: custom:fold-entity-row
    style:
      ha-icon:
        $: |
          ha-svg-icon {
            color: var(--my-font99-color);	# chevron
          }
    head:
      entity: sensor.dummy_fold			# quick-fix for no section lines
      name: Fans & More
      card_mod:
        style:
          hui-generic-entity-row $: |
            state-badge {
               display: none;
            }      
            border: solid 0px ;
            }            
    padding: 15
    open: false
    entities:
      - type: custom:hui-element
        card_type: picture-elements
        style: |
          ha-card {
            height: 53px !important;
          }
        image: /local/pix.gif
        elements:
          - type: state-icon
            entity: input_boolean.dummy_always_off	# dummy to stick the icon to
            icon: mdi:fan	# the icon to stick the combined functionality to.			
            tap_action:
              action: call-service
              service: automation.trigger
              target:
                entity_id: automation.fan_switch
            double_tap_action:
              action: call-service
              service: scene.turn_on
              target:
                entity_id: scene.fan_all_on
            hold_action:
              action: call-service
              service: scene.turn_on
              target:
                entity_id: scene.fan_all_off
            style:
              top: 5%
              left: 5%
              '--mdc-icon-size': 32px
            card_mod:
              style:
                state-badge:
                  $:
                    ha-state-icon:
                      $:
                        ha-icon:
                          $: |
                            ha-svg-icon {
                             animation: {% if is_state('switch.fan_left','off') and is_state('switch.fan_right','off') %} rotation 0.0s linear infinite {% elif is_state('switch.fan_left','off') and is_state('switch.fan_right','on') %} rotation 5.0s linear infinite {% elif is_state('switch.fan_left','on') and is_state('switch.fan_right','off') %} rotation 7.0s linear infinite {% else %} rotation 1.0s linear infinite {% endif %};                            }
                              @keyframes rotation {
                                0% {
                                  transform: rotate(0deg);
                                }
                                100% {
                                  transform: {{ 'rotate(-360deg)' if is_state('switch.fan_left','on') else 'rotate(360deg)' }};
                                }
                              } 
                .: |
                  :host {
                    --paper-item-icon-color: {% if is_state('switch.fan_left','off') and is_state('switch.fan_right','off') %} #3B3B3B {% elif is_state('switch.fan_left','off') and is_state('switch.fan_right','on') %} indianred {% elif is_state('switch.fan_left','on') and is_state('switch.fan_right','off') %} darkolivegreen {% else %} orange {% endif %}; 
            show_state: false```

I am trying to get the fan icon to rotate but it is not working. Anyone able to help?

- entity: sensor.afterburner_gpio_2_out_status
    name: 12V Cooling Fan
    icon: mdi:fan
    card_mod:
      style: |
        :host {
          {% if is_state('sensor.afterburner_gpio_2_out_status', 'Running') %}
          --card-mod-icon-color: yellow;
          animation: rotation 2s linear infinite;
          {% else %}
          --card-mod-icon-color: #03a9f4;
          {% endif %}
        }
        @keyframes rotation {
                              0% {
                                transform: rotate(0deg);
                              }
                              100% {
                                transform: rotate(360deg);
                              }
                            }

thx it is working :slight_smile: