Mushroom Cards - Build a beautiful dashboard easily šŸ„ (Part 1)

Try to put these cards into the layout card

- type: custom:layout-card
          layout_type: grid-layout
          layout:
            grid-template-columns: 0.6fr 0.4fr
            justify-items: center
          cards:
            - type: your card 1
            - type: your card 2 etc etc

You need to play with ā€œgrid-template-columnsā€ setting.

Hi, just get a card mod installed and:

- type: custom:mushroom-template-card
  card_mod:
    style: |
      ha-card {
        border-width: 0px
      }
1 Like

See post 5562

Hi Dimmanramone,

Have you edited the Function node "Format Album Art URL" ? It needs to point to you Home Assistant url.

msg.payload = 'http://10.10.10.1:8123' + msg.data.new_state.attributes.entity_picture
return msg;

I had to comment out the tap action to make it show up. What is the yaml supposed to be in those files?

@aoliveir

As I wrote in my post, I donā€™t need the home assistant instance url. The entity_picture attribute was an external url.

Speaker is a grid popup

type: custom:layout-card
layout_type: grid
layout:
  grid-template-columns: "1fr 1fr"
  grid-template-areas: |
    "spotify spotify" 
cards:
  - view_layout:
      grid-area: spotify  
    type: custom:mushroom-media-player-card
    entity: entity.entity
    use_media_info: true
    show_volume_level: true
    card_mod:
      style: |
        ha-card {
          background: none;
          box-shadow: none;
          border-width: thin;
          border-color: rgba(var(--rgb-grey), 0.5);
          --rgb-state-media-player: var(--rgb-green);
          {% if is_state(config.entity, 'playing') %}
            background: rgba(var(--rgb-green), 0.1);
          {% else %}
            background: transparent;
          {% endif %}                          
        }      
        mushroom-shape-icon {
          {{ 'animation: beat 1.3s ease-out infinite both;' if is_state(config.entity, 'playing') }}
        } 
        @keyframes beat {
          0%, 60% { --icon-symbol-size: 21px; }
          5%, 17%, 57% { --icon-symbol-size: 22px; }
          10%, 20%, 51% { --icon-symbol-size: 23px; }
          25%, 45% { --icon-symbol-size: 24px; }
          30%, 39% { --icon-symbol-size: 25px; }
          33% { --icon-symbol-size: 26px; }
        }    

and for sonos source popup I use this

type: custom:layout-card
layout_type: grid
layout:
  grid-template-columns: "100%"
  grid-template-areas: |
    "sonos"
    "group"
    "media"
cards:
  - view_layout:
      grid-area: sonos
    type: custom:sonos-groups
    styles:
      ha-card:
        background: none
        box-shadow: none
      group:
        background: none
      title: 
        display: none
      button-section:
        border: none
        background: none
      button-on-section:
        background: none
  - view_layout:
      grid-area: group
    type: custom:sonos-grouping
    styles:
      ha-card:
        background: none
        box-shadow: none
      group:
        background: none
      title: 
        display: none
      button-section:
        border: none
        background: none
      button-on-section:
        background: none    
  - view_layout:
      grid-area: media
    type: custom:sonos-media-browser
    mediaBrowserItemsAsList: false
    layout:
      mobileThresholdPx: 500
      mediaItem:
        width: 20%
        mobileWidth: 33% 
    styles:
      ha-card:
        background: none
        box-shadow: none
      group:
        background: none
      title: 
        display: none
      button-section:
        border: none
        background: none
      button-on-section:
        background: none    
      media-button-title:
        border-radius: 20px 20px 0px 0px !important

Thank you. That didnā€™t work at first, but I think the problem was theme-related. After switching themes your suggestion worked as intended.

Nowā€¦is there any way this can work with a Mushroom Person card with an entity picture? I tried messing with it but this is as far as I can get:
image

Colours and ring value hardcoded just for testing (easier to see whatā€™s going on):

Code
icon_type: entity-picture
card_mod:
  style:
    mushroom-shape-avatar$: |
      .container {
        background: radial-gradient(rgb(var(--rgb-red)) 60%, transparent calc(60% + 1px)), conic-gradient(rgb(var(--rgb-green)) 66% 0%, rgb(var(--rgb-red)) 0% 100%);
      }
      .container:after {
        content: "";
        height: 100%;
        width: 100%;
        position: absolute;
        border-radius: 50%;
        #background: rgba(var(--rgb-disabled), 0.1);
      }
1 Like

Need your help @rhysb. I want to make it shine and ilumination but there is no working animation for me. Hereā€™s code:

      mushroom-template-chip:nth-child(3)$: |
        ha-icon {
          {{ 'animation: illumination 2s infinite;' if is_state('binary_sensor.ruch_kuchnia_occupancy', 'on') else 'none' }};
        }
        @keyframes illumination {
          0%, 100% { clip-path: inset(0 0 0 0); }
          80% { clip-path: polygon(0% 99%, 20% 55%, 22% 37%, 39% 20%, 61% 21%, 77% 35%, 79% 57%, 99% 100%); }
        }
        ha-icon {
          animation: shine 2s infinite;
        }
        @keyframes shine {
          0% {
            opacity: 0.5;
            filter: brightness(10%);
          }
          50% {
            opacity: 1;
            filter: brightness(100%);
          }
          100% {
            opacity: 0.5;
            filter: brightness(10%);
          }
        }

Hope you can help once again :slight_smile:

So I make this the tap_action? Thanks

EDIT: Nope that messed up the whole thing, no idea how to implement this, btw not using sonos or spotify instead using YT music and universal media player.

I think you need to delete the ā€œelse ā€˜noneā€™ ā€œ of the if statement.

I copied the code but unfortunately its not sticking for me @rhysb

Here is a video https://photos.app.goo.gl/Qretg4E9YxmpJBA38

My code: Media Player code - Pastebin.com

you donā€™t need to. I use this popup to navigate to my speakers to control them.

1 Like

Sorry just trying to figure out what I need to do. Do you have a github lol, would love to use this media page with the popup just a confused noob.

@rhysb Hi how can I add an animation (bounce, etc) just to the search icon? I tried using your code but the icon didnā€™t do anything.

Here is my code (i removed animation code cuz it didnā€™t work)

type: custom:stack-in-card
mode: horizontal
cards:
  - type: custom:mushroom-chips-card
    chips:
      - type: template
        icon: mdi:home
        tap_action:
          action: navigate
          navigation_path: /homekit-infused/main_room
      - type: template
        icon: mdi:alpha-d-circle
        icon_color: blue
        tap_action:
          action: navigate
          navigation_path: /homekit-infused/home
      - type: template
        icon: mdi:alpha-v-circle
        icon_color: purple
        tap_action:
          action: navigate
          navigation_path: /homekit-infused/vally_esther_room
      - type: template
        icon: mdi:robot-vacuum
        icon_color: |-
          {% set state=states('vacuum.nestico_robot_vacuum') %}
          {% if state=='docked' %}
          grey
          {% elif state=='cleaning' %}
          blue
          {% elif state=='error' %}
          red
          {% elif state=='paused' %}
          pink
          {% elif state=='returning' %}
          purple
          {% endif %}
        tap_action:
          action: navigate
          navigation_path: /homekit-infused/vacuum
      - type: template
        icon: mdi:speaker
        icon_color: green
        tap_action:
          action: navigate
          navigation_path: /homekit-infused/media
      - type: template
        icon: mdi:dog
        icon_color: red
        tap_action:
          action: navigate
          navigation_path: /homekit-infused/luna
      - type: template
        entity: climate.3family_room
        icon_color: |-
          {% set status = state_attr('climate.3family_room','hvac_action') %}
          {% if status == 'off' %}
          grey
          {% elif status == 'cooling' %}
          blue
          {% elif status == 'heating' %}
          red
          {% else %}
          grey
          {% endif %}
        icon: mdi:thermostat
        tap_action:
          action: fire-dom-event
          browser_mod:
            service: browser_mod.popup
            data:
              content:
                type: custom:stack-in-card
                mode: vertical
                cards:
                  - type: custom:mushroom-climate-card
                    entity: climate.3family_room
                    fill_container: false
                    show_temperature_control: true
                    collapsible_controls: false
                    hvac_modes:
                      - heat
                      - cool
                      - fan_only
                    layout: horizontal
                  - type: custom:thermostat-dark-card
                    entity: climate.3family_room
                    hvac:
                      states:
                        idle: idle
                        cooling: cooling
                        heating: heating
                    step: '0.5'
                    chevron_size: '100'
                    pending: '3'
                    idle_zone: '2'
                    highlight_tap: true
                card_mod:
                  style: |
                    ha-card {
                       background: #111111;
                     }
      - type: action
        icon_color: white
        icon: mdi:magnify
        tap_action:
          action: call-service
          service: browser_mod.popup
          data:
            content:
              type: custom:search-card
              max_results: 10
              actions:
                - matches: ^toggle (.+\..+)
                  name: Toggle {1}
                  service: homeassistant.toggle
                  service_data: null
                  entity_id:
                    '1': null
              excluded_domains:
                - alarm_control_panel
                - automation
                - binary_sensor
                - button
                - camera
                - device_tracker
                - govee
                - group
                - input_boolean
                - input_number
                - input_select
                - input_text
                - number
                - script
                - select
                - siren
                - update
                - zone
            dismissable: true
            autoclose: false
            right_button: MEDIA
            left_button: HOME
            left_button_action:
              service: browser_mod.navigate
              data:
                path: /homekit-infused/main_room
            right_button_action:
              service: browser_mod.navigate
              data:
                path: /homekit-infused/media
          target: {}
        card_mod:
          style: |
            ha-card { 
              --chip-background: #11224D;
            }
    alignment: justify
    card_mod:
      style: |
        ha-card {
          --chip-box-shadow: none;
          --chip-background: none;
          --chip-spacing: 0;
          --chip-font-size: 0.3em; 
          --chip-height: 50px          
            } 
style: |
  ha-card { 
    background: #111111;
    border-radius: 30px;
    z-index: 999 !important;
    position: sticky !important;
    position: -webkit-sticky !important;
    top: 0 !important;
  }
1 Like

Edit: added a big blank card and it kinda works, itā€™s not overlaying like yours though https://photos.app.goo.gl/4EEogmXrHseNZXmM8

Try adding z-index to the :host, like this:

      /* Make the media player sticky at the bottom of the page */
      position: sticky;
      bottom: 12px;
      z-index: 9;
1 Like

Unfortunately, it isnā€™t sticking for me :/, here is my code if you wanna see

The card shows but instead of overlaying on top it gets pushed down when I scroll, not overlayed.

            - type: custom:gap-card
              height: 1000

            - type: custom:mushroom-media-player-card
              entity: media_player.currently_playing
              icon: mdi:play
              use_media_info: true
              icon_type: entity-picture
              show_volume_level: false
              media_controls:
                - play_pause_stop
                - next
              volume_controls:
                - volume_set
              fill_container: false
              layout: horizontal
              tap_action:
                action: fire-dom-event
                browser_mod:
                  service: browser_mod.popup
                  data:
                    title: Currently Playing
                    content:
                      type: custom:stack-in-card
                      cards:
                        - type: custom:mushroom-media-player-card
                          entity: media_player.currently_playing
                          icon_type: none
                          layout: vertical
                          media_controls:
                            - previous
                            - play_pause_stop
                            - next
                          volume_controls:
                            - volume_set
                            - volume_buttons
                          show_volume_level: false
                          use_media_info: true
                          collapsible_controls: false
                          card_mod:
                            style:
                              mushroom-state-info$: |
                                /* CSS for Mushroom Popup Media Player */
                                .secondary:before {

                                  /* Add album name between song title and artist name */
                                  {% if state_attr(config.entity, 'media_album_name') != none %}
                                    content: "{{ state_attr(config.entity, 'media_album_name')}}\A";
                                  {% endif %}

                                  /* Format title to fit on seperate line */
                                  white-space: pre;
                                  text-overflow: ellipsis;
                                }
                              .: |
                                ha-card {

                                  /* Remove border from media player */
                                  --ha-card-border-width: 0;

                                  /* Apply album art color to media player icon & volume bar */
                                  --rgb-state-media-player: var(--album-art-color);

                                  /* Disable transitions */
                                  transition: all 0s;
                                }
                                .actions {

                                  /* Apply album art color to media player controls */
                                  --rgb-primary-text-color: var(--album-art-color);
                                  --primary-text-color: rgb(var(--album-art-color));

                                  /* Move volume button to seperate row */
                                  display: block !important;
                                }
                                ha-card:before {
                                  content: "";

                                  /* Show album art above media player when active and default image when idle */
                                  {% if is_state(config.entity, ['playing', 'paused']) %}
                                    background: url( '{{ state_attr(config.entity, "entity_picture") }}') center no-repeat;
                                  {% else %}
                                    background: url('/local/idle_art.png') center no-repeat;
                                  {% endif %}

                                  /* Add padding around album art */
                                  margin: 0px 4px 16px;

                                  /* Add drop shadow to album art */
                                  filter: drop-shadow(4px 4px 6px rgba(var(--album-art-color), 0.3));

                                  /* Round borders of album art */
                                  border-radius: var(--control-border-radius);

                                  /* Adjust the album art aspect ratio based on media type */
                                  {% set media_type = state_attr(config.entity, 'media_content_type') %}
                                  {% if media_type == 'tvshow' %}
                                    aspect-ratio: 16 / 9;
                                  {% elif media_type == 'movie' %}
                                    aspect-ratio: 2 / 3;
                                  {% else %}
                                    aspect-ratio: 1 / 1;
                                  {% endif %}

                                  /* Stretch album art to fit box. Fix for if album art is not sized correctly */
                                  background-size: 100% 100%;
                                }
                                mushroom-button {

                                  /* Size volume button to match other controls and center */
                                  display: flex;
                                  width: calc((100% / 3) - (var(--spacing) / 3) * 2);
                                  margin: auto;
                                }
                                mushroom-media-player-media-control,
                                mushroom-media-player-volume-control {

                                  /* Correct margins for volume button on second row */
                                  display: flex;
                                  margin-right: 0px !important;
                                  
                                  /* Check if PLAY|STOP are supported and adjust margin accordingly */
                                  {% if state_attr(config.entity, 'supported_features') | int | bitwise_and(20480) > 0 %}
                                    margin-bottom: var(--spacing) !important;
                                  {% endif %}
                                }
                        - entity: media_player.currently_playing
                          hide:
                            icon: true
                            name: true
                            runtime: true
                            source: true
                            power: true
                            state_label: true
                            volume: true
                            info: true
                            progress: false
                            controls: true
                          more_info: false
                          type: custom:mini-media-player
                          toggle_power: false
                          group: true
                          card_mod:
                            style:
                              mmp-progress$: |
                                paper-progress {

                                  /* Apply album art color to progress bar when paused */
                                  --paper-progress-container-color: rgba(var(--album-art-color), 0.2) !important;
                                  
                                  /* Apply album art color to progress bar when playing */
                                  --paper-progress-active-color: rgb(var(--album-art-color)) !important;
                                }
                              .: |
                                ha-card {

                                  /* Move progress bar up into gap. Check if PLAY|STOP are supported */
                                  --base-offset: calc(4 * var(--mush-spacing, 12px)
                                                      + 1.33 * var(--mush-spacing, 12px)
                                                      + var(--mush-card-primary-line-height, 1.5) * var(--mush-card-primary-font-size, 14px)
                                                      + var(--mush-card-secondary-line-height, 1.5) * var(--mush-card-secondary-font-size, 12px)
                                                      + var(--mush-control-height, 42px));

                                  /* Check if Play (16385) or Stop (4096) are supported and add control button height if they are */
                                  {% if state_attr(config.entity, 'supported_features') | int | bitwise_and(20480) > 0 %}
                                    --control-offset: calc(var(--mush-spacing, 12px) + var(--mush-control-height, 42px));
                                  {% else %}
                                    --control-offset: 0px;
                                  {% endif %}

                                  /* Check if album name is present and add to height if it is */
                                  {% set album_name = state_attr(config.entity, 'media_album_name') %}
                                  {% if album_name == None or album_name == "" %}
                                    --album-offset: 0px;
                                  {% else %}
                                    --album-offset: calc(var(--mush-card-secondary-line-height, 1.5) * var(--mush-card-secondary-font-size, 12px));
                                  {% endif %}

                                  bottom: calc(var(--base-offset) + var(--control-offset) + var(--album-offset));

                                  /* Correct margins for progress bar */
                                  margin: 0px 28px -12px;

                                  /* Set height of card to match pregress bar height */
                                  height: var(--mmp-progress-height);

                                  /* Remove border outline */
                                  --ha-card-border-width: 0;

                                  /* Round corners of progress bar */
                                  --mmp-border-radius: var(--control-border-radius, 12px) !important;

                                  /* Set height of progress bar */
                                  --mmp-progress-height: 12px !important;

                                  /* Remove transitions to prevent progress bar floating in */
                                  transition: all 0s;
                                }
                      card_mod:
                        style: |
                          :host {

                            /* Assign album art color to variable used in popup */
                            --album-art-color:      
                            {% if is_state('media_player.currently_playing', ['playing', 'paused']) %}
                              {{ states('sensor.muted_color') }}
                            {% else %}
                              141, 117, 238
                            {% endif %};

                            /* Remove background because it is applied to popup */
                            --ha-card-background: none;

                            
                          }
                    card_mod:
                      style:
                        ha-dialog$: |
                          .mdc-dialog__surface {

                            /* Apply gradient background to popup using album art colors. Set to default colors when idle */
                            {% if is_state('media_player.currently_playing', ['playing', 'paused']) %}
                              background: linear-gradient(305deg, transparent 50%, rgba({{ states('sensor.dark_vibrant_color') }}, 0.4)), 
                                          linear-gradient(55deg, transparent 50%, rgba({{ states('sensor.vibrant_color') }}, 0.2)),  
                                          linear-gradient(180deg, transparent 40%, rgba({{ states('sensor.dark_muted_color') }}, 0.3));
                            {% else %}
                              background: linear-gradient(0deg, transparent 40%, rgba(192, 127, 190, 0.3)), 
                                          linear-gradient(240deg, transparent 40%, rgba(143, 119, 237, 0.3)),  
                                          linear-gradient(120deg, transparent 40%, rgba(122, 181, 239, 0.3));
                            {% endif %}
                          }
                        ha-header-bar$: |
                          .mdc-top-app-bar {

                            /* Remove header background so that popup background is visible */
                            --mdc-theme-primary: none;

                            /* Reduced the gap between header and album art */
                            margin-bottom: -16px;
                          }
                        .: |
                          :host {

                            /* Set width of popup */
                            --popup-min-width: 450px;
                          }
              card_mod:
                style: |
                  /* CSS for Mushroom Mini Media Player */
                  ha-card {

                    /* Apply album art color to volume bar */
                    --rgb-state-media-player: var(--album-art-color);

                    /* Apply gradient background to sticky media player using album art colors */
                    {% if is_state('media_player.currently_playing', ['playing', 'paused']) %}
                      --ha-card-background: linear-gradient(135deg, rgba({{ states('sensor.dark_vibrant_color') }}, 0.3), 
                                                                    rgba({{ states('sensor.dark_muted_color') }}, 0.3));
                    {% endif %} 
                  }
                  .actions {

                    /* Apply album art color to sticky media player controls */
                    --rgb-primary-text-color: var(--album-art-color);
                    --primary-text-color: rgb(var(--album-art-color));

                    /* Allow the album info to display more text */
                    max-width: fit-content;
                  }
                  mushroom-media-player-volume-control {

                    /* Fix the width of the volume bar */
                    width: 200px;
                  }
                  :host {

                    /* Add background to host to prevent transparent card */
                    border-radius: var(--ha-card-border-radius, 12px);
                    background: var(--card-background-color);

                    /* Assign album art color to variable used in sticky media player */
                    {% if is_state('media_player.currently_playing', ['playing', 'paused']) %}
                      --album-art-color: {{ states('sensor.muted_color') }};
                    {% else %}
                    
                      /* Hide the sticky media player when it is idle */
                      display: none !important;
                    {% endif %}

                    /* Make the media player sticky at the bottom of the page */
                    z-index: 9;
                    position: sticky;
                    position: -webkit-sticky;
                    bottom: 12px;
                  }

Could you provide more information, how you set up the media_player.currently_playing with the universal platform?

Hi rhysb, do you know how to do a sticky card in a css grid layout?