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

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