Mushroom Cards - Build a beautiful dashboard easily 🍄 (Part 1)

Apologies @rhysb, where did I go wrong? :confused:

With template cards, is it possible to define a secondary action for tapping on the secondary info?

Should work better if you add the card_mod to the Chips instead of Chip:

        card_mod:
          style: |
            mushroom-action-chip:nth-child(3):active {
              background: rgba(var(--rgb-red), 0.5);
              border-radius: var(--chip-border-radius);
              transform: scale(1.2);
            }
            mushroom-action-chip:nth-child(4):active {
              background: rgba(var(--rgb-green), 0.5);
              border-radius: var(--chip-border-radius);
              transform: scale(1.2);
            }

I know your post about the air purifier card is over a year old, I have several of these in my home. I love the button card you used, but I needed four presets for one air purifier and wanted to add an off button. I got all of that sorted out and it works for controlling the air purifier, but the animation doesn’t work and I have a strange line in the card. Any ideas?

EDIT: It looks like setting the theme to either of the mushroom shadow or mushroom square shadow hides the line.

Purifier Card

type: custom:stack-in-card
cards:
  - type: custom:mushroom-template-card
    entity: fan.first_floor_air_purifier
    icon: mdi:fan
    primary: First Floor Air Purifier
    secondary: |-
      {% set fanspeed = state_attr(config.entity, 'percentage') %}
      {% if is_state('fan.first_floor_air_purifier', 'off') %}
        Off
      {% elif is_state_attr(config.entity, "mode", "auto") %}
        Auto
      {% elif is_state_attr(config.entity, "mode", "sleep") %}
        Sleep
      {% elif fanspeed == 100 %}
        Very High
      {% elif fanspeed == 75 %}
        High
      {% elif fanspeed == 50 %}
        Medium
      {% elif fanspeed == 25 %}
        Low
      {% endif %}
    icon_color: green
    card_mod:
      style:
        mushroom-shape-icon$: |
          @keyframes rotation {
            0% {
              transform: rotate(0deg);
            }
            100% {
              transform: rotate(360deg);
            }
          }
          ha-icon {
            box-shadow: 0px 0px;
            animation: rotation linear infinite !important;
            {% set fanspeed = state_attr(config.entity, 'percentage') |float %}
            {% if is_state_attr(config.entity, "mode", "auto") %}
              animation-duration: 2s !important;
            {% elif is_state_attr(config.entity, "mode", "sleep") %}
              animation-duration: 6s !important;
            {% elif fanspeed == 100 %}
              animation-duration: 0.5s !important;
            {% elif fanspeed == 75 %}
              animation-duration: 1.5s !important;
            {% elif fanspeed == 50 %}
              animation-duration: 2.5s !important;
            {% elif fanspeed == 25 %}
              animation-duration: 3.5s !important;
            {% else %}
            animation-duration: ;
            {% endif %}
  - type: horizontal-stack
    cards:
      - type: custom:layout-card
        layout_type: grid
        cards:
          - type: custom:mushroom-template-card
            layout: vertical
            primary: 'Off'
            tap_action:
              action: call-service
              service: fan.set_percentage
              data:
                percentage: 0
              target:
                entity_id: fan.first_floor_air_purifier
            view_layout:
              grid-area: button1
            card_mod:
              style: |
                ha-card {
                  height: 44px !important;
                  box-shadow: none;
                  --card-primary-font-weight: normal;
                }
          - type: custom:mushroom-template-card
            layout: vertical
            primary: Low
            tap_action:
              action: call-service
              service: fan.set_percentage
              data:
                percentage: 25
              target:
                entity_id: fan.first_floor_air_purifier
            view_layout:
              grid-area: button2
            card_mod:
              style: |
                ha-card {
                  height: 44px !important;
                  box-shadow: none;
                  --card-primary-font-weight: normal;
                }
          - type: custom:mushroom-template-card
            layout: vertical
            primary: Medium
            tap_action:
              action: call-service
              service: fan.set_percentage
              data:
                percentage: 50
              target:
                entity_id: fan.first_floor_air_purifier
            view_layout:
              grid-area: button3
            card_mod:
              style: |
                ha-card {
                  height: 44px !important;
                  box-shadow: none;
                  --card-primary-font-weight: normal;

                }
          - type: custom:mushroom-template-card
            layout: vertical
            primary: High
            tap_action:
              action: call-service
              service: fan.set_percentage
              data:
                percentage: 75
              target:
                entity_id: fan.first_floor_air_purifier
            view_layout:
              grid-area: button4
            card_mod:
              style: |
                ha-card {
                  height: 44px !important;
                  box-shadow: none;
                  --card-primary-font-weight: normal;
                }
          - type: custom:mushroom-template-card
            layout: vertical
            primary: Very High
            tap_action:
              action: call-service
              service: fan.set_percentage
              data:
                percentage: 100
              target:
                entity_id: fan.first_floor_air_purifier
            view_layout:
              grid-area: button5
            card_mod:
              style: |
                ha-card {
                  height: 44px !important;
                  box-shadow: none;
                  --card-primary-font-weight: normal;
                }
          - type: custom:mushroom-template-card
            layout: vertical
            icon: mdi:fan-auto
            icon_color: white
            tap_action:
              action: call-service
              service: fan.set_preset_mode
              data:
                preset_mode: auto
              target:
                entity_id: fan.first_floor_air_purifier
            double_tap_action:
              action: call-service
              service: fan.set_preset_mode
              data:
                preset_mode: sleep
              target:
                entity_id: fan.first_floor_air_purifier
            view_layout:
              grid-area: button6
            card_mod:
              style: |
                ha-card {
                  height: 44px !important;
                  box-shadow: none;
                }
                mushroom-shape-icon {
                  --shape-color: none !important;
                  --icon-symbol-size: 20px;
                }
        layout:
          grid-template-columns: 14% 16% 21% 16% 23% 10%
          grid-template-rows: auto
          grid-template-areas: |
            "button1 button2 button3 button4 button5 button6"
card_mod:
  style: |
    ha-card {
      {% if is_state('fan.first_floor_air_purifier', 'on') %}
          background: rgba(101,170,91,0.1);
      {% endif %}
    }

2 Likes

No worries, I an effort to condense my page I did actually switch to a tile card however it looks like using a variable in the animation logic is preventing the spin (not sure why). Replacing the fan speed variable seems to fix the issue. Let me know if you want the code for the full card or if this is ok

          ha-icon {
            box-shadow: 0px 0px;
            animation: rotation linear infinite !important;
            {% if is_state_attr(config.entity, "mode", "auto") %}
              animation-duration: 2s !important;
            {% elif is_state_attr(config.entity, "mode", "sleep") %}
              animation-duration: 6s !important;
            {% elif state_attr(config.entity, 'percentage') == 100 %}
              animation-duration: 0.5s !important;
            {% elif state_attr(config.entity, 'percentage') == 75 %}
              animation-duration: 1.5s !important;
            {% elif state_attr(config.entity, 'percentage') == 50 %}
              animation-duration: 2.5s !important;
            {% elif state_attr(config.entity, 'percentage') == 25 %}
              animation-duration: 3.5s !important;
            {% else %}
              animation-duration: ;
            {% endif %}
          }
1 Like

Thanks for the quick reply!!! I really appreciate it. That worked for everything, except for off. In the off state the animation still spins at what looks like the “Low” value. From the code it looks like it should stop, but I’m no expert by any means.

Ahh yea forgot to add an off condition

          ha-icon {
            box-shadow: 0px 0px;
            animation: rotation linear infinite !important;
            {% if is_state(config.entity, "off") %}
              animation-duration: ;
            {% elif is_state_attr(config.entity, "mode", "auto") %}
              animation-duration: 2s !important;
            {% elif is_state_attr(config.entity, "mode", "sleep") %}
              animation-duration: 6s !important;
            {% elif state_attr(config.entity, 'percentage') == 100 %}
              animation-duration: 0.5s !important;
            {% elif state_attr(config.entity, 'percentage') == 75 %}
              animation-duration: 1.5s !important;
            {% elif state_attr(config.entity, 'percentage') == 50 %}
              animation-duration: 2.5s !important;
            {% elif state_attr(config.entity, 'percentage') == 25 %}
              animation-duration: 3.5s !important;
            {%- else -%}
              animation-duration: ;
            {%- endif %}
          }
1 Like

Thank you! That works perfectly. You mentioned you switched to tile card, when you have a minute, would you mind showing what that looks like? Some of your older post of your Dashboards are really great. I’d love to see what this particular device looks like now.

No worries! Thanks haha and yea of course. I mainly wanted two devices on one row and the tile card is perfect fit except it’s missing the auto button (technically missing sleep as well but I never use it). Basically just added the auto button and styled to match the rest of my dashboard. It does use percent in the secondary but I don’t mind the percentage either.

Screenshot 2023-06-01 at 8.38.10 PM

Card code
type: custom:vertical-stack-in-card
cards:
  - type: tile
    entity: fan.andrews_air_purifier
    color: green
    name: Air Purifier
    features:
      - type: fan-speed
    card_mod:
      style:
        ha-tile-icon$: |
          ha-svg-icon {
            {% if is_state(config.entity,'off') %}
              animation: ;
            {% elif is_state_attr(config.entity,'percentage',33) %}
              animation: rotate 1.2s linear infinite;
            {% elif is_state_attr(config.entity,'percentage',66) %}
              animation: rotate 0.7s linear infinite;
            {% elif is_state_attr(config.entity,'percentage',100) %}
              animation: rotate 0.5s linear infinite;
            {% elif is_state_attr(config.entity,'mode','auto') %}
              animation: rotate 1.2s linear infinite;
            {% elif is_state_attr(config.entity,'mode','sleep') %}
              animation: rotate 2s linear infinite;
            {%- endif %}
          }
          @keyframes rotate {
            100% { transform: rotate(360deg); }
          }
        ha-tile-info$: |
          .secondary {
            opacity: 80%;
          }
        .: |
          ha-card {
          --primary-text-color:  var(--tile-color);
          {% if is_state(config.entity, 'on') %}
              background: rgba(101,170,91,0.1);
          {% endif %}
          }
  - type: custom:mushroom-chips-card
    chips:
      - type: template
        icon_color: |-
          {% if is_state_attr(config.entity, 'mode', 'manual') %}
            disabled
          {% elif is_state_attr(config.entity, 'mode', 'auto') %}
            green
          {% endif %}
        icon: mdi:fan-auto
        entity: fan.andrews_air_purifier
        tap_action:
          action: call-service
          service: fan.set_preset_mode
          data:
            preset_mode: auto
          target:
            entity_id: fan.andrews_air_purifier
        card_mod:
          style: |
            ha-card {
              {% if is_state_attr(config.entity, 'mode', 'manual') %}
                --chip-background: rgba(var(--rgb-disabled), 0.15);
              {% elif is_state_attr(config.entity, 'mode', 'auto') %}
                --chip-background: rgba(var(--rgb-green), 0.15);
              {% endif %}
            } 
    alignment: end
    card_mod:
      style: |
        ha-card {
            --ha-card-box-shadow: none;
            top: 12px;
            width: -webkit-fill-available;
            right: 12px;
            position: absolute;
        } 
        .chip-container {
            right: 0px;
            position: absolute;
        }
card_mod:
  style: |
    ha-card {
      background: none;
    }

3 Likes

Thanks @rhysb, I do remember coming across your post on nth-child, but I couldn’t locate it again. However, the solution only seemed to work on the 4th chip and not the 3rd :confused:

Is it because the 1st and 2nd chips are mushroom-entity-chips while the 3rd and 4th are mushroom-action-chips?

1 Like

It is working for me. With the smaller icon it just doesn’t appear to change as much.

@rhysb kindly guide

Wow, what a beautiful interface :slight_smile:

Can I get help - I have the following code:

I want to insert the timer of the times inside this window if one button will open the buttons thanks

type: grid
title: fan_test
cards:
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: mqtt.publish
      service_data:
        topic: cmnd/fan_parents/FanSpeed
        payload: '0'
      target: {}
    entity: light.fan_parents_room
    hold_action:
      action: none
    name: 'Off'
    icon: mdi:stop-circle-outline
  - type: button
    tap_action:
      action: call-service
      service: mqtt.publish
      service_data:
        topic: cmnd/fan_parents/FanSpeed
        payload: '1'
      target: {}
    entity: fan.fan_parents_room
    hold_action:
      action: none
    name: Low
  - type: button
    tap_action:
      action: call-service
      service: mqtt.publish
      service_data:
        topic: cmnd/fan_parents/FanSpeed
        payload: '2'
      target: {}
    entity: fan.fan_parents_room
    hold_action:
      action: none
    name: Med
  - type: button
    tap_action:
      action: call-service
      service: mqtt.publish
      service_data:
        topic: cmnd/fan_parents/FanSpeed
        payload: '3'
      target: {}
    entity: fan.fan_parents_room
    hold_action:
      action: none
    name: High
  - type: button
    tap_action:
      action: toggle
    entity: light.fan_parents_room
    name: Light
    hold_action:
      action: none
  - type: horizontal-stack
    cards:
      - aspect_ratio: 3/3
        color: rgb(44, 109, 214)
        color_type: label-card
        entity: >-
          input_boolean.fan_on_for_20_minutes_minutes_minutes_minutes_minutes_minutes
        name: 20
        state:
          - styles:
              card:
                - box-shadow: 0px 0px 10px 3px var(--button-card-light-color)
            value: 'on'
          - styles:
              card:
                - '--paper-card-background-color': rgb(44, 109, 214)
            value: 'off'
        styles:
          card:
            - margin: 0px 0px 0px -3px
          name:
            - font-weight: bold
            - font-size: 25px
            - color: white
        tap_action:
          action: call-service
          service: script.set_20_time_for_fan_parents
        type: custom:button-card
  - aspect_ratio: 3/3
    color: rgb(44, 109, 214)
    color_type: label-card
    entity: input_boolean.fan_on_for_30_minutes_minutes_minutes
    name: 30
    state:
      - styles:
          card:
            - box-shadow: 0px 0px 10px 3px var(--button-card-light-color)
        value: 'on'
      - styles:
          card:
            - '--paper-card-background-color': rgb(44, 109, 214)
        value: 'off'
    styles:
      card:
        - margin: 0px 0px 0px -3px
      name:
        - font-weight: bold
        - font-size: 25px
        - color: white
    tap_action:
      action: call-service
      service: script.set_30_time_for_fan_parents_time_for_fan_parents
    type: custom:button-card
  - aspect_ratio: 3/3
    color: rgb(44, 109, 214)
    color_type: label-card
    entity: input_boolean.fan_on_for_45_minutes_minutes_minutes_minutes_minutes
    name: 45
    state:
      - styles:
          card:
            - box-shadow: 0px 0px 10px 3px var(--button-card-light-color)
        value: 'on'
      - styles:
          card:
            - '--paper-card-background-color': rgb(44, 109, 214)
        value: 'off'
    styles:
      card:
        - margin: 0px 0px 0px -3px
      name:
        - font-weight: bold
        - font-size: 25px
        - color: white
    tap_action:
      action: call-service
      service: script.set_45_time_for_fan_parents
    type: custom:button-card
  - aspect_ratio: 3/3
    color: rgb(44, 109, 214)
    color_type: label-card
    entity: input_boolean.fan_on_for_60_minutes_minutes_minutes_minutes
    name: 60
    state:
      - styles:
          card:
            - box-shadow: 0px 0px 10px 3px var(--button-card-light-color)
        value: 'on'
      - styles:
          card:
            - '--paper-card-background-color': rgb(44, 109, 214)
        value: 'off'
    styles:
      card:
        - margin: 0px 0px 0px -3px
      name:
        - font-weight: bold
        - font-size: 25px
        - color: white
    tap_action:
      action: call-service
      service: >-
        script.set_60_time_for_fan_parents_time_for_fan_parents_time_for_fan_parents
    type: custom:button-card
  - aspect_ratio: 3/3
    color: rgb(44, 109, 214)
    color_type: label-card
    entity: input_boolean.fan_on_for_120_minutes_minutes
    name: 120
    state:
      - styles:
          card:
            - box-shadow: 0px 0px 10px 3px var(--button-card-light-color)
        value: 'on'
      - styles:
          card:
            - '--paper-card-background-color': rgb(44, 109, 214)
        value: 'off'
    styles:
      card:
        - margin: 0px 0px 0px -3px
      name:
        - font-weight: bold
        - font-size: 25px
        - color: white
    tap_action:
      action: call-service
      service: script.set_120_time_for_fan_parents
    type: custom:button-card
square: false
columns: 5

#################################

type: custom:vertical-stack-in-card
cards:
  - type: tile
    entity: fan.andrews_air_purifier
    color: green
    name: Air Purifier
    features:
      - type: fan-speed
    card_mod:
      style:
        ha-tile-icon$: |
          ha-svg-icon {
            {% if is_state(config.entity,'off') %}
              animation: ;
            {% elif is_state_attr(config.entity,'percentage',33) %}
              animation: rotate 1.2s linear infinite;
            {% elif is_state_attr(config.entity,'percentage',66) %}
              animation: rotate 0.7s linear infinite;
            {% elif is_state_attr(config.entity,'percentage',100) %}
              animation: rotate 0.5s linear infinite;
            {% elif is_state_attr(config.entity,'mode','auto') %}
              animation: rotate 1.2s linear infinite;
            {% elif is_state_attr(config.entity,'mode','sleep') %}
              animation: rotate 2s linear infinite;
            {%- endif %}
          }
          @keyframes rotate {
            100% { transform: rotate(360deg); }
          }
        ha-tile-info$: |
          .secondary {
            opacity: 80%;
          }
        .: |
          ha-card {
          --primary-text-color:  var(--tile-color);
          {% if is_state(config.entity, 'on') %}
              background: rgba(101,170,91,0.1);
          {% endif %}
          }
  - type: custom:mushroom-chips-card
    chips:
      - type: template
        icon_color: |-
          {% if is_state_attr(config.entity, 'mode', 'manual') %}
            disabled
          {% elif is_state_attr(config.entity, 'mode', 'auto') %}
            green
          {% endif %}
        icon: mdi:fan-auto
        entity: fan.andrews_air_purifier
        tap_action:
          action: call-service
          service: fan.set_preset_mode
          data:
            preset_mode: auto
          target:
            entity_id: fan.andrews_air_purifier
        card_mod:
          style: |
            ha-card {
              {% if is_state_attr(config.entity, 'mode', 'manual') %}
                --chip-background: rgba(var(--rgb-disabled), 0.15);
              {% elif is_state_attr(config.entity, 'mode', 'auto') %}
                --chip-background: rgba(var(--rgb-green), 0.15);
              {% endif %}
            } 
    alignment: end
    card_mod:
      style: |
        ha-card {
            --ha-card-box-shadow: none;
            top: 12px;
            width: -webkit-fill-available;
            right: 12px;
            position: absolute;
        } 
        .chip-container {
            right: 0px;
            position: absolute;
        }
card_mod:
  style: |
    ha-card {
      background: none;
    }

Can anything help? :slight_smile:

Hey @Mattia2399 have you found a way to build this? :slight_smile:

1 Like

So can we achieve this in the sticky footer? :slight_smile:

Thanks for all your contribution, you’re a mushroom hero!

7 Likes

If you have card_mod installed you can try the following, it will change the background colour of all chips on the card. Add to the bottom of the card configuration. There’s a few other things in there as well for spacing and padding , but naturally the last line will change the background colour.

card_mod:
  style: |
    :host {
      --mush-chip-spacing: 0.1em;
      --mush-chip-font-size: 0.28em;
      --mush-chip-padding: 0em;
      --mush-chip-background: #003355
    }

Hi,

Apologies for the cross post ( also posted on Swiper Thread) but I thought I might actually be better off posting in here as it may be something to do with the “Mushroom Card” ccs class (??!??!).

I’m trying to use Mushroom + Swiper for a 4" NSPanel Pro GUI and its going well; other than when I need to use a mushroom card slider ( see gif below) Screen Recording 2023-06-02 at 17.09.48

I think ( according to the Swiper Docs) I can use the class of a ccs object to inhibit Swiper:

parameters:
  edgeSwipeDetection: prevent
  effect: slider
  observer: true
  noSwiping: true
  noSwipingClass: slider
  preventInteractionOnTransition: true

Taken from https://swiperjs.com/swiper-api#param-noSwiping.

If you can’t tell I haze zero experience with css or coding in general; but any advice to be able to use the mushroom slider would be much appreciated! :slight_smile:

TIA
Alex

Actually yes, I’m almost there. I just have to find a way to make the popup appear on top of the other cards.


6 Likes

Nice work, maybe better from a UI perspective to keep the icons small and on the left of the room name like a list?
If you share your code so far I can play around with it too to make the popup work :slight_smile:

2 Likes