Mushroom Cards Card Mod Styling/Config Guide

Sorry add a !important:

overflow: visible !important;

@dimitri.landerloos
Thanks that did it. I now have a new issue. Is there such a way to get the text to scroll in the box only. Or hide after a certain point?

I have a couple of options, in the below, one is bouncing left to right and one scrolling from left to right. I need to somehow get the text between the red lines. I can mess around with values which make it go halfway accross the screen but not sure what i need to do to hide it after a certain point.

ha scroll2

Add a overflow: hidden; to the card. You can then figure out the animation for yourself :slight_smile:

    card_mod:
      style:
        mushroom-state-info$: |
          .secondary {
            {{ 'animation: my-animation 15s linear infinite;' if is_state('media_player.bedroom_speaker', 'off') }}
            transform-origin: 0% 100%;
            overflow: visible !important;
           }
           @keyframes my-animation {
              0%, 100% { transform: translateX(30%); }
              50%  { transform: translateX(0%); }
           }
        .: |
          ha-card {
            overflow: hidden;
          }
1 Like

Anyone able to animate just the border of a mushroom template card? The below works but spins the icon as well which I’m just wanting to animate spin the border. Thanks!

style:
  .: |
    ha-card {
      border-style: none;
      background-color: transparent;
    }
    mushroom-shape-icon$: |
      .shape {
    	--icon-symbol-size: 56px !important;
        --icon-size: 80px !important;
        border: 2.5px outset green !important;
        --shape-animation: circle 1s linear infinite;
      }
    @keyframes circle {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform:rotate(360deg);
      }
    }

Border animations like that are not really possible easily in CSS in general.

you have to fake it something like this by placing a pseudo element behind the original element:
Untitled video - Made with Clipchamp - 2023-11-20T225358.551

card_mod:
  style:
    mushroom-shape-icon$: |
      .shape {
        --icon-symbol-size: 56px !important;
        --icon-size: 80px !important;
      }
      .shape:before {
        content: '';
        position: absolute;
        width: inherit;
        height: inherit;
        border-radius: 50%;
        border: 2.5px outset green !important;
        animation: circle 1s linear infinite;
      }
      @keyframes circle {
        0% {transform: rotate(0deg);}
        100% {transform:rotate(360deg);}
      }
    .: |
      ha-card {
        border-style: none;
        background-color: transparent;
      }
2 Likes

That’s perfect! Thank you for your help.

Hey. I finally got the animation for all icons (chip card). The only problem is that they always start moving only after refreshing the page. Does anyone know where the problem could be?
The chip card is displayed based on the condition whether the appliance is on/off. Or is the problem that I am displaying the page on the tablet via Fully Kiosk Browser?

easy way to find out if it is Fully Kiosk/The specific device doing it. does it work as intended on a different device?

if it only happens on one device i dont think ill be able to help very much unfortunately as it will be down to the browser being used perhaps having different ways of applying keyframes.

I have tried Chrome and android mobile app. Both behave the same. It is always a condition chip card. The chip card is displayed, but the animation starts after the page refresh.
These are for example animations
Washing Machine
Dishwasher
Dryer
Ding Animation
All from your post (Aug 20)
When the condition is run a second time (if the icon was refreshed the first time), the animation works. But only if the browser is not refreshed)
Video:
Ding Animation

Ok, try and post your config here please and ill see if there is something obvious happening.

card_mod:
  style:
    mushroom-conditional-chip:nth-child(5):
      mushroom-template-chip$: |
        ha-state-icon {
          animation: ring 4s linear infinite;
          transform-origin: 50% 15%;
        }
        @keyframes ring {
          0% { transform: rotate(0); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          2% { transform: rotate(30deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          6% { transform: rotate(-28deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          10% { transform: rotate(34deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          14% { transform: rotate(-32deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          18% { transform: rotate(30deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          22% { transform: rotate(-28deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          26% { transform: rotate(26deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          30% { transform: rotate(-24deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          34% { transform: rotate(22deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          38% { transform: rotate(-20deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          42% { transform: rotate(18deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          46% { transform: rotate(-16deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          50% { transform: rotate(14deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          54% { transform: rotate(-12deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          58% { transform: rotate(10deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          62% { transform: rotate(-8deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          66% { transform: rotate(6deg); }
          70% { transform: rotate(-4deg); }
          74% { transform: rotate(2deg); }
          78% { transform: rotate(-1deg); }
          82% { transform: rotate(1deg); }
          86% { transform: rotate(0); }
          100% { transform: rotate(0); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
        { 

Can you pleast post your full config. Entire card please.

Including any stack in cards, grids, etc.

type: custom:mushroom-chips-card
chips:
  - type: menu
    card_mod: null
    style: |
      ha-card {
       border: unset;
       background: unset;

       --chip-font-size: 11px;
      }   
  - type: template
    icon: mdi:lightning-bolt-circle
    card_mod: null
    style: |
      ha-card {
       border: unset;
       background: unset;
       --chip-icon-size: 25px;
       --chip-font-size: 11px;
      }   
    icon_color: >-
      {{ "red" if states("sensor.elektromer_byt_power") | int >= 1000 else
      "#0cc46e" }}
    content: '{{ states("sensor.elektromer_byt_power") }} W'
    entity: sensor.elektromer_byt_energy
  - type: template
    icon: mdi:transmission-tower
    card_mod: null
    style: |
      ha-card {
       border: unset;
       background: unset;
       --chip-icon-size: 25px;
       --chip-font-size: 11px;
      } 
    content: '{{ states("input_text.helper_hdo_informace") }}'
    icon_color: '{{ "grey" if states("input_boolean.vd_hdo") == "off" else "#0cc46e" }}'
  - type: template
    content: '{{ states("sensor.speedtest_stahovani") | round(0) }} Mbit/s'
    icon: mdi:download-circle
    card_mod: null
    style: |
      ha-card {
       border: unset;
       background: unset;
       --chip-icon-size: 25px;
       --chip-font-size: 11px;
      } 
    icon_color: >-
      {{ "red" if states("sensor.speedtest_stahovani") | int <= 300 else
      "#0cc46e" }}
    entity: sensor.speedtest_stahovani
  - type: conditional
    conditions:
      - condition: state
        entity: input_boolean.vd_postovni_schranka
        state: 'on'
    chip:
      type: template
      entity: input_boolean.vd_postovni_schranka
      icon: mdi:bell-ring
      icon_color: red
      card_mod: null
      style: |
        ha-card {
         border: unset;
         background: unset;
         --chip-icon-size: 25px;
         --chip-font-size: 11px;
        }       
      content: NovĂĄ poĹĄta!
  - type: conditional
    conditions:
      - condition: state
        entity: input_boolean.vd_popelnice
        state: 'on'
    chip:
      type: template
      tap_action:
        action: toggle
      icon: mdi:trash-can
      icon_color: amber
      card_mod: null
      style: |
        ha-card {
         border: unset;
         background: unset;
         --chip-icon-size: 25px;
         --chip-font-size: 11px;
        }  
      content: Vyndat popelnice!
      entity: input_boolean.vd_popelnice
  - type: spacer
  - type: template
    tap_action:
      action: toggle
    icon: mdi:teddy-bear
    card_mod: null
    style: |
      ha-card {
       border: unset;
       background: unset;
       --chip-icon-size: 25px;
       --chip-font-size: 11px;
      }     
    icon_color: >-
      {{ "purple" if states("input_boolean.vd_hlidani_deti") == "on" else
      "disabled" }}
    entity: input_boolean.vd_hlidani_deti
    content: >-
      {{ "Vypnout hlídání dětí" if states("input_boolean.vd_hlidani_deti") ==
      "on" else "Zapnout hlídání dětí" }}
card_mod:
  style:
    mushroom-conditional-chip:nth-child(5):
      mushroom-template-chip$: |
        ha-state-icon {
          animation: ring 4s linear infinite;
          transform-origin: 50% 15%;
        }
        @keyframes ring {
          0% { transform: rotate(0); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          2% { transform: rotate(30deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          6% { transform: rotate(-28deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          10% { transform: rotate(34deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          14% { transform: rotate(-32deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          18% { transform: rotate(30deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          22% { transform: rotate(-28deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          26% { transform: rotate(26deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          30% { transform: rotate(-24deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          34% { transform: rotate(22deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          38% { transform: rotate(-20deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          42% { transform: rotate(18deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          46% { transform: rotate(-16deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          50% { transform: rotate(14deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          54% { transform: rotate(-12deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          58% { transform: rotate(10deg); clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); }
          62% { transform: rotate(-8deg); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
          66% { transform: rotate(6deg); }
          70% { transform: rotate(-4deg); }
          74% { transform: rotate(2deg); }
          78% { transform: rotate(-1deg); }
          82% { transform: rotate(1deg); }
          86% { transform: rotate(0); }
          100% { transform: rotate(0); clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%, 85% 50%, 80% 30%, 60% 5%, 40% 5%, 20% 30%, 15% 50%); }
        { 

So i have been looking at this and i cant recreate your exact issue. But i have experienced some weird behavior myself when using the conditonal chips, so i ditched them in favour of doing the condition in card mod instead. Like this:

card_mod:
  style:
    mushroom-template-chip:nth-child(5)$: |
      ha-state-icon {
        /* dishwasher */
        animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes bounce {
        0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
        40% { transform: translateY(-1.2px) rotate(5deg); } 
        60% { transform: translateY(-1.1px) rotate(-4deg); } 
      } 
      @keyframes wash {
        50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
      }
    .: |
      mushroom-template-chip:nth-child(5) {
        {% if states('input_boolean.dishwasher') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}

        {% endif %}
      }

Try and implement this for one you have problems with and see if it helps.

You may need to change margin-right: 0px to margin-left or both depending on your alignment being used.

Looks like it’s still the same :frowning:
Could it be for example somewhere in the cash memory in the chrome browser? Or in Chromium browsers… Edge behaves the same with animations.
In custom:mushroom-template-card I also have conditional custom:mushroom-chips-card with animation “blink”

  - type: custom:mushroom-chips-card
    chips:
      - type: conditional
        conditions:
          - entity: binary_sensor.senzor_pohyb_obyvaci_pokoj_occupancy
            state: 'on'
        chip:
          type: template
          icon_color: cyan
          icon: mdi:sofa-single
          card_mod:
            style: |
              ha-card {
                animation: blink 3s linear infinite;
                border: unset;
              }
              @keyframes blink {
                50% {opacity: 0;}
              } 

And that works fine. But if I put this animation in the chip card, it also doesn’t work without refreshing the page. It’s strange

Can you show me a code snippet of where you implemented what i stated above? I have a google nest hub aswell so i might be able to test some more.

What are you using to show the dashboard on it?

    mushroom-conditional-chip:nth-child(5):
      mushroom-template-chip$: |
        ha-state-icon {
          animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
          transform-origin: 50% 75%;
        }
        @keyframes bounce {
          0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
          40% { transform: translateY(-1.2px) rotate(5deg); } 
          60% { transform: translateY(-1.1px) rotate(-4deg); } 
        } 
        @keyframes wash {
          50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
        }
      .: |
        mushroom-template-chip:nth-child(5) {
          {% if states('input_boolean.vd_mycka') == 'off' %}
            margin-right: 0px !important;
            display: none !important;
          {% else %}

          {% endif %}
        }

I have a Lenovo Tab M10 tablet in my living room with the Fully Kiosk Browser app. Currently I tried this on a classic PC with Win 10 and MS Edge ver. 119.0 but Google Chrome behaves the same way

So you havent removed the conditional chip. Implement it like this:

type: custom:mushroom-chips-card
chips:
  - type: template
    icon_color: blue
    icon: mdi:dishwasher
card_mod:
  style:
    mushroom-template-chip:nth-child(1)$: |
      ha-state-icon {
        animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes bounce {
        0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
        40% { transform: translateY(-1.2px) rotate(5deg); } 
        60% { transform: translateY(-1.1px) rotate(-4deg); } 
      } 
      @keyframes wash {
        50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
      }
    .: |
      mushroom-template-chip:nth-child(1) {
        {% if states('input_boolean.vd_mycka') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}
        {% endif %}
      }

This section is now your condition to show the chip instead of the conditional chip being used:

      mushroom-template-chip:nth-child(1) {
        {% if states('input_boolean.vd_mycka') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}
        {% endif %}
      }
1 Like

Thanks, that looks promising! :partying_face:
Can you please advise me what the code will look like if I add more cards?

type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:dishwasher
    icon_color: blue
  - type: template
    icon: mdi:dishwasher
    icon_color: red
card_mod:
  style:
    mushroom-template-chip:nth-child(1)$: |
      ha-state-icon {
        animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes bounce {
        0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
        40% { transform: translateY(-1.2px) rotate(5deg); } 
        60% { transform: translateY(-1.1px) rotate(-4deg); } 
      } 
      @keyframes wash {
        50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
      }
    .: |
      mushroom-template-chip:nth-child(1) {
        {% if states('input_boolean.vd_mycka') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}
        {% endif %}
      }
    mushroom-template-chip:nth-child(2)$: |
      ha-state-icon {
        animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes bounce {
        0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
        40% { transform: translateY(-1.2px) rotate(5deg); } 
        60% { transform: translateY(-1.1px) rotate(-4deg); } 
      } 
      @keyframes wash {
        50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
      }
    .: |
      mushroom-template-chip:nth-child(2) {
        {% if states('input_boolean.vd_mycka') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}
        {% endif %}
      }

If I copy the whole thing and just overwrite nth-child(2) it will return an error. It’s definitely just a bad write

Thank you so much for your help, I would never have figured it out on my own !

duplicated mapping key (45:5)

 42 |       @keyframes wash {
 43 |         50%  { clip-path: polygon(0 ...
 44 |       }
 45 |     .: |
----------^
 46 |       mushroom-template-chip:nth-ch ...
 47 |         {% if states('input_boolean ...

Sure. so if you had multiple chips you would do this:

type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:dishwasher
    icon_color: blue
  - type: template
    icon: mdi:dishwasher
    icon_color: red
card_mod:
  style:
    mushroom-template-chip:nth-child(1)$: |
      ha-state-icon {
        animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes bounce {
        0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
        40% { transform: translateY(-1.2px) rotate(5deg); } 
        60% { transform: translateY(-1.1px) rotate(-4deg); } 
      } 
      @keyframes wash {
        50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
      }
    mushroom-template-chip:nth-child(2)$: |
      ha-state-icon {
        animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes bounce {
        0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
        40% { transform: translateY(-1.2px) rotate(5deg); } 
        60% { transform: translateY(-1.1px) rotate(-4deg); } 
      } 
      @keyframes wash {
        50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 36% 74%, 31% 43%, 61% 40%, 71% 69%, 62% 78%, 36% 73%, 35% 100%, 100% 100%, 100% 0); }
      }
    .: |
      mushroom-template-chip:nth-child(1) {
        {% if states('input_boolean.vd_mycka') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}
        {% endif %}
      }
      mushroom-template-chip:nth-child(2) {
        {% if states('input_boolean.vd_mycka') == 'off' %}
          margin-right: 0px !important;
          display: none !important;
        {% else %}
        {% endif %}
      }
1 Like