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

If you’re willing to get very deep into CSS there is a way to get a bubble-button-card to be a 2x2.

image

But just to get this much working I had to do all this CSS:

.card-content {
  width: 100%;
  margin: 0 !important;
}

.large .bubble-button-card-container {
  height: 184px !important;
  overflow: hidden !important;
}

.bubble-button-card {
  display: grid;
  grid-template-areas:
    'n n n b'
    'l l l b'
    'i i . b'
    'i i . b';
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1.5fr 0.5fr 1fr 1fr;
  justify-items: center;
}

.bubble-icon-container {
  grid-area: i;
  border-radius: 50% !important;
  width: 150% !important;
  height: 150% !important;
  max-width: none !important;
  max-height: none !important;
  position: absolute !important;
  # left: -33% !important;
  # top: -33% !important;
  # transform: translate(-50%, -50%) !important;
  # margin-top: 25% !important;
  # margin-left: -25% !important;
  place-self: center !important;
  margin: 0px 0px 20px 20px !important;
  padding: 0px, 0px, 0px, 0px !important;
}

.bubble-icon {
  position: relative !important;
  --mdc-icon-size: 100px !important;
  opacity: 0.5 !important;
}

.bubble-name-container {
  # width: 100%;
  grid-area: n;
  justify-self: start;
  margin-left: 20px;
  max-width: calc(100% -(12px + 0px));
}

.bubble-name {
  font-weight: bold;
  font-size: 16px;
}

.bubble-state {
  font-weight: bold;
  font-size: 14px;
}

.rows-2 .bubble-sub-button-container {
  grid-area: b;
  display: flex !important;
  flex-wrap: wrap;
  flex-direction: column;
  justify-content: flex-start;
  # width: 40px;
  # grid-template-columns: min-content;
  # grid-template-rows: repeat(5, 1fr);
  width: auto !important;
  padding-right: 0px;
  height: 100% !important;
  margin-top: 25px;
}

.bubble-sub-button {
  min-width: 36px !important;
}

Not to mention I also had to make sure to change the card to be a 2x2 in the layout tab from HA for the card UI.

5 Likes

Dear @Cloos ,

I have completely shifted my dashboard to bubble card, except one button which I am using from mushroom card.

In the screenshot there are two buttons, the above one is from mushroom card and the below is from bubble card.

I am able to add the required animation to button using bubble card. I have no idea how to add the below two things which I am using with the button using mushroom card.

  1. The badge on the icon which tells how much time is remaining for the switch.
  2. The ring(progress bar).

Mushroom Card Button Code

type: custom:mushroom-template-card
icon: "{{ 'mdi:fountain' if is_state(entity, 'on') else 'mdi:fountain' }}"
icon_color: "{{ 'green' if is_state(entity, 'on') else 'grey' }}"
primary: Fountain
entity: switch.fountain
card_mod:
  style:
    mushroom-shape-icon$: |
      .shape {
       {% if is_state(config.entity, 'on') %}
          --card-background-color: rgba(21, 38, 18,1);
       {% else %}
         --card-background-color: rgba(87, 72, 30,1); 
       {% endif %}
        background: radial-gradient(var(--card-background-color) 60%, transparent calc(60% + 1px)), conic-gradient(var(--icon-color) {{  (states("counter.fountain_timer")|int/60/states("input_number.fountain_inching")|int*100 ) }}% 0%, var(--card-background-color) 0% 100%);
      }
    .: |
      ha-state-icon {
        {% if is_state(config.entity, 'on') %}
          animation: fountain 1.5s ease infinite;
        {% endif %}  
      }  
      mushroom-shape-icon:after {
        {% if is_state(config.entity, 'on') %}
          content: '{{ states('input_number.fountain_inching')|int-(states("counter.fountain_timer")|float/60)|round(0) }}';
        {% endif %}                      
        
        position: absolute;
        top: -11%;
        right: -11%;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 15px;
        height: 15px;
        font-size: 10px;
        font-weight: 700;
        background-color: rgba(var(--rgb-amber), 0.5);
        border-radius: 50%;
      }
      @keyframes fountain { 
        0%, 100% { clip-path: polygon(0 100%,0 0, 100% 0, 100% 100%); }
        50% { clip-path: polygon(0 100%, 0 47%, 100% 47%, 100% 100%); }
        60% { clip-path: polygon(0 100%, 100% 100%, 100% 37%, 79% 36%, 71% 21%, 56% 25%, 44% 25%, 31% 20%, 20% 36%, 0 36%); }
        70% { clip-path: polygon(0 100%, 100% 100%, 100% 36%, 79% 36%, 71% 22%, 81% 1%, 24% 0, 31% 21%, 20% 36%, 0 36%); }
        80% { clip-path: polygon(0 100%, 100% 100%, 100% 36%, 79% 36%, 76% 28%, 100% 0, 0 0, 23% 28%, 20% 36%, 0 36%); }
      } 

Bubble Card Button Code

type: custom:bubble-card
card_type: button
icon: mdi:fountain
name: Fountain
entity: switch.fountain
styles: |-
  .bubble-icon {
    animation: ${hass.states['switch.fountain'].state === 'on' ? 'fountain 1.5s ease infinite' : ''};
    color: ${hass.states['switch.fountain'].state === 'on' ? 'green' : 'grey'} !important;
  } 
  @keyframes fountain { 
    0%, 100% { clip-path: polygon(0 100%,0 0, 100% 0, 100% 100%); }
    50% { clip-path: polygon(0 100%, 0 47%, 100% 47%, 100% 100%); }
    60% { clip-path: polygon(0 100%, 100% 100%, 100% 37%, 79% 36%, 71% 21%, 56% 25%, 44% 25%, 31% 20%, 20% 36%, 0 36%); }
    70% { clip-path: polygon(0 100%, 100% 100%, 100% 36%, 79% 36%, 71% 22%, 81% 1%, 24% 0, 31% 21%, 20% 36%, 0 36%); }
    80% { clip-path: polygon(0 100%, 100% 100%, 100% 36%, 79% 36%, 76% 28%, 100% 0, 0 0, 23% 28%, 20% 36%, 0 36%); }
  } 
  .bubble-button-background {
    opacity: 1 !important;
    background-color: ${state === 'on' ? 'green' : 'none'} !important;
  }  

@Cloos How to make the badge and circular progressbar using bubble card button.

I would really appreciate your help and guidance.

Thank you.

2 Likes

Hello @Cloos

Thank you very much for the answer I specify that I do not use the “theme” Bubble I would like to apply this style just on my Bubble cards. but i think with that

.bubble-button-card-container {
  border-radius: 15px;
  }
  .bubble-button-background {
  border-radius: 15px;
  }

in the Custom Style / Template is ok no ?

I insist sorry @Cloos but would you have an answer for this question?

Thank you in advance

Hey @ddewar

Really good job !!! ans i love it

there would be a possibility that you share the complete code of your card please, I tried to copy what you shared but unfortunately it does not work for me.
Thanks

For such cards I would rather directly go with button card, which allows this and much more. That is why I am still hesitating to go full on bubble card, I always face points where the button card is more suitable, although it has no GUI and is purely yaml.

Can you share the full code for this card? :pray:

Exactly what I was trying to develop the upcoming days… Love the idea of the animated ring as a progress-indicator, or timer functionality…

The notification-badges are really simple too make. I’ll do that all the time with a bit of extra CSS and the ::after argument. Just position the element absolute, give it a bg-color, with a width/height and use content to set the javascript content.

@stefan1982
Can you please help with the exact code…

Thank you

Inside the bubble-card style section:

  ha-card::after {
    position: absolute;
    top: -10px;
    left: -10px;
    padding: 0 10px;
    border-radius: 999px;
    border: 1px solid black;
    color: #fff;
    content: "a small tiny badge";
    background: red;
    display: block;
  }

Thank you so much. How to display the content from a variable ?

Any idea how to implement the ring progress indicator ?

Sure, also @stefan1982 tagging you because you asked as well.

type: custom:bubble-card
card_type: button
button_type: state
name: Family Room
icon: mdi:television
sub_button:
  - entity: light.family_room_lights
    show_last_changed: false
    show_attribute: false
    show_state: false
    tap_action:
      action: toggle
    show_background: true
    hold_action:
      action: call-service
      service: input_select.select_option
      data:
        option: family_room_lights
      target:
        entity_id: input_select.minimalist_ui_switch
    double_tap_action:
      action: call-service
      service: input_select.select_option
      data:
        option: family_room_lights
      target:
        entity_id: input_select.minimalist_ui_switch
  - entity: fan.family_room_ceiling_fan_fan
    tap_action:
      action: toggle
    double_tap_action:
      action: more-info
    hold_action:
      action: more-info
  - entity: media_player.family_room_assistant
    show_last_changed: false
    show_state: false
    show_name: false
    tap_action:
      action: toggle
  - entity: vacuum.slider
    tap_action:
      action: toggle
    double_tap_action:
      action: more-info
    hold_action:
      action: more-info
card_layout: large-2-rows
button_action:
  tap_action:
    action: navigate
    navigation_path: family-room
tap_action:
  action: navigate
  navigation_path: family-room
styles: >
  .card-content {
    width: 100%;
    margin: 0 !important;
  }


  .large .bubble-button-card-container {
    height: 175px !important;
    overflow: hidden !important;
  }


  .bubble-button-card {
    display: grid;
    grid-template-areas:
      'n n n b'
      'l l l b'
      'i i . b'
      'i i . b';
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: 1.5fr 0.5fr 1fr 1fr;
    justify-items: center;
  }


  .bubble-icon-container {
    grid-area: i;
    border-radius: 50% !important;
    width: 150% !important;
    height: 150% !important;
    max-width: none !important;
    max-height: none !important;
    position: absolute !important;
    # left: -33% !important;
    # top: -33% !important;
    # transform: translate(-50%, -50%) !important;
    # margin-top: 25% !important;
    # margin-left: -25% !important;
    place-self: center !important;
    margin: 0px 0px 0px 0px !important;
    padding: 0px, 0px, 0px, 0px !important;
    background-color: rgba(var(--color-jojoba), 0.75) !important;
  }


  .bubble-icon {
    width: 40%;
    position: relative !important;
    --mdc-icon-size: 100px !important;
    opacity: 0.5 !important;
  }


  .bubble-name-container {
    # width: 100%;
    grid-area: n;
    justify-self: start;
    margin-left: 20px;
    max-width: calc(100% -(12px + 0px));
  }


  .bubble-name {
    font-weight: bold;
    font-size: 16px;
  }


  .bubble-state {
    font-weight: bold;
    font-size: 14px;
  }


  .rows-2 .bubble-sub-button-container {
    grid-area: b;
    display: flex !important;
    flex-wrap: wrap;
    flex-direction: column;
    justify-content: flex-start;
    # width: 40px;
    # grid-template-columns: min-content;
    # grid-template-rows: repeat(5, 1fr);
    width: auto !important;
    padding-right: 0px;
    height: 100% !important;
    margin-top: 25px;
  }


  .bubble-sub-button {
    min-width: 36px !important;
  }

  .bubble-sub-button-1 {
    # color: rgba(var(${hass.states['fan.family_room_ceiling_fan_fan'].state === 'on' ? '--color-yellow' : ''}), 1) !important;
    # background-color: rgba(var(${hass.states['light.family_room_lights'].state === 'on' ? '--color-yellow' : ''}), 0.3) !important;
  }

  .bubble-sub-button-2 {
    color: rgba(var(${hass.states['fan.family_room_ceiling_fan_fan'].state === 'on' ? '--color-blue' : ''}), 1) !important;
    background-color: rgba(var(${hass.states['fan.family_room_ceiling_fan_fan'].state === 'on' ? '--color-blue' : ''}), 0.3) !important;
  }

  .bubble-sub-button-3 {
    color: rgba(var(${hass.states['media_player.family_room_assistant'].state != 'playing' ? '' : '--color-green'}), 1) !important;
    background-color: rgba(var(${hass.states['media_player.family_room_assistant'].state != 'playing' ? '' : '--color-green'}), 0.3) !important;
  }

  .bubble-sub-button-4 {
    color: rgba(var(${hass.states['vacuum.slider'].state === 'cleaning' ? '--color-purple' : ''}), 1) !important;
    background-color: rgba(var(${hass.states['vacuum.slider'].state === 'cleaning' ? '--color-purple' : ''}), 0.3) !important;
  }

  .rows-2 .bubble-sub-button {
    height: 36px !important;  
  }


  .bubble-sub-button-2 .bubble-sub-button-icon {
    animation: ${hass.states['fan.family_room_ceiling_fan_fan'].state === 'on' ? 'slow-rotate 2s linear infinite' : ''};
  }

  @keyframes slow-rotate {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }


  ${subButtonIcon[0].setAttribute("icon",
  hass.states['light.family_room_lights'].state === 'on' ? 'mdi:lightbulb-group'
  : 'mdi:lightbulb-off')}

  ${subButtonIcon[1].setAttribute("icon",
  hass.states['fan.family_room_ceiling_fan_fan'].state === 'on' ? 'mdi:fan' :
  'mdi:fan-off')}

  ${subButtonIcon[2].setAttribute("icon",
  hass.states['media_player.family_room_assistant'].state === 'playing' ?
  'mdi:speaker' : 'mdi:speaker-off')}

  ${subButtonIcon[3].setAttribute("icon", hass.states['vacuum.slider'].state ===
  'cleaning' ? 'mdi:robot-vacuum' : 'mdi:robot-vacuum-off')}
layout_options:
  grid_columns: 2
  grid_rows: 3
entity: sensor.family_room_temperature_sensor_temperature
show_attribute: false
show_name: true
show_icon: true
scrolling_effect: true
show_state: true
hold_action:
  action: navigate
  navigation_path: family-room

Also, this video probably has a much better way of doing it than I did. I used the bubble card sub buttons because I like them more than creating my own.

6 Likes

Totally get that. I’ve been really enjoying the Bubble-Card project, so I went this route to see how far I could push it. Moving X number of subbuttons around means less work for me coding wise if I only need some CSS and the subbutton number.

I have been trying this extension for some time now and find it very nice and useful.

I would really like to have an option for pop-ups that allows them to open like a sub-menu instead of in full screen mode, similar to the Expander card:

GitHub - Alia5/lovelace-expander-card: Expander card for HomeAssistant

1 Like

Hi!
I have just started using bubble cards and I absolutely love them.
The only missing for me at the moment is thermostat card, but mushroom climate fits quite well.
Anyhow, I have been trying to set up simple dashboard with separate views for each floor so I couold have floating and auto ordering navigation panel at the bottom - separate for each floor so it doesn;t get messy.
I am running latest update of HA OS and latest bubble cards release.
My problem is that auto ordering on my cards doesnt work at all!
I have made sure its card is at the bottom of the section as last card in the config.
It renders properly but is static until I slide it.
It shows light status though.
I also tried moving the card to another (last) section and I kept it there single - still no go.
Any ideas? What am I doing wrong?

views:
  - icon: mdi:numeric-negative-1
    path: ug
    cards: []
    theme: clear-dark
    type: sections
    sections:
      - type: grid
        cards:
          - type: heading
            heading_style: title
            heading: cellar
          - type: custom:bubble-card
            card_type: horizontal-buttons-stack
            auto_order: true
            1_name: Master
            1_icon: mdi:sofa-single
            1_link: '#master'
            1_entity: light.master
            1_pir_sensor: binary_sensor.ff_master_bedroom_motion
            2_name: Master
            2_icon: mdi:toilet
            2_link: '#masterbath'
            2_entity: light.master_bathroom
            2_pir_sensor: binary_sensor.ff_master_bathroom_motion
            3_name: Corridor
            3_icon: kuf:scene_corridor
            3_link: '#ffcorridor'
            3_entity: light.ff_hallway_1
            3_pir_sensor: binary_sensor.ff_corridor_motion
            4_name: Zosia
            4_icon: mdi:teddy-bear
            4_link: '#zosia'
            4_entity: light.zosia
            4_pir_sensor: binary_sensor.ff_zosia_s_room_motion
            5_name: Zosia
            5_icon: mdi:bathtub
            5_link: '#zosiabath'
            5_entity: light.zosia_s_bathroom
            5_pir_sensor: binary_sensor.ff_zosia_s_bathroom_motion
            6_name: guest
            6_icon: kuf:scene_visit_guests
            6_link: '#guest'
            6_entity: light.guest
            6_pir_sensor: binary_sensor.ff_guest_room_motion
            7_link: '#library'
            7_name: Library
            7_icon: mdi:library
            7_entity: light.library
            7_pir_sensor: binary_sensor.ff_library_motion
        column_span: 2
    theme: clear-dark

@Cloos

Plz help

Hi! Indeed Bubble Card doesn’t supports timers yet (I really need to work on that), but someone did find a way to do it with custom styling and templates, here is the link:

https://www.reddit.com/r/BubbleCard/s/JwNLqRleWV

1 Like

Did you figure this out? I’d also like the song info to be displayed the full width of the bubble instead of jammed in between the icon and buttons.

No not yet, I guess it can be achieved with CSS. But its out of my technical expertise.

@Cloos mentioned that he will be doing something about this in the next beta.

Like in mushroom media card there are three alignment options. Requesting @Cloos to consider doing something like that.

Until then I am still looking for a solution.

Thank you so so much @Cloos :heart::heart:

It worked.

type: custom:bubble-card
card_type: separator
sub_button:
  - entity: sensor.processor_temperature
    show_background: false
    show_state: true
  - entity: sensor.processor_use
    show_background: false
    show_state: true
  - entity: sensor.weather_room_humidity
    show_background: false
    show_state: true
  - entity: sensor.weather_room_temperature
    show_background: false
    show_state: true

How to decrease the spacing between sub button entities?

I have one more sensor entity to fit in the same row.

Kindly guide