⚪ Bubble Card - A minimalist card collection for Home Assistant with a nice pop-up touch

Are you sure your sensor-name is the one you need? If it’s a boolean, it should be probably hass.states[‘binary_sensor.pv_uberschuss’].state instead of hass.states[‘sensor.pv_uberschuss’].state.

1 Like

Your answer helped me to get the right direction.
Before I created a template sensor which had the states “true” and “false”. This was indeed

hass.states['sensor.pv_uberschuss'].state

But I wasn’t able to check if this state is “true” or “false” because I don’t know how to compare the state with those “words”.

But now I deleted the template sensor and created a new binary sensor instead:

hass.states['binary_sensor.pv_uberschuss_binary'].state

And in the bubble styles I can now check if the binary sensor is “on” or “off”.

  .bubble-sub-button-1 {
    background-color: ${
    hass.states['binary_sensor.pv_uberschuss_binary'].state == "on" ? "var(--good-color)" :
    "none"
    } !important;
  }
1 Like

Great! Glad it worked out the way you wanted and I was able to help

Anyone? I also noticed that when using a vertical stack on the normal dashboard, the gaps are not like that. So the gaps are only bigger in pop-ups for some reason. Can’t find a setting for that either

My code to set decimal numbers (Example: 23.2 °C and 53 %)

${card.querySelector('.bubble-state').innerText =
  parseFloat(hass.states["sensor.lywsd03mmc_eingangsbereich_temperature"].state).toFixed(1) + " °C • " +
  parseFloat(hass.states["sensor.lywsd03mmc_eingangsbereich_humidity"].state).toFixed(0) + " %"
}

Same Code (Replace . to ,)

${card.querySelector('.bubble-state').innerText =
  parseFloat(hass.states["sensor.lywsd03mmc_eingangsbereich_temperature"].state).toFixed(1).replace('.', ',') + " °C • " +                
  parseFloat(hass.states["sensor.lywsd03mmc_eingangsbereich_humidity"].state).toFixed(0) + " %"
}
3 Likes

Is there a guide somewhere for camera popups?
I’m just not sure how to integrate non-bubble cards into a popup?? (or how to show a camera??)

Have you gotten any further with this? I’ve been looking for the same thing for a while now. Unfortunately I don’t have enough knowledge to set this up myself.

Just moving over from mushroom cards to bubble cards, just sharing where I’m at after the first day:

Temperature Cards show temps relative to 75F (Blue cooler, red warmer), battery states go from green at 100% to Red at 0%, and I’ve got a bunch of contional cards that will appear if something is out of the ordinary, like severe weather or smoke or something. Still working on pop up cards, for now this is all on one screen.

did you found a solution there?

Also doing the same for my phone dashboard.

Here one of the pages so far:

Hope people like

6 Likes

Like this. Are you templating the changed shape of the bubblecard somehow? I want to use a mix of bubble + mushroom cards and want to get the bubblecards styled more similarly to mushroom so they work better together.

1 Like

At the moment just using the inbuilt style function of the bubble cards. I am sure you could make it simpler but not got to that yet.

.bubble-button-card-container {
  color: rgba(244, 67, 54, 1) !important;
  font-family: Quicksand;
  background: White !important;
  box-shadow: 0px 3px 8px 0px rgba(244, 67, 54, 0.35) !important;
  border-radius: 20px;
  border-style: solid;
      border-width: 1px;
      border-color: rgba(244, 67, 54, 0.35) !important;
}
.bubble-icon {
color: rgba(244, 67, 54, 1) !important;
}
.bubble-sub-button {
color: White !important;
background-color: rgba(244, 67, 54, 1) !important;
border-radius: 12px;
}
.bubble-icon-container {
  background-color: white
      border-radius: 20px;
      border-style: solid;
      border-width: 1px;
      border-color: rgba(244, 67, 54, 0.2) !important;
}

Perfect, thanks - will have a play.

Would you mind sharing the yaml?

If you have the time. There’s parts I’d like to steal haha.

Side question for all, does anyone have issues with the state update on the card taking a while to update?

Like if I turn the light on via the dashboard it will indicate it is on through everything but the state which will remain as Off and vice versa.

Watch the indentation of your (CSS) code. I noticed that - when the indentation of your CSS isn’t on the correct level of indentation - the CSS sometimes is ignored, which leads to unexpected results.

Just a tip…

Will when I get the chance.

Yeah I know. It has been bugging me that the indents are wrong but at the moment it is very much a work in progress. Planning to finish it all and then go back and clean up some of the code.

Although so far not had the problem you described.

Could you probably share your sensor.doors_open and sensor.windows_open ??

Here is some yaml for some of the cards I have done so far. Please bear in mind they are a work in progress. Thanks.

type: custom:bubble-card
card_type: button
button_type: state
entity: person.william
name: Will
icon: mdi:face-man
force_icon: true
sub_button:
  - entity: person.william
    icon: fas:square-phone
    name: Call
    show_name: false
    show_state: false
    tap_action:
      action: url
      url_path: tel:"yournumber"
  - entity: person.william
    name: Text
    icon: mdi:comment-text
    tap_action:
      action: url
      url_path: sms:"yournumber"
  - entity: person.william
    name: Map
    icon: mdi:map-marker-radius
    tap_action:
      action: call-service
      navigation_path: Person
      service: script.select_person
      target: {}
      data:
        person: Will
        link: /dashboard-phone/person

styles: |2-

    .bubble-button-card-container {
     color: ${state === 'home' ? 'rgba(0, 128, 0, 1)' : 'rgba(255, 0, 0, 1)'} !important;
     font-family: Quicksand;
     background: White;
     box-shadow: ${state === 'home' ? '0px 3px 8px 0px rgba(0, 128, 0, 0.35)' : '0px 3px 8px 0px rgba(255, 0, 0,0.35)'} !important;
     border-radius: 20px;
     border-style: solid;
     border-width: 1px;
     border-color: ${state === 'home' ? 'rgba(0, 128, 0, 0.35)' : 'rgba(255, 0, 0,0.35)'} !important;
        
    }
    .bubble-icon {
     color: ${state === 'home' ? 'rgba(0, 128, 0, 1)' : 'rgba(255, 0, 0, 1)'} !important;
    }
    .bubble-sub-button {
     color: white !important;
     background-color: ${state === 'home' ? 'rgba(0, 128, 0, 1)' : 'rgba(255, 0, 0, 1)'} !important;
     border-radius: 12px;
    }
    .bubble-icon-container {
     background-color: white
     border-radius: 20px;
     border-style: solid;
     border-width: 1px;
     border-color: ${state === 'home' ? 'rgba(0, 128, 0, 0.35)' : 'rgba(255, 0, 0,0.35)'} !important;
    }
tap_action:
  action: none
double_tap_action:
  action: none
hold_action:
  action: none
button_action:
  tap_action:
    action: none
  double_tap_action:
    action: none
  hold_action:
    action: none

type: custom:bubble-card
card_type: button
name: Oil
icon: mdi:storage-tank
force_icon: true
sub_button:
  - entity: sensor.tank_percentage_full
    icon: fas:square-phone
    name: Call
    tap_action:
      action: url
      url_path: 'tel: supplierNumber'
  - entity: sensor.tank_percentage_full
    name: Mail
    icon: mdi:email-arrow-right
    tap_action:
      action: url
      url_path: >-
        mailto:[email protected]
        ?subject=Oil%20Order&body=Dear%20Sir%2FMadam%0D%0A%0D%0AI%20wanted%20to%20order%20some%20heating%20oil.%0D%0A%0D%0AI%20need%20up%20to%202000l.%0D%0A%0D%0APlease%20could%20you%20provide%20me%20with%20a%20quote%20for%20this%20and%20an%20approximate%20date%20when%20this%20could%20be%20delivered%3F%0D%0A%0D%0AKind%20regards%2C%0D%0A%0D%0A 
        Will
styles: |2-


    
  .bubble-button-card-container {
    color: rgba(0, 0, 128, 1) !important;
    font-family: Quicksand;
    background: White !important;
    box-shadow: 0px 3px 8px 0px rgba(0, 0, 128, 0.35) !important;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(0, 0, 128, 0.35) !important;
  }
  .bubble-icon {
    color: rgba(0, 0, 128, 1) !important;
  }
  .bubble-sub-button {
    color: White !important;
    background-color: rgba(0, 0, 128, 1) !important;
    border-radius: 12px;
  }
  .bubble-icon-container {
    background-color: white
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color:  rgba(0, 0, 128, 0.2) !important;
  }
show_attribute: true
button_type: state
entity: sensor.tank_percentage_full
show_last_changed: false
show_state: true

type: custom:bubble-card
card_type: button
button_type: state
name: Living Room
icon: mdi:home-thermometer-outline
force_icon: true
sub_button:
  - entity: climate.living_room
    name: Heat
    icon: mdi:fire
    tap_action:
      action: call-service
      service: climate.set_hvac_mode
      target:
        entity_id: climate.living_room
      data:
        hvac_mode: heat
  - entity: climate.living_room
    name: 'Off'
    icon: mdi:power
    tap_action:
      action: call-service
      service: climate.set_hvac_mode
      target:
        entity_id: climate.living_room
      data:
        hvac_mode: 'off'
  - entity: climate.living_room
    name: Increase
    icon: mdi:plus
    tap_action:
      target: {}
      service: script.change_temp
      data:
        climate: living_room
      action: call-service
  - entity: climate.living_room
    name: Set Temp
    show_attribute: true
    attribute: temperature
    show_icon: false
    tap_action:
      action: none
  - entity: climate.living_room
    name: Decrease
    icon: mdi:minus
    tap_action:
      target: {}
      service: script.change_temp_down
      data:
        climate: living_room
      action: call-service
  - name: Toggle
    icon: mdi:auto-mode
    tap_action:
      action: toggle
    entity: input_boolean.temp_toogle
styles: |2-

    .bubble-button-card-container {
        color: rgba(244, 67, 54, 1) !important;
        font-family: Quicksand;
        background: White;
        box-shadow: 0px 3px 8px 0px rgba(244, 67, 54, 0.35) !important;
        border-radius: 20px;
        border-style: solid;
        border-width: 1px;
        border-color: rgba(244, 67, 54, 0.35) !important;
    }
    .bubble-icon {
    
      color: rgba(244, 67, 54, 1) !important;
    }
    .bubble-sub-button {
      color: white !important;
      background-color: rgba(244, 67, 54, 1);
      border-radius: 12px;
    }
    .bubble-icon-container {
      background-color: white
      border-radius: 20px;
      border-style: solid;
      border-width: 1px;
      border-color:  rgba(244, 67, 54, 0.2) !important;
      
    }

    .bubble-sub-button-1 {
      display: ${hass.states['input_boolean.temp_toogle'].state === 'off' ? '' : 'none'} !important;
    }

      .bubble-sub-button-2 {
      display: ${hass.states['input_boolean.temp_toogle'].state === 'off' ? '' : 'none'} !important;
    }

      .bubble-sub-button-3 {
      display: ${hass.states['input_boolean.temp_toogle'].state === 'on' ? '' : 'none'} !important;
    }
      .bubble-sub-button-4 {
      display: ${hass.states['input_boolean.temp_toogle'].state === 'on' ? '' : 'none'} !important;
      background-color: rgba(244, 67, 54, 0.2);
      color: rgba(244, 67, 54, 1) !important;
      
    }
      .bubble-sub-button-5 {
      display: ${hass.states['input_boolean.temp_toogle'].state === 'on' ? '' : 'none'} !important;
    }
show_attribute: true
attribute: current_temperature
tap_action:
  action: none
double_tap_action:
  action: none
hold_action:
  action: none
button_action:
  tap_action:
    action: none
  double_tap_action:
    action: none
  hold_action:
    action: none
entity: climate.living_room

type: custom:bubble-card
card_type: button
name: Main Light
icon: mdi:lightbulb
force_icon: true
sub_button:
  - icon: mdi:power
    name: Power
    tap_action:
      action: call-service
      service: light.toggle
      target:
        entity_id: light.living_room_main_light
styles: |-
  .bubble-button-card-container {
    color: rgba(255, 174, 66, 1);
    font-family: Quicksand;
    background: White !important;
    box-shadow: 0px 3px 8px 0px rgba(255, 174, 66, 0.35) !important;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(255, 174, 66, 0.35) !important;
  }
  .bubble-icon {
    color: rgba(255, 174, 66, 1) !important;
  }
  .bubble-sub-button {
    color: White !important;
    background-color: rgba(255, 174, 66, 1) !important;
    border-radius: 12px;
  }
  .bubble-icon-container {
    background-color: white;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(255, 174, 66, 0.2) !important;
  }
  .bubble-range-slider {
    border-radius: 20px;
    color: rgba(255, 174, 66, 1) !important;
    }
  .bubble-range-fill {
    background-color: rgba(255, 174, 66, 0.3) !important;
    }
show_attribute: true
attribute: brightness
button_type: slider
entity: light.living_room_main_light
show_last_changed: false
show_state: true

type: custom:bubble-card
card_type: media-player
name: Sonos
show_state: true
show_attribute: true
hide:
  volume_button: true
styles: |-
  .bubble-media-player-container {
    color: rgba(20, 143, 119, 1) !important;
    font-family: Quicksand;
    background: White !important;
    box-shadow: 0px 3px 8px 0px rgba(20, 143, 119, 0.35) !important;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(20, 143, 119, 0.35) !important;
  }
  .bubble-icon {
    color: rgba(20, 143, 119, 1) !important;
  }
  .bubble-sub-button {
    color: White !important;
    background-color: rgba(20, 143, 119, 1) !important;
    border-radius: 12px;
  }
  .bubble-icon-container {
    background-color: white
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(20, 143, 119, 0.2) !important;
    
  }

  .bubble-play-pause-button {
    background-color: rgba(20, 143, 119, 1) !important;
    color: White !important;
    border-radius: 12px;
   }
   
  .bubble-power-button {
    background-color: rgba(20, 143, 119, 1) !important;
    color: White !important;
    border-radius: 12px;
   }

  .bubble-previous-button {
    background-color: rgba(20, 143, 119, 1) !important;
    color: White !important;
    border-radius: 12px;
   } 

  .bubble-next-button {
    background-color: rgba(20, 143, 119, 1) !important;
    color: White !important;
    border-radius: 12px;
   } 

  .bubble-volume-button {
    background-color: rgba(20, 143, 119, 1) !important;
    color: White !important;
    border-radius: 12px;
   } 
entity: media_player.kitchen_sonos

type: custom:bubble-card
card_type: button
name: Back Blind
icon: mdi:roller-shade
force_icon: true
sub_button:
  - icon: mdi:arrow-up
    name: Open
    tap_action:
      action: call-service
      service: cover.open_cover
      target:
        entity_id: cover.master_bedroom_back_blind
  - name: Stop
    icon: fas:stop
    tap_action:
      action: call-service
      service: cover.stop_cover
      target:
        entity_id: cover.master_bedroom_back_blind
  - entity: cover.master_bedroom_back_blind
    name: Close
    icon: mdi:arrow-down
    tap_action:
      action: call-service
      service: cover.close_cover
      target:
        entity_id: cover.master_bedroom_back_blind
styles: |-

  .bubble-button-card-container {
    color: rgba(179, 55, 113, 1) !important;
    font-family: Quicksand;
    background: White !important;
    box-shadow: 0px 3px 8px 0px rgba(179, 55, 113, 0.35) !important;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(179, 55, 113, 0.35) !important;
  }
  .bubble-icon {
    color: rgba(179, 55, 113, 1) !important;
  }
  .bubble-sub-button {
    color: White !important;
    background-color: rgba(179, 55, 113, 1) !important;
    border-radius: 12px;
  }
  .bubble-icon-container {
    background-color: white
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(179, 55, 113, 0.2) !important;
  }
  .bubble-sub-button-3 {
    display: ${hass.states['cover.master_bedroom_back_blind'].state === 'open' ? '' : 'none'} !important;
    }

  .bubble-sub-button-1 {
    display: ${hass.states['cover.master_bedroom_back_blind'].state === 'closed' ? '' : 'none'} !important;
    }
show_attribute: false
show_last_changed: false
show_state: true
tap_action:
  action: none
button_action:
  tap_action:
    action: none
button_type: state
entity: cover.master_bedroom_back_blind

type: custom:bubble-card
card_type: button
name: Boost + Schedule
icon: mdi:storage-tank
force_icon: true
sub_button:
  - icon: mdi:heat-wave
    name: Boost
    tap_action:
      action: call-service
      service: script.boost_select_room
      target: {}
      data:
        room: Living Room
        link: /dashboard-phone/boost-heating
  - name: Schedule
    icon: mdi:progress-clock
    tap_action:
      action: call-service
      service: script.boost_select_room
      target: {}
      data:
        room: Living Room
        link: /dashboard-phone/schedules
styles: |-
  .bubble-button-card-container {
    color: rgba(244, 67, 54, 1) !important;
    font-family: Quicksand;
    background: White !important;
    box-shadow: 0px 3px 8px 0px rgba(244, 67, 54, 0.35) !important;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(244, 67, 54, 0.35) !important;
  }
  .bubble-icon {
    color: rgba(244, 67, 54, 1) !important;
  }
  .bubble-sub-button {
    color: White !important;
    background-color: rgba(244, 67, 54, 1) !important;
    border-radius: 12px;
  }
  .bubble-icon-container {
    background-color: white
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(244, 67, 54, 0.2) !important;
  }
show_attribute: false
button_type: state
entity: script.boost_select_room
show_last_changed: false
show_state: false

type: custom:bubble-card
card_type: button
name: Power
icon: mdi:power-socket-uk
force_icon: true
sub_button:
  - icon: mdi:teddy-bear
    name: Child Lock
    tap_action:
      action: toggle
  - name: All Power
    icon: fas:circle-info
    tap_action:
      action: call-service
      service: script.power_select_room
      target: {}
      data:
        room: Living Room
        link: /dashboard-phone/power
styles: |-
  .bubble-button-card-container {
    color: rgba(101, 59, 159, 1) !important;
    font-family: Quicksand;
    background: White !important;
    box-shadow: 0px 3px 8px 0px rgba(101, 59, 159, 0.35) !important;
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(101, 59, 159, 0.35) !important;
  }
  .bubble-icon {
    color: rgba(101, 59, 159, 1) !important;
  }
  .bubble-sub-button {
    color: White !important;
    background-color: rgba(101, 59, 159, 1) !important;
    border-radius: 12px;
  }
  .bubble-icon-container {
    background-color: white
    border-radius: 20px;
    border-style: solid;
    border-width: 1px;
    border-color: rgba(101, 59, 159, 0.2) !important;
  }
show_attribute: true
attribute: friendly_name
button_type: state
entity: input_boolean.living_room_child_lock
show_last_changed: false
show_state: true
7 Likes

Another question guys. How can I change the behaviour of the iconcolor when the connected entity is not “on”?

Example:
image

As you can see the icon of the first bubble button “Hausspeicher” is solid white, beause the entity behind it is the state of charge of my PV battery.
The second bubble button is just a “name” bubble button and no “state”. It does not show an attribute. And as you can see the icon is white but not solid, it is “grayed out”, because somehow it is considered “off”.

How can I change this to a solid white instead?
What am I missing here?