Fun with custom:button-card

I’ve got the button background color working with

                - entity: binary_sensor.katie_smith_s_galaxy_s7_edge_presence_2
                  name: Katie
                  template: standard
                  type: 'custom:button-card'
                  state:
                    - value: 'on'
                      color: Gold
                    - value: 'off'
                      color: SlateGrey

I still haven’t quite figured out how to change the name color and icon color according to state. Suggestions?

Try using a styles section under the state. Using your example:

                - entity: binary_sensor.katie_smith_s_galaxy_s7_edge_presence_2
                  name: Katie
                  template: standard
                  type: 'custom:button-card'
                  state:
                    - value: 'on'
                      styles:
                        card:
                          - background-color: gold
                    - value: 'off'
                      styles:
                        card:
                          - background-color: slategrey

You can change a lot of visuals with the styles under each state value. The above should work fine for the background color for both on and off, but it can also be done this way:

                - entity: binary_sensor.katie_smith_s_galaxy_s7_edge_presence_2
                  name: Katie
                  template: standard
                  type: 'custom:button-card'
                  styles:
                    card:
                      - background-color: slategrey
                  state:
                    - value: 'on'
                      styles:
                        card:
                          - background-color: gold

That approach gives a standard style regardless of the state, then the on state adjusts what is needed for that state. This is particularly useful to avoid repeating the same settings in every state, such as font size. Also, since you are using the standard template, you can set the background color in that template instead of in the specific button. That will reduce what you need to define in your buttons.

1 Like

I just re-read your question about name and icon colors and realized I misunderstood in my initial reply. To affect those colors use the same styles sections under each state value and specify the styles for name and icon. Building on my other example:

                - entity: binary_sensor.katie_smith_s_galaxy_s7_edge_presence_2
                  name: Katie
                  template: standard
                  type: 'custom:button-card'
                  state:
                    - value: 'on'
                      styles:
                        card:
                          - background-color: gold
                        name:
                          - color: black
                        icon:
                          - color: white
                          - opacity: 0.5
                    - value: 'off'
                      styles:
                        card:
                          - background-color: slategrey
3 Likes

Perfect. Thanks for the help.

Here’s what I did with it: I created a set of additional templates, based on the standard one: (under button_card_templates)

  standard-button:
    template: standard
    state:
      - value: 'on'
        styles:
          card:
            - background-color: gold
          name:
            - color: blue
          icon:
            - color: blue
            - opacity: 1
      - value: 'off'
        styles:
          card:
            - background-color: slategrey
          name:
            - color: white
          icon:
            - color: white
            - opacity: 0.5
  standard-alert:
    template: standard
    state:
      - value: 'on'
        styles:
          card:
            - background-color: darkgrey
          name:
            - color: yellow
          icon:
            - color: yellow
            - opacity: 1
      - value: 'off'
        styles:
          card:
            - background-color: darkgrey
          name:
            - color: white
          icon:
            - color: white
            - opacity: 0.5
  standard-cover:
    template: standard
    state:
      - value: 'open'
        styles:
          card:
            - background-color: gold
          name:
            - color: blue
          icon:
            - color: blue
            - opacity: 1
      - value: 'closed'
        styles:
          card:
            - background-color: slategrey
          name:
            - color: white
          icon:
            - color: white
            - opacity: 0.5

Then, within my custom button cards, something like this:

                - entity: binary_sensor.katie_smith_s_galaxy_s7_edge_presence_2
                  name: Katie
                  template: standard-button
                  type: 'custom:button-card'

or this:

                - entity: binary_sensor.daytime_sensor
                  name: Day?
                  template: standard-alert
                  type: 'custom:button-card'

or this:

                    - entity: cover.garage
                      name: Over head
                      template: standard-cover
                      type: 'custom:button-card'
                      aspect_ratio: 1/1.3

That looks like it will work :+1:

The more you play with it the more you’ll see places where you can consolidate some of the settings. For example, the off’ state is pretty consistent across all 3 of your templates, so if you wanted to you could make a base template with that config that the other 3 use as a template. There is also an id feature for states that makes it possible for the templates to merge state configs correctly (even if the values aren’t the same!)

Just for fun, and because I like sharing ideas, here is a different way to define your templates given your example:

  standard-button:
    template: standard
    state:
      - id: value_on
        value: 'on'
        styles:
          card:
            - background-color: gold
          name:
            - color: blue
          icon:
            - color: blue
            - opacity: 1
      - id: value_off
        value: 'off'
        styles:
          card:
            - background-color: slategrey
          name:
            - color: white
          icon:
            - color: white
            - opacity: 0.5
  
  standard-alert:
    template: standard-button
    state:
      - id: value_on
        styles:
          card:
            - background-color: darkgrey
          name:
            - color: yellow
          icon:
            - color: yellow
      - id: value_off
        styles:
          card:
            - background-color: darkgey

  standard-cover:
    template: standard-button
    state:
      - id: value_on
        value: 'open'
      - id: value_off
        value: 'closed'

What I did was use your standard-button as a common template for the other two templates. I added id settings for the 2 states so that the other 2 templates can add or replace configs as needed.

In your standard-alert template I changed the state settings to refer to the id instead of the value and removed any settings already defined in the standard-button template, such as the icon opacity and a few other things.

In the standard-cover template I only had to change the value settings to open and closed, since the colors in the standard-button template are already what is needed.

The custom button card is so flexible that there is often more than a couple ways to get the desired effect. You could even use a single template to do this with some variables and javascript to adjust the colors. I’m having fun writing this up, so I’ll give an example:

  standard-button:
    template: standard
    variables:
      value_on: 'on'
      value_off: 'off'
      background_color_on: gold
      background_color_off: slategrey
      text_color_on: blue
      text_color_off: white
    state:
      - id: value_on
        value: '[[[ return variables.value_on ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_on ]]]'
          name:
            - color: '[[[ return variables.text_color_on ]]]'
          icon:
            - color: '[[[ return variables.text_color_on ]]]'
            - opacity: 1
      - id: value_off
        value: '[[[ return variables.value_off ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_off ]]]'
          name:
            - color: '[[[ return variables.text_color_off ]]]'
          icon:
            - color: '[[[ return variables.text_color_off ]]]'
            - opacity: 0.5

And then to use that template:

                # the variables don't need to be set because the template's default values are good
                - entity: binary_sensor.katie_smith_s_galaxy_s7_edge_presence_2
                  name: Katie
                  template: standard-button
                  type: 'custom:button-card'

                # same template, but setting a few variables to change colors
                - entity: binary_sensor.daytime_sensor
                  name: Day?
                  template: standard-button
                  type: 'custom:button-card'
                  variables:
                    background_color_on: darkgrey
                    background_color_off: darkgrey
                    text_color_on: yellow

                # again, same template but set some variables to change the on/off values
                - entity: cover.garage
                  name: Over head
                  template: standard-button
                  type: 'custom:button-card'
                  aspect_ratio: 1/1.3
                  variables:
                    value_on: open
                    value_off: closed

Hopefully that wasn’t too deep and it gives you a taste of what’s possible. :slight_smile:

1 Like

Not too deep at all and I can definitely see some other possibilities.
Thanks again.
I’d noticed the use of variables in another part of your example and had wanted to try using them. Your example is right along those lines.
As a side note, I’m always walking a balance point when I’m coding. I like to get things as elegant as possible without getting too cute (to the point where I won’t be able to remember what I did and why when I look back at it in a year :slight_smile: ) I made the mistake of some Byzantine CSS some time back. It looks like your examples are just the right level of actual simplification as opposed to obfuscation.

1 Like

I noticed that my garage cover has two additional states: “closing” and “opening”. (Go figure.) However, I like the fact that these don’t share the color theme with “open” or “closed”. It highlights that it’s in progress. A little serendipity along the way and something I can tweak if I decide to tweak it later.

Nice. I don’t have those states on mine.
We can easily add styling for those states like this:

  standard-cover:
    template: standard-button
    state:
      - id: value_on
        value: 'open'
      - id: value_off
        value: 'closed'
      - value: 'opening'
        styles:
          card:
            - background-color: magenta
      - value: 'closing'
        styles:
          card:
            - background-color: cyan

Or, if you were using the variables version:

                - entity: cover.garage
                  name: Over head
                  template: standard-button
                  type: 'custom:button-card'
                  aspect_ratio: 1/1.3
                  variables:
                    value_on: open
                    value_off: closed
                  state:
                    - value: 'opening'
                      styles:
                        card:
                          - background-color: magenta
                    - value: 'closing'
                      styles:
                        card:
                          - background-color: cyan
2 Likes

Yes. I’d figured something like that. I’m leaving it the way it is for now, but if I get an urge for completeness, I’ll that in.

One last question (I think):
Is there a way to change the name based on state? For instance, could the button tied to my binary_sensor.daytime_sensor (states ‘on’ or ‘off’) be “Day” when “on” and “Night” when “off”? I’m not entirely sure how to code the name text in the middle of a conditional state.

Specify the name you want in each of the states. You can set a few other things in states too, like icon and spin.

...
  state:
    - value: 'on'
      id: value_on
      name: Day
    - value: 'off'
      id: value_off
      name: Night
...
1 Like

Ah. I was lacking the id:
Thanks one more time.

The id is important when merging state settings because they are an array. If you don’t use the id then they are added to the array as new items. For example, if your template defines value: 'on' and your button also defines value: 'on' you will have 2 entries in your array for ‘on’ instead of one combined entry, and only one of them will be used (probably the one defined in the template because it is first in the final array). Merging states depends on the id because merging by value has significant challenges: the value could be javascript, or even if value is a literal the operator can be different and change the context what what the value represents. A nice benefit of using the id to merge state configs is that you don’t have to re-define the value or operator. This is especially useful when that value is javascript in the template.

Thanks for the explanation. I was trying to leverage that a little further. My presence device (person.russell_smith) has several states (home, not_home, Work, Church (as defined by my zones)). I cast this to binary_sensor.russ_sensor to toggle home/away status. I thought it would be interesting to use the multi-status “person” device in my indicator. At first I thought I could do something like

                - entity: person.russell_smith
                  name: Russ
                  template: standard-button
                  type: 'custom:button-card'
                  aspect_ratio: 1/1.07
                  styles:
                    name:
                      - font-size: 0.47em
                  state:
                    - value: home
                      id: value_on
                      name: Russ home
                      icon: 'mdi:home'
                    - value: not_home
                      id: value_off
                      name: Russ away
                      icon: 'mdi:home-outline'
                      variables:
                        text_color_off: yellow
                    - value: Work
                      id: value_off
                      name: Russ work
                      icon: 'mdi:office-building'
                      variables:
                        text_color_off: powderblue
                    - value: Church
                      id: value_off
                      name: Russ church
                      icon: 'mdi:church'
                      variables:
                        text_color_off: plum

but that didn’t work. So I added two more states to the standard_button:

    state:
      - id: value_on
        value: '[[[ return variables.value_on ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_on ]]]'
          name:
            - color: '[[[ return variables.text_color_on ]]]'
          icon:
            - color: '[[[ return variables.text_color_on ]]]'
            - opacity: 1
      - id: value_off
        value: '[[[ return variables.value_off ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_off ]]]'
          name:
            - color: '[[[ return variables.text_color_off ]]]'
          icon:
            - color: '[[[ return variables.text_color_off ]]]'
            - opacity: 0.5
      - id: value_2
        value: '[[[ return variables.value_2 ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_2 ]]]'
          name:
            - color: '[[[ return variables.text_color_2 ]]]'
          icon:
            - color: '[[[ return variables.text_color_2 ]]]'
            - opacity: 0.5
      - id: value_3
        value: '[[[ return variables.value_3 ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_3 ]]]'
          name:
            - color: '[[[ return variables.text_color_3 ]]]'
          icon:
            - color: '[[[ return variables.text_color_3 ]]]'
            - opacity: 0.5

and then coded my indicator like this:

                - entity: person.russell_smith
                  name: Russ
                  template: standard-button
                  type: 'custom:button-card'
                  aspect_ratio: 1/1.07
                  styles:
                    name:
                      - font-size: 0.47em
                  state:
                    - value: home
                      id: value_on
                      name: Russ home
                      icon: 'mdi:home'
                    - value: not_home
                      id: value_off
                      name: Russ away
                      icon: 'mdi:home-outline'
                      variables:
                        text_color_off: yellow
                    - value: Work
                      id: value_2
                      name: Russ work
                      icon: 'mdi:office-building'
                    - value: Church
                      id: value_3
                      name: Russ church
                      icon: 'mdi:church' 

It works, but I’m not sure why I could just load into the value_off id array with the Work and Church values.

I think in your first yaml you just needed to remove the id for Work and Church. You have id: value_off for not_home, Work and Church…effectively merging them together and clobbering the first 2 with the last one. You just need Work and Church to be added to the array as separate states. You only need the id’s if needing to configure the same states in multiple templates and/or the top level button. If you want to keep the id’s on them, make them unique.

1 Like

I see… and now I understand just a tad more of the way this works.
Thank you.

I decided to do a similar thing with the garage “cover” as follows:

                    - entity: cover.garage_door_opener
                      template: standard-button
                      type: 'custom:button-card'
                      aspect_ratio: 1/1.3
                      styles:
                        name:
                          - font-size: 0.47em
                      state:
                        - value: open
                          id: value_on
                          name: Overhead open
                        - value: closed
                          id: value_off
                          name: Overhead closed
                        - value: opening
                          name: Overhead opening
                          icon: 'mdi:arrow-up-bold-box-outline'
                        - value: closing
                          name: Overhead closing
                          icon: 'mdi:arrow-down-bold-box-outline'

That all works wonderfully, but I also tried changing the background color for opening and closing by adding the lines

                      variables:
                        text_color_off: DarkCoral

right under the icon setting. That didn’t work. Any ideas?

I also added the code

                      tap_action:
                        action: call-service
                        service: cover.toggle
                        service_data:
                          entity_id: cover.garage_door_opener

So now, instead of calling up the “more information” window (which will actually let me open or close the door, but it needs one more tap to open and one more to close the window), a tap will toggle the door open or closed depending on its current state.

I don’t believe variables can be set in the state config. If you want to change the background color in a state config you need to use styles:

                        - value: opening
                          name: Overhead opening
                          icon: 'mdi:arrow-up-bold-box-outline'
                          styles:
                            card:
                              - background-color: DarkCoral
1 Like