Fun with custom:button-card

if you want a scrolling text, just search the community for it. there are examples of button-card using the actual scroll html feature. but since that is supposed to be outdated, you can also find examples of the new way of doing it, with Css translateX()

I m sure because I posted about both :wink:

Sep-20-2024 11-57-17

(nevermind the hiccups here, which is caused by the screen vid resolution, it’s buttery smooth on the desktop, even with the custom ticker tape font )

btw the ask of dos1973 seems another, those are not scrolling cards with text? seem more of a bar card tbh. many example in the comm. too.

no one is going to make the card for you probably, so give it some effort and bring back the results here so we can check them and help

Could anyone help me?

hi there, just a question cause I am dealing to understand this card a bit deeper, whats the n and i stand for in the grid-template-area property?

I cant understand it, its clear for me when you point to a temp, btn or whatever, since you declare it later on in the custom_fields field, but this two and others I see often in other examples i cant see whatś its meaning.

Hi, have you seen this: GitHub - custom-cards/button-card: ❇️ Lovelace button-card for home assistantADVANCED styling options

1 Like

nice, that worked! I have taken a look before, but didn´t see it in there, now with a deeper dive I just found it. thankl you

1 Like

Here’s my news-ticker…

Config:

  - platform: feedparser
    name: CTV News
    date_format: "%a, %d %b %Y %H:%M:%S %Z"
    feed_url: "https://www.ctvnews.ca/rss/ctvnews-ca-top-stories-public-rss-1.822009"
    inclusions: title
    exclusions: []
    scan_interval:
      minutes: 15
    show_topn: 20

  - platform: feedparser
    name: Google News
    date_format: "%a, %d %b %Y %H:%M:%S %Z"
    feed_url: "https://www.google.ca/alerts/feeds/00028625660956993271/15040452229692133315"
    inclusions: title
    exclusions: []
    scan_interval:
      minutes: 15
    show_topn: 20

  ## CTV NEWS

  - platform: template
    sensors:
      ctv_news_attributes_0:
        friendly_name: "CTV News Content 0"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[0].title }}

  - platform: template
    sensors:
      ctv_news_attributes_1:
        friendly_name: "CTV News Content 1"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[1].title }}

  - platform: template
    sensors:
      ctv_news_attributes_2:
        friendly_name: "CTV News Content 2"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[2].title }}

  - platform: template
    sensors:
      ctv_news_attributes_3:
        friendly_name: "CTV News Content 3"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[3].title }}

  - platform: template
    sensors:
      ctv_news_attributes_4:
        friendly_name: "CTV News Content 4"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[4].title }}

  - platform: template
    sensors:
      ctv_news_attributes_5:
        friendly_name: "CTV News Content 5"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[5].title }}

  - platform: template
    sensors:
      ctv_news_attributes_6:
        friendly_name: "CTV News Content 6"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[6].title }}

  - platform: template
    sensors:
      ctv_news_attributes_7:
        friendly_name: "CTV News Content 7"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[7].title }}

  - platform: template
    sensors:
      ctv_news_attributes_8:
        friendly_name: "CTV News Content 8"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[8].title }}

  - platform: template
    sensors:
      ctv_news_attributes_9:
        friendly_name: "CTV News Content 9"
        value_template: >
          {{ states.sensor.ctv_news.attributes.entries[9].title }}

  ## GOOGLE NEWS

  - platform: template
    sensors:
      google_news_attributes_0:
        friendly_name: "Google News Content 0"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[0].title }}

  - platform: template
    sensors:
      google_news_attributes_1:
        friendly_name: "Google News Content 1"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[1].title }}

  - platform: template
    sensors:
      google_news_attributes_2:
        friendly_name: "Google News Content 2"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[2].title }}

  - platform: template
    sensors:
      google_news_attributes_3:
        friendly_name: "Google News Content 3"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[3].title }}

  - platform: template
    sensors:
      google_news_attributes_4:
        friendly_name: "Google News Content 4"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[4].title }}

  - platform: template
    sensors:
      google_news_attributes_5:
        friendly_name: "Google News Content 5"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[5].title }}

  - platform: template
    sensors:
      google_news_attributes_6:
        friendly_name: "Google News Content 6"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[6].title }}

  - platform: template
    sensors:
      google_news_attributes_7:
        friendly_name: "Google News Content 7"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[7].title }}

  - platform: template
    sensors:
      google_news_attributes_8:
        friendly_name: "Google News Content 8"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[8].title }}

  - platform: template
    sensors:
      google_news_attributes_9:
        friendly_name: "Google News Content 9"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[9].title }}

  - platform: template
    sensors:
      google_news_attributes_10:
        friendly_name: "Google News Content 10"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[10].title }}

  - platform: template
    sensors:
      google_news_attributes_11:
        friendly_name: "Google News Content 11"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[11].title }}

  - platform: template
    sensors:
      google_news_attributes_12:
        friendly_name: "Google News Content 12"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[12].title }}

  - platform: template
    sensors:
      google_news_attributes_13:
        friendly_name: "Google News Content 13"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[13].title }}

  - platform: template
    sensors:
      google_news_attributes_14:
        friendly_name: "Google News Content 14"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[14].title }}

  - platform: template
    sensors:
      google_news_attributes_15:
        friendly_name: "Google News Content 15"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[15].title }}

  - platform: template
    sensors:
      google_news_attributes_16:
        friendly_name: "Google News Content 16"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[16].title }}

  - platform: template
    sensors:
      google_news_attributes_17:
        friendly_name: "Google News Content 17"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[17].title }}

  - platform: template
    sensors:
      google_news_attributes_18:
        friendly_name: "Google News Content 18"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[18].title }}

  - platform: template
    sensors:
      google_news_attributes_19:
        friendly_name: "Google News Content 19"
        value_template: >
          {{ states.sensor.google_news.attributes.entries[19].title }}

YAML:

type: custom:html-card
view_layout:
  position: main
content: |
  <div class="ticker-wrap">
    <div class="ticker">
      <img src="/local/images/the-weather-network-6.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span>
      <span class="ticker__item" style="color: #FFFFFF; font-weight: bold; animation: flashBlue 1s infinite;">WEATHER OUTLOOK </span>
      <style>
      @keyframes flashBlue {
        0% { color: #0984ff; font-weight: bold; }
        50% { color: #000000; font-weight: bold; }
        100% { color: #0984ff; font-weight: bold; }
      }
      </style>
      <span class="ticker__item"  color: #FFFFFF; font-weight: bold;">Current Temperature: [[ sensor.seaton_st_realfeel_temperature ]]°C </span>
      <span class="ticker__item"  color: #FFFFFF; font-weight: bold;">Today's High: [[ sensor.seaton_st_realfeel_temperature_max_day_0 ]]°C </span>
      <span class="ticker__item"  color: #FFFFFF; font-weight: bold;">Current Conditions: [[ sensor.toronto_summary ]] [[ sensor.seaton_st_condition_day_0 ]]. </span>
      <span class="ticker__item"  color: #FFFFFF; font-weight: bold;">Tonight: [[ sensor.seaton_st_condition_night_0 ]]. </span>
      <span class="ticker__item"  color: #FFFFFF; font-weight: bold;">Total Hours of Sun Today: [[ sensor.seaton_st_hours_of_sun_day_0 ]]. </span>
      <span class="ticker__item"  color: #FFFFFF; font-weight: bold;">Air Quality Today: [[ sensor.seaton_st_air_quality_day_0 ]]. <img src="/local/images/the-weather-network-6.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span></span>
      <span class="ticker__item" style="color: #39FF14;">Ragweed Pollen Index:</span><span style="color: white; font-weight: bold;"> [[ sensor.seaton_st_ragweed_pollen_day_0 ]]</span>
      <span class="ticker__item" style="color: #39FF14;">Grass Pollen Index:</span><span style="color: white; font-weight: bold;">  [[ sensor.seaton_st_grass_pollen_day_0 ]]</span>
      <span class="ticker__item" style="color: #39FF14;">Tree Pollen:</span><span style="color: white; font-weight: bold;">  [[ sensor.seaton_st_tree_pollen_day_0 ]]</span>
      <span class="ticker__item" style="color: #FFFFFF; animation: flashRed 1s infinite;">NEWS HEADLINES FOR TODAY <span style="color: green; font-weight: bold;"></span> </span>
      <style>
      @keyframes flashRed {
        0% { color: red; font-weight: bold; }
        50% { color: #000000; font-weight: bold; }
        100% { color: red; font-weight: bold; }
      }
      </style>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_0 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_1 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_2 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_3 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_4 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_5 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_6 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_7 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_8 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.ctv_news_attributes_9 ]]  |  <img src="/local/images/ctv-news.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_0 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_1 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_2 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_3 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_4 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_5 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_6 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_7 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"> </span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_8 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_9 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_10 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_11 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_12 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_13 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_14 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_15 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_16 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_17 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_18 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
      <span class="ticker__item"  color: #FFFFFF;">[[ sensor.google_news_attributes_19 ]]  |  <img src="/local/images/google-news-4.png" alt="logo" style="height: 20px; vertical-align: middle;"></span> </span>
    </div>
  <style>
    ha-card {
      height: 0px;
      visibility: hidden;
      z-index: 99;
    }    
    
    @keyframes ticker {
      0% {
        transform: translate3d(0, 0, 0);
        visibility: visible;
      }
      100% {
        transform: translate3d(-100%, 0, 0);
        }
      }  
      .ticker-wrap {
        font-family: tahoma;
        font-size: 1.3rem;
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        overflow: hidden;
        height: 2.5rem;
        background-color: black;
        visibility: visible;
        padding-left: 100%;
        box-sizing: content-box;
      }
      .ticker {
        display: inline-block;
        height: 2.5rem;
        font-size: 1.3rem;
        line-height: 2.5rem;  
        white-space: nowrap;
        padding-right: 100%;
        box-sizing: content-box;
        animation-iteration-count: infinite;
        animation-timing-function: linear;
        animation-name: ticker;
        animation-duration: 240s;
        &__item {
          display: inline-block;
          color: white;
          font-weight: bold;
        }
      }
      .ticker__item:before {
        content: "  »»";
        color: #ffff00;
        font-size: 1.5rem;
        font-weight: bold;
        margin-right: 10px;
        }
      .ticker__item:after {
      } 
  </style>
1 Like

n refers to the default button name and i to the icon. That way you don’t have to define custom_fields for these two should you choose to utilize them. Same goes for ‘l’ as in label.

Sorry about the choppiness. Its the converter I used for mp4 to gif.

news-ticker

2 Likes

wow that is a huge config… might benefit from some templating optimizations, but other than that, I would really recommend creating a separate ‘show off’ post for that in the category Share your Projects.

it will be lost here very soon, and given it’s unique properties really needs its own topic :wink:

you could elaborate on the actual ticker animation, and give us some details on how you managed to set the speed and duration of the animation, in relation to the content (length of the string) which is by definition dynamic considering the many sources and news they bring?

Ive found that to be the most challenging aspect moving from the html marquee tag (which simply scrolls the string that it is offered) to the js translateX code (which requires all sorts of complex calculations depending on screen size/available button estate and string length )

Especially when showing on Desktop and Mobile. Which makes me wonder how your ticker tape actually shows on mobile… :wink:

thanks for sharing

2 Likes

Hey, I know it’s a large config section. I tried to move it over to sensors.yaml but I couldn’t get it to work without errors with a couple other sensors I have for something else.

Truth be told, I found this code online in one of the threads on here if I remember correctly. Regarding the speed and duration, in their code, I played around with the following two lines and it some how (don’t understand how) it allows me to control those attributes:

  transform: translate3d(-100%, 0, 0);  # I change the -100% up or down depending on what I need to speed it up or down)
and
  animation-duration: 240s;  # I use this for the duration after watching the ticker and seeing if it restarted prematurely or way too late

Here’s what it looks like on mobile (Ignore the colour, I used a gif converter and compressor to get it under 3mb haha and I haven’t done anything regarding mobile, so ignore the placement of everything):

out1

yeah, thats what I did at first, but it was never right… so I ended up calculating the total string length, and setting those variables based in the length.

ofc, the difficulty also lies in the fact that the available space is different with different media screen sizes and orientations…
but I managed :wink:

Hi,

Weird question that I have searched and searched for the answer for.
Let’s assume I have a variable use_state.

variables:
    use_state: false
    icon_color: blue

I want to conditionally set the property color in styles (or card_mod equivalent). (pseudo code)

styles:
    icon:
      if use_state == false
      - color: {{ icon_color }}
     endif

The point is, I need the whole -color prop to be conditional, because button card by default will apply the active or inactive color. if it fails the use_state conditional, I don’t touch the -color prop. if I make the conditional to be the color prop:

- color: if use_state etc...

then it zaps the color prop completely and I lose all the normal button-card color styling.

I’ve tried {% if … %} and [[[ if… ]]] - all to no avail.

FWIW - this is in a popup script. and so I can also pass in variables to the script.

Any ideas? I hope I explained this sufficiently!

Hello, I tried following the example in the 1st post but I assume some things are a bit outdated.

Can someone help me figure out what the problem is with the following?

I use a template (part of the example):

blind-option:
  template: option-button
  tap_action:
    action: perform-action
    perform_action: cover.set_cover_position
    target:
      entity: '[[[ return variables.entity ]]]'
    data:
      position: '[[[ return variables.set_value ]]]'
  state:
    - operator: default
      styles:
        card:
          - background-color: '[[[ return variables.option_button_off_color ]]]'
          - color: '[[[ return variables.option_text_off_color ]]]'
    - operator: template
      value: >-
        [[[ return (entity.attributes.brightness||0) >= variables.range_start
        && (entity.attributes.brightness||0) <= variables.range_stop ]]]
      styles:
        card:
          - background-color: '[[[ return variables.option_button_on_color ]]]'
          - color: '[[[ return variables.option_text_on_color ]]]'   

in my dashboard.yaml file I use the following code:

  - type: 'custom:button-card'
    entity: cover.scherm
    template: presets
    name: Blinds
    variables:
      entity: cover.scherm
      option_template: blind-option
      option1_name: ANG
      option1_set_value: 12
      option1_range_start: 2
      option1_range_stop: 35
      option2_name: OPN
      option2_set_value: 50
      option2_range_start: 36
      option2_range_stop: 99
      option3_name: CLN
      option3_set_value: 100
      option3_range_start: 100
      option3_range_stop: 100
      option4_name: CLS
      option4_set_value: 0
      option4_range_start: 9999
      option4_range_stop: 9999      

When I press one of the 4 buttons I get the following error:

Failed to perform the action cover/set_cover_position. must contain at least one of entity_id, device_id, area_id, floor_id, label_id.

any suggestions?

Kind regards,
Remco

for those who need it. Here is my full custom template file for this button section:

---
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        

option-button:
  template: standard
  show_icon: false
  aspect_ratio: 1/1
  styles:
    card:
      - border-radius: 20%
      
blind-option:
  template: option-button
  tap_action:
    action: perform-action
    perform_action: cover.set_cover_position
    target:
      entity: '[[[ return variables.entity ]]]'
    data:
      position: '[[[ return variables.set_value ]]]'
  state:
    - operator: default
      styles:
        card:
          - background-color: '[[[ return variables.option_button_off_color ]]]'
          - color: '[[[ return variables.option_text_off_color ]]]'
    - operator: template
      value: >-
        [[[ return (entity.attributes.brightness||0) >= variables.range_start
        && (entity.attributes.brightness||0) <= variables.range_stop ]]]
      styles:
        card:
          - background-color: '[[[ return variables.option_button_on_color ]]]'
          - color: '[[[ return variables.option_text_on_color ]]]'        

presets:
  template: standard
  color_type: icon
  tap_action:
    action: none
  styles:
    card:
      - background-color: 'rgba(0,0,0,0.3)'
    icon:
      - color: white
    grid:
      - grid-template-areas: '"i opt1 opt2 opt3 opt4" "n opt1 opt2 opt3 opt4"'
      - grid-template-columns: 1fr 1fr 1fr 1fr 1fr
    custom_fields:
      opt1:
        - margin: 0.1em
        - overflow: visible
      opt2:
        - margin: 0.1em
        - overflow: visible
      opt3:
        - margin: 0.1em
        - overflow: visible
      opt4:
        - margin: 0.1em
        - overflow: visible
    variables:
      option_template: dimmer-option
      option_button_on_color: var(--paper-item-icon-active-color)
      option_text_on_color: white
      option_button_off_color: var(--paper-card-background-color)
      option_text_off_color: white
      option1_name: Low
      option1_set_value: 51
      option1_range_start: 1
      option1_range_stop: 77
      option2_name: Med
      option2_set_value: 102
      option2_range_start: 78
      option2_range_stop: 170
      option3_name: High
      option3_set_value: 255
      option3_range_start: 171
      option3_range_stop: 255
      option4_name: 'Off'
      option4_set_value: 0
      option4_range_start: 0
      option4_range_stop: 0        
  custom_fields:
    opt1:
      card:
        type: 'custom:button-card'
        entity: '[[[ return variables.entity ]]]'
        template: '[[[ return variables.option_template ]]]'
        name: '[[[ return variables.option1_name ]]]'
        variables:
          set_value: '[[[ return variables.option1_set_value ]]]'
          range_start: '[[[ return variables.option1_range_start ]]]'
          range_stop: '[[[ return variables.option1_range_stop ]]]'
          option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
          option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
          option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
          option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
    opt2:
      card:
        type: 'custom:button-card'
        entity: '[[[ return variables.entity ]]]'
        template: '[[[ return variables.option_template ]]]'
        name: '[[[ return variables.option2_name ]]]'
        variables:
          set_value: '[[[ return variables.option2_set_value ]]]'
          range_start: '[[[ return variables.option2_range_start ]]]'
          range_stop: '[[[ return variables.option2_range_stop ]]]'
          option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
          option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
          option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
          option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
    opt3:
      card:
        type: 'custom:button-card'
        entity: '[[[ return variables.entity ]]]'
        template: '[[[ return variables.option_template ]]]'
        name: '[[[ return variables.option3_name ]]]'
        variables:
          set_value: '[[[ return variables.option3_set_value ]]]'
          range_start: '[[[ return variables.option3_range_start ]]]'
          range_stop: '[[[ return variables.option3_range_stop ]]]'
          option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
          option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
          option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
          option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
    opt4:
      card:
        type: 'custom:button-card'
        entity: '[[[ return variables.entity ]]]'
        template: '[[[ return variables.option_template ]]]'
        name: '[[[ return variables.option4_name ]]]'
        variables:
          set_value: '[[[ return variables.option4_set_value ]]]'
          range_start: '[[[ return variables.option4_range_start ]]]'
          range_stop: '[[[ return variables.option4_range_stop ]]]'
          option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
          option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
          option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
          option_text_off_color: '[[[ return variables.option_text_off_color ]]]'      

I am trying to create a card that adjusts to the currently logged-in user in HA, and my intention is to capture their image from the user profile. I adjusted the code already shared here by user @sebbaT Fun with custom:button-card - #861 by sebbaT because the entity names have accents and contain two personal names per user, in my case for example, “João Silva.”

type: custom:button-card
entity: |-
  [[[
    return "person." + user.name.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/ /g, "_");
  ]]]
show_entity_picture: true

The question I want to ask is whether there is a cleaner alternative to achieve this by capturing data from the currently logged-in user entity.

Can anyone help… I have this custom field pulling in Temp & Humidity and i just want an icon beside both. No need to change color or anything.

custom_fields:
  temp: |
    [[[ return states['sensor.main_floor_thermometer_temperature_2'].state +
    '°C' ]]]    
  hum: |
    [[[ return states['sensor.main_floor_thermometer_humidity_2'].state + '%'
    ]]]

there is a nice example how to do that in the cards documentation, did you check that?

I looked at it… must have been late. i see it now. Thank you…

custom_fields:
  temp: >
    [[[ 
      return `<ha-icon
        icon="mdi:thermometer"
        Style="width 22px; height: 22px; color: yellow;">
        </ha-icon><span>${states['sensor.main_floor_thermometer_temperature_2'].state}°C`]]]
1 Like

nice yu9 it it working, though Style should really be style…

also the state can use the built-in helpers function lokalize, so you int need to add the unit anymore

look it up, its a real powerful option of button-card

helpers.localize(entity)

if you use the entity, or, eg

return helpers.localize(states[afstand],undefined,0);

if you want to set the rounding.

not you dont need to add .state anymore when using the helpers, it just requires the ‘state’ entity_id

so in your case

${states['sensor.main_floor_thermometer_temperature_2'].state}°C

would become

${helpers.localize(states['sensor.main_floor_thermometer_temperature_2'])

I’ve gotten rid of all units on all cards like that, just let the system take care of that.

the Processor button with all the custom_fields uses:

custom_fields:
  temp: >
    [[[ return `<ha-icon icon=mdi:thermometer
                <span style='width:15px; color: var(--state-color);'> </ha-icon>
                ${helpers.localize(entity)}</span>`; ]]]
  cpu: >
    [[[ return `<ha-icon icon=mdi:server style='width:12px;'> </ha-icon>
                Cpu: <span style='color: var(--cpu-color);'>
                ${helpers.localize(states['sensor.processor_use'])}</span>`; ]]]
  ram: >
    [[[ return `<ha-icon icon=mdi:memory style='width:12px;'></ha-icon>
                Ram: <span style='color:var(--ram-color);'>
                ${helpers.localize(states['sensor.memory_use_percent'])}</span>`; ]]]
  disk: >
    [[[ return `<ha-icon icon=mdi:harddisk style='width:12px;'></ha-icon>
                Disk: <span style='color:var(--disk-color);'>
                ${helpers.localize(states['sensor.disk_use_percent_home'])}</span>`; ]]]

in my setup :wink:

Just find out what’s the original value of the property (with code inspector), and then assign that value if your condition isn’t met. You can also try values like ‘unset’, ‘initial’, ‘inherit’.

- color: "[[[ return variables.use_state ? variables.icon_color : 'unset'; ]]]"

Can anyone guide me on setting colors for light & dark mode? I’m missing a step or 2

Example of the problem

One set of lights:

type: custom:vertical-stack-in-card
cards:
  - type: custom:stack-in-card
    mode: horizontal
    cards:
      - type: markdown
        content: |
          ### Master Bedroom
        card_mod:
          style: |
            ha-card {
              height: 100%;
              width: 250%
            }
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        entity: switch.security_booth_lights_l1
        icon: mdi:lightbulb-group
        show_name: false
        show_icon: true
        color_type: card
        aspect_ratio: 1/1
        styles:
          grid:
            - grid-template-areas: "\"i\" \"n\" \"s\""
            - grid-template-columns: 1fr
            - grid-template-rows: 1fr min-content min-content
          img_cell:
            - align-self: center
            - text-align: start
          name:
            - justify-self: center
            - font-weight: normal
          state:
            - justify-self: start
        state:
          - value: "off"
            styles:
              card:
                - color: SlateGrey
                - background-color: var(--switch-button-off-color) !important;
          - value: "on"
            styles:
              card:
                - color: White
                - background-color: var(--switch-button-on-color) !important;
      - type: custom:button-card
        color_type: blank-card
      - type: custom:button-card
        color_type: blank-card
      - type: custom:button-card
        entity: switch.security_booth_lights_l2
        icon: mdi:television-classic
        show_name: false
        show_icon: true
        color: auto
        color_type: card
        aspect_ratio: 1/1
        styles:
          grid:
            - grid-template-areas: "\"i\" \"n\" \"s\""
            - grid-template-columns: 1fr
            - grid-template-rows: 1fr min-content min-content
          img_cell:
            - align-self: center
            - text-align: start
          name:
            - justify-self: center
            - font-weight: normal
          state:
            - justify-self: start
        state:
          - value: "off"
            styles:
              card:
                - color: SlateGrey
                - background-color: var(--switch-button-off-color) !important;
          - value: "on"
            styles:
              card:
                - color: White
                - background-color: var(--switch-button-on-color) !important;
      - type: custom:button-card
        entity: switch.security_booth_lights_l3
        icon: mdi:air-conditioner
        show_name: false
        show_icon: true
        color: auto
        color_type: card
        aspect_ratio: 1/1
        styles:
          grid:
            - grid-template-areas: "\"i\" \"n\" \"s\""
            - grid-template-columns: 1fr
            - grid-template-rows: 1fr min-content min-content
          img_cell:
            - align-self: center
            - text-align: start
          name:
            - justify-self: center
            - font-weight: normal
          state:
            - justify-self: start
        state:
          - value: "off"
            styles:
              card:
                - color: SlateGrey
                - background-color: var(--switch-button-off-color) !important;
          - value: "on"
            styles:
              card:
                - color: White
                - background-color: var(--switch-button-on-color) !important;
view_layout:
  position: sidebar
card_mod:
  style: |
    ha-card {
     background: transparent !important;
     margin-top: 0px;
     #margin-left: 15px;
     #max-width: 450px;
    }

EDIT:
Found a solution here

UPDATE:
It works but isn’t consistent for button card. Modifying the Metro theme but the background-color reference I created for off is (finally) behaving itself, on isn’t registering consistently at all. Using element inspector sometimes the color doesn’t change to the reference selected for on without reloading the page. If I color the card directly in yaml, the on color stays loaded in off mode for light or dark.

Relevant part of theme yaml

light:
  lovelace-background: var(--background-image)
  background-image: "center / cover no-repeat fixed url('/local/Metro_day.svg')"
  switch-button-off-color: "rgba(255,255,255,.55)"
  switch-button-on-color: "rgba(255,193,7,.75)"
dark:
  lovelace-background: var(--background-image)
  background-image: "center / cover no-repeat fixed url('/local/Metro_night.svg')"
  switch-button-off-color: "rgba(0,0,0,.55)"
  switch-button-on-color: "rgba(255,193,7,.75)"