Fun with custom:button-card

Still my fav card this, been playing around recently and addeding different elements to it.

Thank you. I think that is the solution.
On another note…
Is it possible to dynamically move card or element inside card? Replacing hard coded position coordinate with variable driven by different entity?

Hey All,

I’m trying to add the mini-graph as it shows in this post; Fun with custom:button-card - #852 by edwardtich

However, when I’ve added this into my button-card, it’s just adding [object Object] in place of the graph. I can’t work out what I’m doing wrong, and ChatGPT isn’t helping me either (ha!).

Any ideas?

SCR-20231120-kkhu

type: custom:button-card
entity: light.office_light_switch
icon: mdi:desk
name: Office
tap_action:
  action: navigate
  navigation_path: /lovelace/office
  haptic: medium
styles:
  grid:
    - grid-template-areas: '"i temp" "n hum" "graph graph"'
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content min-content
  card:
    - background: var(--contrast2)
    - padding: 16px
    - '--mdc-ripple-press-opacity': 0
  img_cell:
    - justify-self: start
    - width: 24px
  icon:
    - width: 24px
    - height: 24px
    - color: var(--contrast8)
  name:
    - justify-self: start
    - font-size: 14px
    - margin: 4px 0 4px 0
    - color: var(--contrast)
    - font-family: Montserrat
    - font-weight: 600
  custom_fields:
    temp:
      - align-self: start
      - justify-self: end
      - font-size: 13px
      - font-weight: 500
      - margin: 4px 0 0px 0
      - color: var(--contrast8)
      - font-family: Montserrat
    hum:
      - align-self: start
      - justify-self: end
      - font-size: 13px
      - font-weight: 500
      - margin: 4px 0 12px 0
      - color: var(--contrast8)
      - font-family: Montserrat
    graph:
      - padding-top: 0%
      - width: 100%
      - height: 100%
      - margin-bottom: '-3%'
custom_fields:
  temp: |
    [[[
    return `<ha-icon
      icon="mdi:thermometer"
      style="width: 18px; height: 18px; color: var(--orange);">
      </ha-icon><span>${parseFloat(states['sensor.office_temperature_sensor_temperature'].state).toFixed(0)}°C</span>`
    ]]]
  hum: |
    [[[
    return `<ha-icon
      icon="mdi:water-percent"
      style="width: 18px; height: 18px; color: var(--blue);">
      </ha-icon> <span>${parseFloat(states['sensor.office_temperature_sensor_humidity'].state).toFixed(0)}%</span>`
    ]]]
  graph:
      type: custom:mini-graph-card
      entities:
      - entity: sensor.office_temperature_sensor_temperature
        name: Temperature
        color: '#ff8c00'
      - entity: sensor.office_temperature_sensor_humidity
        name: Humidity
        color: '#3399ff'
        y_axis: secondary
      height: 50
      hours_to_show: 24
      line_width: 3
      font_size: 50
      animate: true
      show:
        name: false
        icon: false
        state: false
        legend: false
        fill: fade
      card_mod:
        style: |
          ha-card {
            position: absolute !important;
            height: 100%;
            width: 100%;
            top: 0px;
            --ha-card-border-width: 0;
          }
          ha-card:after {
            content: "";
            position: absolute;
            width: 100%;
            height: 100%;
            background: linear-gradient(to right, var(--card-background-color) 20%, transparent);
          }
state:
  - value: 'on'
    styles:
      card:
        - background: |
            [[[
                var color = entity.attributes?.rgb_color;
                if (entity.state != "on"){
                  return 'var(--contrast20)';
                }
                else if (color){
                  return 'rgba(' + color + ')'
                }
                else{
                  return 'var(--yellow)'
                }
            ]]]
      icon:
        - color: var(--red)
        - animation: bounce 2s infinite
      name:
        - color: var(--black)
  - value: 'off'
    styles:
      name:
        - color: var(--contrast20)
extra_styles: |
  @keyframes bounce {
    0% { transform: scale3d(1, 1, 1); }
          7% { transform: scale3d(1.25, 0.75, 1); }
          10% { transform: scale3d(0.75, 1.25, 1); }
          12% { transform: scale3d(1.15, 0.85, 1); }
          16% { transform: scale3d(0.95, 1.05, 1); }
          19% { transform: scale3d(1.05, 0.95, 1); }
          25% { transform: scale3d(1, 1, 1); }
  }

EDIT: I managed to get this working, and also do some cool stuff with it. So now, when the entity is on, the color of the name changes, and the icon bounces.

If anyone is interested in using my code to add to their setup, it is below.

type: custom:stack-in-card
cards:
  - type: custom:button-card
    entity: light.living_room_light_switch
    icon: '[[[ return entity.attributes.icon ]]]'
    show_icon: false
    name: Living Room
    tap_action:
      action: navigate
      navigation_path: /lovelace/living-room
      haptic: medium
    styles:
      card:
        - background: var(--contrast2)
        - padding: 16px
        - '--mdc-ripple-press-opacity': 0
      icon_cells:
        - justify-self: start
        - margin-top: 12px
        - margin-left: 15px
        - animation: |
            [[[
              var state = states['light.living_room_light_switch'].state;
              return state === 'on' ? 'bounce 2s infinite' : 'none';
            ]]]
      img_cell:
        - justify-self: start
        - width: 24px
      custom_fields:
        temp:
          - align-self: start
          - justify-self: end
          - font-size: 13px
          - font-weight: 500
          - margin: 4px 0 0px 0
          - color: var(--contrast8)
          - font-family: Montserrat
        hum:
          - align-self: start
          - justify-self: end
          - font-size: 13px
          - font-weight: 500
          - margin: 1px 0 12px 0
          - color: var(--contrast8)
          - font-family: Montserrat
        graph:
          - padding-top: 0%
          - width: 100%
          - height: 100%
        icon_cells:
          - width: 24px
          - height: 24px
          - color: var(--contrast8)
          - animation: |
              [[[
                var state = states['light.living_room_light_switch'].state;
                return state === 'on' ? 'bounce 2s infinite' : 'none';
              ]]]
      name:
        - justify-self: start
        - font-size: 14px
        - margin: 1px 0 1px 0
        - color: |
            [[[
              var state = states['light.living_room_light_switch'].state;
              return state === 'on' ? 'white' : 'grey';
            ]]]
        - font-family: Montserrat
        - font-weight: 600
      grid:
        - grid-template-areas: '"icon_cells slider temp" "n slider hum"'
        - grid-template-columns: 1fr min-content 1fr
        - grid-template-rows: 1fr min-content min-content
    custom_fields:
      icon_cells: |
        [[[
         var state = states['light.living_room_light_switch'].state;
         if(state == "on")
          return `<ha-icon
          icon="mdi:sofa"
          style="width: 25px; height: 25px; color: yellow;">
          </ha-icon>
          `;
         else 
          return `<ha-icon
          icon="mdi:sofa-outline"
          style="width: 25px; height: 25px; color: grey;">
          </ha-icon>
          `;
        ]]]
      temp: |
        [[[
          return `<ha-icon
          icon="mdi:thermometer"
          style="width: 18px; height: 18px; color: var(--orange);">
          </ha-icon><span>${parseFloat(states['sensor.living_room_temp_sensor_temperature'].state).toFixed(0)}°C</span>`
        ]]]
      hum: |
        [[[
          return `<ha-icon
          icon="mdi:water-percent"
          style="width: 18px; height: 18px; color: var(--blue);">
          </ha-icon> <span>${parseFloat(states['sensor.living_room_temp_sensor_humidity'].state).toFixed(0)}%</span>`
        ]]]
    card_mod:
      style: |
        ha-card {
          z-index: 1;
          height: 70px;
        }
    extra_styles: |
      @keyframes bounce {
        0% { transform: scale3d(1, 1, 1); }
        7% { transform: scale3d(1.25, 0.75, 1); }
        10% { transform: scale3d(0.75, 1.25, 1); }
        12% { transform: scale3d(1.15, 0.85, 1); }
        16% { transform: scale3d(0.95, 1.05, 1); }
        19% { transform: scale3d(1.05, 0.95, 1); }
        25% { transform: scale3d(1, 1, 1); }
      }
  - type: custom:mini-graph-card
    entities:
      - entity: sensor.living_room_temp_sensor_temperature
        name: Temperature
        color: '#ff8c00'
      - entity: sensor.living_room_temp_sensor_humidity
        name: Humidity
        color: '#3399ff'
        y_axis: secondary
    height: 40
    hours_to_show: 24
    line_width: 3
    font_size: 50
    show:
      name: false
      icon: false
      state: false
      legend: false
    card_mod:
      style: |
        ha-card {
          position: absolute;
          height: 100%;
          width: 100%;
          top: 0px;
          --ha-card-border-width: 0;
        }
        ha-card:after {
          content: "";
          position: absolute;
          width: 100%;
          height: 100%;
        }

Light On:
image

Light Off:
image

2 Likes

encja

How to use a fan that rotated proportionally to the entity’s rotation.

type: custom:button-card
state:
  - value: 'on'
    color: blue
    spin: true
entity: entity: sensor.panasonic_heat_pump_main_fan2_motor_speed
show_state: tfalse
icon: mdi:fan

Hi,
Have look here…

This may help:

OK. I have one other question. How can I add a second circle field directly below the original circle field without impacting the position of the icon, name, or state? I would like to add a second circle below the one shown, without affecting the position of anything on the left side of the card.

image

Here is my current card code. Thanks in advance for any help. I tried just making a second field called “fuel” and put it in the right column next to l, s, n and copied the circle code. But it altered the location of my name and label.

truck:
  template:
    - base
  variables:
    state_on: >
      [[[ return states["sensor.garage_fordpass_ignitionstatus"].state == 'ON' ]]]
    circle_input: >
      [[[ return states["sensor.garage_fordpass_fuel"].state ]]]
  state_display: >
    [[[
      if (entity) {
          return variables.state === 'home'
              ? variables.translate_home
              : variables.state === 'not_home'
                  ? variables.translate_not_home
                  : variables.state;
      }
      return variables.translate_unknown;
    ]]]
  tap_action:
    action: more-info
  double_tap_action:
    action: more-info
    entity: sensor.garage_fordpass_fuel
  hold_action:
    action: toggle
    entity: switch.garage_fordpass_ignition_switch
  styles:
    grid:
      - grid-template-areas: |
          "icon  circle"
          "n     n"
          "s     s"
          "l     l"
      - grid-template-columns: repeat(2, 1fr)
      - grid-template-rows: auto repeat(3, min-content)
      - gap: 1.3%
      - align-items: start
      - will-change: transform
    name:
      - justify-self: start
      - line-height: 110%
      - font-size: 15px
      - font-weight: bold
    state:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    label:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    card:
      - --c-color-home: none
      - --c-color-away: none
      - --c-color-zone: none
      - --c-stroke-width: none
      - --c-icon-color-on: var(--contrast1)
      - --c-icon-color-off: '#97989c'
      - --c-stroke-color-on: var(--contrast1)
      - --c-stroke-color-off: '#97989c'
      - --c-stroke-color-power-off: none
      - --c-fill-color-on: none
      - --c-fill-color-off: none
      - --c-fill-color-power-off: none
      - --c-stroke-width: 2.3
      - --c-stroke-width-dragging: 4
      - --c-font-color-on: var(--contrast1)
      - --c-font-color-off: '#97989c'
      - --c-font-color-power-off: none
      - --c-font-size: 14px
      - --c-unit-font-size: 10.5px
      - --c-font-weight: 700
      - --c-letter-spacing: -0.02rem
      - background-image: >
          [[[
            if (variables.state === 'home') {
            return `linear-gradient(to bottom, rgba(50,168,82,1) 0%, rgba(50,168,82,1) 52%, rgba(0,0,0,0) 48%)`;
            }
            if (variables.state === 'BHS') {
            return `linear-gradient(to bottom, rgba(255,191,0,1) 0%, rgba(255,191,0,1) 52%, rgba(0,0,0,0) 48%)`;
            }
            if (variables.state === 'CCAC') {
            return `linear-gradient(to bottom, rgba(255,191,0,1) 0%, rgba(255,191,0,1) 52%, rgba(0,0,0,0) 48%)`;
            }
            if (variables.state === 'Lowes') {
            return `linear-gradient(to bottom, rgba(255,191,0,1) 0%, rgba(255,191,0,1) 52%, rgba(0,0,0,0) 48%)`;
            }
            if (variables.state === 'Stantec') {
            return `linear-gradient(to bottom, rgba(255,191,0,1) 0%, rgba(255,191,0,1) 52%, rgba(0,0,0,0) 48%)`;
            }
            if (variables.state === 'Vernon') {
            return `linear-gradient(to bottom, rgba(255,191,0,1) 0%, rgba(255,191,0,1) 52%, rgba(0,0,0,0) 48%)`;
            } else {
            return `linear-gradient(to bottom, rgba(255,0,0,1) 0%, rgba(255,0,0,1) 52%, rgba(0,0,0,0) 48%)`;
            }
          ]]]
    custom_fields:
      circle:
        - display: initial
        - width: 100%
        - margin: -9% 0 0 0
        - justify-self: center
        - opacity: 1
  custom_fields:
    circle: >
      [[[
        if (variables.state_on) {
            let input = variables.circle_input,
              r = 22,
              c = r * 2 * Math.PI,
              dasharray = c,
              dashoffset = c - input / 100 * c;
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${r}" stroke='var(--c-stroke-color-on)' stroke-dashoffset="${dashoffset}" stroke-dasharray="${dasharray}" stroke-width='var(--c-stroke-width)' fill='var(--c-fill-color-on)' style="transform: rotate(-90deg); transform-origin: 50% 50%;" />
              <text x="50%" y="54%" fill='var(--c-font-color-on)' font-size='var(--c-font-size)' text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${variables.circle_input}<tspan font-size='var(--c-unit-font-size)'>%</tspan></text>
            </svg>
          `;
        } else {
            let input = variables.circle_input,
              r = 22,
              c = r * 2 * Math.PI,
              dasharray = c,
              dashoffset = c - input / 100 * c;
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="22" stroke='var(--c-stroke-color-off)' stroke-dashoffset="${dashoffset}" stroke-dasharray="${dasharray}" stroke-width='var(--c-stroke-width)' fill='var(--c-fill-color-off)' style="transform: rotate(-90deg); transform-origin: 50% 50%;" />
              <text x="50%" y="54%" fill='var(--c-font-color-off)' font-size='var(--c-font-size)' text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${variables.circle_input}<tspan font-size='var(--c-unit-font-size)'>%</tspan></text>
            </svg>
          `;
        }
      ]]]

I tried to just copy the current custom field and altered the code, but I ended up with this.
image

I would really appreciate it if someone could help me with a problem that I can’t solve or understand. FYI I the noob of the noobs so…don’t laugh xD

As you can see in the image below, I have a problem with those cards when viewing them on a iPhone 11. One thing I learned is if I remove all the icons I don’t have any problem.

The code below is for the second card…

Thank you all in advance!

type: custom:button-card
name: Praia de Miramar
entity: weather.praia_de_miramar
label: |
  [[[
     const temperature = states["weather.praia_de_miramar"].attributes.temperature;
     const humidity = states["weather.praia_de_miramar"].attributes.humidity;
     return `<ha-icon icon="fas:temperature-half" style="height:15px; color: #E3DA29;"></ha-icon> ${temperature}°C <ha-icon icon="fas:droplet" style="height:15px; color: #29abe2;"></ha-icon> ${humidity}%`;
   ]]]
show_label: true
show_name: true
show_icon: true
size: 45px
color: '#f1c64d'
card_size: 10
styles:
  card:
    - padding: 7px
    - background: rgba(0, 0, 0, 0.4)
    - border: none
    - border-radius: 100px
    - width: 100%
  grid:
    - grid-template-areas: '"i n" "i l"'
    - grid-template-rows: min-content min-content
    - grid-template-columns: 0.8fr 1.5fr
    - padding-right: 12px
  label:
    - font-family: Montserrat, sans-serif
    - font-size: 1.1rem
    - line-height: 1
    - justify-self: right
    - font-weight: 1000
    - text-align: right
    - width: 100%
    - margin-left: 24px
  name:
    - align: right
    - font-size: 0.8rem
    - line-height: 1
    - font-weight: 200
    - width: 100%
    - text-align: right

EDIT: Nevermind. I was able to figure this out.

I have a custom button card that shows the number of people at home. It turns on when there is anyone at home and it reports the number of people home within the circle. As shown.
image

When everyone leaves, I have an automation that waits for an hour before adjusting the HVAC so that it is not constantly fluctuating for short trips. I have been able to show a progress bar for the countdown. On other cards though, I have been able to show a countdown for other timers by using an embedded button-card.
image

I am struggling on how to get this to happen within this card. Essentially, I want the card like it is in the first picture when someone is home. While the automation is counting down, I would like for it to be the second picture with the addition of the countdown timer. And finally when there is no one home and the countdown is complete it would be this.
image

I guess my question is how can I have the sensor count and the countdown timer overlap the same area of the card and only show up when the appropriate states are met. I have included a copy of my current code for the button.

Button card code

  - type: custom:button-card
    template:
      - base
      - icon_home2
    variables:
      timer: >
        [[[ return states["timer.leaving"].state == 'active' ]]]
      circle_input: >
        [[[ return states["sensor.people_home"].state]]]
    entity: group.humans
    name: Presence
    show_state: true
    state_display: >
      [[[
        if (entity) {
            return variables.state === 'home'
                ? variables.translate_home
                : variables.state === 'not_home'
                    ? variables.translate_not_home
                    : variables.state;
        }
        return variables.translate_unknown;
      ]]]
    tap_action:
      action: more-info
    styles:
      card:
        - --c-stroke-color-on: var(--contrast1)
        - --c-stroke-color-off: none
        - --c-fill-color-on: none
        - --c-fill-color-off: none
        - --c-stroke-width: 2.3
        - --c-stroke-width-dragging: 4
        - --c-font-color-on: var(--contrast1)
        - --c-font-color-off: none
        - --c-font-size: 14px
        - --c-font-weight: 700
        - --c-letter-spacing: -0.02rem
      custom_fields:
        circle:
          - display: initial
          - width: 88%
          - margin: -3% 2% 0 0
          - justify-self: end
          - opacity: 1
        timer:
          - display: block
          - position: absolute
          - top: >
              [[[
                return window.matchMedia('(max-width: 1200px)').matches
                    ? '82%'
                    : '89%';
              ]]]
          - left: -13%
          - width: 125%
    custom_fields:
      circle: >
        [[[
          if (variables.state_on) {
            return `
              <svg viewBox="0 0 50 50">
                <circle cx="25" cy="25" r="22" stroke='var(--c-stroke-color-on)' stroke-width='var(--c-stroke-width)' fill='var(--c-fill-color-on)' />
                <text x="50%" y="54%" fill='var(--c-font-color-on)' font-size='var(--c-font-size)' font-weight='var(--c-font-weight)' letter-spacing='var(--c-letterlspacing)' text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${variables.circle_input}</text>
              </svg>
            `;
          } else {
            return `
              <svg viewBox="0 0 50 50">
                <circle cx="25" cy="25" r="22" stroke='var(--c-stroke-color-off)' stroke-width='var(--c-stroke-width)' fill='var(--c-fill-color-off)' />
                <text x="50%" y="54%" fill='var(--c-font-color-off)' font-size='var(--c-font-size)' font-weight='var(--c-font-weight)' letter-spacing='var(--c-letterlspacing)' text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${variables.circle_input}</text>
              </svg>
            `;
          }
        ]]]
      timer:
        card:
          type: custom:timer-bar-card
          entity: timer.leaving
          layout: full_row
          text_width: 0px
          invert: true
          bar_foreground: >
            [[[
              return variables.timer
                  ? '#3182b7'
                  : 'none';
            ]]]
          bar_background: none
          modifications:
            - elapsed: 90%
              bar_foreground: 'rgb(255,0,0)'

Base template code.

base:
  template:
    - settings
    - extra_styles
  variables:
    state_on: >
      [[[ return ['on', 'home', 'heat_cool', 'Complete', 'Running', 'Fresh', 'Charging', 'Started'].indexOf(!entity || entity.state) !== -1; ]]]
    state_home: >
      [[[ return ['home'].indexOf(!entity || entity.state) !== -1; ]]]
    state_zone: >
      [[[ return ['BHS', 'CCAC', 'Harmony', 'Stantec', 'Vernon'].indexOf(!entity || entity.state) !== -1; ]]]
    state_away: >
      [[[ return ['not_home'].indexOf(!entity || entity.state) !== -1; ]]]
    state: >
      [[[ return !entity || entity.state; ]]]
    entity_id: >
      [[[ return !entity || entity.entity_id; ]]]
    entity_picture: >
      [[[ return !entity || entity.attributes.entity_picture; ]]]
  aspect_ratio: 1/1
  show_state: false
  show_label: false
  show_icon: false
  styles:
    grid:
      - grid-template-areas: |
          "icon   circle"
          "n      n"
          "l      l"
          "s      s"
      - grid-template-columns: repeat(2, 1fr)
      - grid-template-rows: auto repeat(3, min-content)
      - gap: 1.3%
      - align-items: start
      - will-change: transform
      - position: relative
    name:
      - justify-self: start
      - line-height: 110%
      - font-size: 15px
      - font-weight: bold
    state:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    label:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    card:
      - overflow: hidden
      - border-radius: 10px
      - border-width: 0px
      - -webkit-tap-highlight-color: rgba(0,0,0,0)
      - transition: none
      - --mdc-ripple-color: >
          [[[
            return variables.state_on
                ? 'var(--contrast1)'
                : '#97989c';
          ]]]
      - color: >
          [[[
            return variables.state_on
                ? 'var(--contrast1)'
                : '#97989c';
          ]]]
      - background-color: >
          [[[
            return variables.state_on
                ? 'var(--contrast20)'
                : 'rgba(115, 115, 115, 0.25)';
          ]]]

EDIT: I was able to figure it out with the use of conditional cards.

Are you asking for my help? I am not sure what you need or that I can even help.

Hey guys, can someone give me a hint why my color template won’t work?

type: custom:button-card
entity: input_button.helper_staus_wechseln_aussensteckdose
icon: |
  [[[
    if (states['input_select.shelly1pm_eingangsbereich_aussen_aussensteckdose'].state == "Dauer An")
       return 'mdi:power-on';
    if (states['input_select.shelly1pm_eingangsbereich_aussen_aussensteckdose'].state == "Aus")
       return 'mdi:power-off';
    else return 'mdi:clock'
  ]]]
name: Außensteckdose
label: |
  [[[
    return states['input_select.shelly1pm_eingangsbereich_aussen_aussensteckdose'].state ;
  ]]]
show_label: true
color: |
  [[[
    if (states['switch.shelly_eingangsbereich_aussen_aussensteckdose'].state == "on")
       return "red";
    else 
      return "lightGrey";
  ]]]
hold_action:
  action: more-info
tap_action:
  action: call-service
  service: input_select.select_next
  service_data:
    entity_id: input_select.shelly1pm_eingangsbereich_aussen_aussensteckdose
    cycle: true
styles:
  label:
    - color: gray
    - font-size: 12px
  grid:
    - grid-template-areas: '"i" "n" "s" "l"'
    - grid-template-columns: 1fr
    - grid-template-rows: 1fr min-content min-content
  img_cell:
    - align-self: center
    - text-align: center
  name:
    - justify-self: center
    - padding-left: 0px
    - font-weight: bold
    - font-size: 12px
  state:
    - justify-self: start
    - padding-left: 10px

Guys, I’m looking for a way to create a button that:

  • toggles a script to mute/unmute my mediaplayers
  • the icon should represent the state

This is what I have:

show_name: false
show_icon: true
type: custom:button-card
styles:
  card:
    - height: 60px
tap_action:
  action: toggle
entity: script.toggle_volume_mediaplayers
icon:
  - color: |
      [[[
        if (input_boolean.mediaplayersmuted == 'on') return 'red';
        else return 'white';
      ]]] 
state:
  - value: 'on'
    icon: mdi:volume-off
  - value: 'off'
    icon: mdi:volume-high

How do I get the icon to show an unmuted/muted speaker with the right primary and accent colors (used some colors for my test in the code above)?
The state changes only briefly when toggling the button.

Thanks a lot for any help!

Dear all, could someone point me to the right direction on how to give to a custom button a “particular” color if weekday is today??
I have 7 custom buttons (from monday to sunday) and wanna give orange color to the sunday button (if today is sunday).

thanks a lot

You’d need card_mod for that, something like this:

card_mod:
  style:
    .: |
      ha-card {       
        /* Set size and spacing of button */

        {% if states('sensor.example) == 'True' %}
          background: rgba(70, 130, 180, 0.5) !important;
        {% else %}
          background: rgba(199, 224, 238, 0.5) !important; 
        {% endif %}
        }

I tried to follow the example posted by OP to organize custom buttons using card templates. Initially seemed like everything is working fine.

But then I noticed that sometimes when I open dashboard with these components - they are not rendering. Refreshing the page (if in browser) or switching to another dashboard and re-opening previous dashboard “fixes” it till next time.

Then I spotted a JavaScript errors in the console:

TypeError: Cannot read properties of undefined (reading 'style')
    at button-card.js:426:18867
    at Ti._createCard (button-card.js:426:19038)
    at button-card.js:445:213
    at Array.forEach (<anonymous>)
    at Ti._buildCustomFields (button-card.js:445:30)
    at Ti._gridHtml (button-card.js:524:25)
    at Ti._buttonContent (button-card.js:506:454)
    at Ti._cardHtml (button-card.js:486:18)
    at Ti.render (button-card.js:426:19509)
    at Ti.update (button-card.js:1:14818)
Uncaught (in promise) TypeError: e.setConfig is not a function
    at Ti.render (button-card.js:426:19640)
    at Ti.update (button-card.js:1:14818)
    at Ti.performUpdate (button-card.js:1:6145)
    at Ti.scheduleUpdate (button-card.js:1:5792)
    at Ti._$Ej (button-card.js:1:5700)

Apparently, something isn’t working as expected and causing the custom button card to fail to render.
After experimenting a bit I found out that it’s only happens when child cards are added into custom:button-car container.

This doesn’t happens 100 out of 100. Sometimes, after countless refreshes, there will be no error and the card would render.

If I comment the custom_fields node in the first card (horizontal-stack) - the card renders fine (an empty container with title “Garage”) and there is no JS errors. I can refresh the page whole day and it will work. A second card in the view - a standalone custom button card renders just fine, without any errors.

Seems like custom button card used as a container expect children cards to have certain properties in JavaScript, which are not set/undefined.

Does anyone have this issue?

button_card_templates:
  standard:
    color_type: card
    size: 80%
    hold_action:
      action: more-info
    styles:
      card:
        - padding: 0.2em
        - '--mdc-ripple-color': yellow
        - '--mdc-ripple-press-opacity': 0.5
      icon:
        - opacity: 0.5
      name:
        - font-size: 0.65em
        - white-space: normal
      state:
        - font-size: 0.65em
        - white-space: normal
      label:
        - font-size: 0.4em
        - white-space: normal
  wide:
    template: standard
    styles:
      grid:
        - position: relative
        - grid-template-areas: '"i n"'
        - grid-template-columns: 1fr 1fr
        - grid-template-rows: 1fr
  container:
    color_type: label-card
    color: dimgray
    styles:
      card:
        - padding: 0
      name:
        - border-radius: 0.4em 0.4em 0 0
        - padding: 0.1em
        - width: 100%
        - font-weight: bold
      grid:
        - grid-template-areas: '"i" "n" "buttons"'
        - grid-template-columns: 1fr
        - grid-template-rows: 1fr min-content min-content
      custom_fields:
        buttons:
          - background-color: rgba(0,0,0,0.3)
          - margin: 0
          - padding: 0.3em
views:
  - title: Home
    cards:
      - type: custom:button-card
        color: '#EDE7B0'
        name: Garage Card
        # custom_fields:
        #   buttons:
        #     card:
        #       type: horizontal-stack
        #       cards:
        #         - entity: light.garage_ceiling_ligths_garage_ceiling_lights
        #           name: Ceiling Lights
        #           template: standard
        #           icon: mdi:lightbulb-fluorescent-tube
        #           type: custom:button-card
        #         - entity: switch.garage_workbench_lights_relay
        #           name: Workbench Lights
        #           template: standard
        #           icon: mdi:lightbulb-fluorescent-tube-outline
        #           type: custom:button-card
      - type: custom:button-card
        entity: light.garage_ceiling_ligths_garage_ceiling_lights

@n6ham, I haven’t seen that issue on my dashboards. I noticed you don’t have template: container on your top level card. The container template defines styles for the “buttons” custom field, but I wouldn’t think it would cause an error if you aren’t using the template. I have no idea why you are getting that error.

Right, I was messing around and removed the template.
Added it back, but still getting this problem.
It only appears when I refresh the page of the dashboard.
Switching between the dashboards somehow fixes it

Ok, I narrowed down the problem a little further. Here’s the dashboard code that works (i.e. does not throw and renders consistently with a minor glitch in icon color of the button).

Removing or commenting non-custom horizontal-stack container will break the dashboard. Moving it below the custom container will break it as well.

It feels like there’s something going on with initialization of some JS objects that only works properly when a custom container is not the first container in the dashboard.

button_card_templates:
  standard:
    color_type: card
    size: 80%
    hold_action:
      action: more-info
    styles:
      card:
        - padding: 0.2em
        - '--mdc-ripple-color': yellow
        - '--mdc-ripple-press-opacity': 0.5
      icon:
        - opacity: 0.5
      name:
        - font-size: 0.65em
        - white-space: normal
      state:
        - font-size: 0.65em
        - white-space: normal
      label:
        - font-size: 0.4em
        - white-space: normal
  wide:
    template: standard
    styles:
      grid:
        - position: relative
        - grid-template-areas: '"i n"'
        - grid-template-columns: 1fr 1fr
        - grid-template-rows: 1fr
  container:
    color_type: label-card
    styles:
      card:
        - padding: 0
      name:
        - border-radius: 0.4em 0.4em 0 0
        - padding: 0.1em
        - width: 100%
        - font-weight: bold
      grid:
        - grid-template-areas: '"i" "n" "buttons"'
        - grid-template-columns: 1fr
        - grid-template-rows: 1fr min-content min-content
      custom_fields:
        buttons:
          - margin: 0
          - padding: 0.3em
views:
  - title: Home
    cards:
      - type: horizontal-stack
        cards:
          - type: entity
            entity: sensor.cpu_temperature
      - type: custom:button-card
        color: '#EDE7B0'
        name: Garage Card
        template: container
        custom_fields:
          buttons:
            card:
              type: horizontal-stack
              cards:
                - entity: light.garage_ceiling_ligths_garage_ceiling_lights
                  name: Ceiling Lights
                  template: standard
                  icon: mdi:lightbulb-fluorescent-tube
                  type: custom:button-card
                - entity: switch.garage_workbench_lights_relay
                  name: Workbench Lights
                  template: standard
                  icon: mdi:lightbulb-fluorescent-tube-outline
                  type: custom:button-card

Hi,

while I am restructuring my Home Assistant instance, I am also getting into button_card_templates and I love the idea of the different code segments splitted in different files and folders.
However, I am not getting it to work :frowning:

I have a folder called /config/common/button-card-templates - where I have one file per template .

Within this folder I have a template file called header_chip.yaml, which contains yaml code as follows:

header_chip:
  variables:
    var_path: 'var_path'
    var_icon: 'var_icon'
    var_iconColor: 'var_iconColor'
    var_name: 'var_name'

  tap_action:
    action: navigate
    navigation_path: '[[[ return variables.var_path ]]]'
  name: '[[[ return variables.var_name ]]]'
  content_info: none
  icon: '[[[ return variables.var_icon ]]]'
  icon_color: '[[[ return variables.var_iconColor ]]]'
  use_entity_picture: false

and this template I reference in a file called living-room.yaml, which contains code follows:

title: home
button_card_templates: !include_dir_merge_named ../../common/button-card-templates/

views:
  - title: Test-Dash
    cards:
      - type: custom:mushroom-chips-card
        chips:
          - type: weather
            show_conditions: true
            show_temperature: true
            entity: weather.forecast_home

      - type: custom:mushroom-chips-card
        chips:
          - type: custom:button-card
            template: header_chip
            entity: person.nebuhome
            variables:
              var_path: '/Office'
              var_icon: 'mdi:desk'
              var_iconColor: 'var(--orange)'
              var_name: 'Test41'

While the weather shows up, the template does not show up, and I have no idea why that is.
The reference of !include_dir_merge_named works - I have tested that with another reference.

Anybody an idea, what I am doing wrong?

Thanks a lot for any help!