Lovelace: Button card

hey all,

super new to this but i want to do something simple, hopw to i format the date to a short date so it looks identical to the “start time” card? (i want to keep the time as is in am/pm)

my button-card styling is getting rusty…

Dec-04-2024 13-41-39

had this working with the html marquee tag before,

name: >
  [[[ return `<div style='display: flex;
                          padding: 0px 5px 0px 5px;
                         align-items: center;
                         background: transparent;'>
      <div></div>
      <marquee>
      <span style='color: var(--primary-color);align-items: center;'>${variables.cond}</span>
      </marquee>`; ]]]

Dec-04-2024 14-01-40

can even cut it short to

name: >
  [[[ return `<marquee> ${variables.cond} </marquee>`; ]]]
size: 100%
aspect_ratio: 1
styles:
  name:
    - display: flex;
    - padding: 0px 5px
    - font-size: 13px
    - font-weight: bold
    - color: var(--primary-color)
    - overflow: visible

and it still marquees nicely

but now want to replace that with the modern css translateX animation…

cant get the name to remain inside the padding of the card, not even if I set it explicitly with

    - display: flex;
    - padding: 0px 5px 0px 5px

the translateX ignores that and makes it overflow…

type: custom:button-card
template:
  - styles_cf_notification
  - styles_cf_notification_left
show_entity_picture: true
variables:
  cond: >
    [[[ return states['sensor.buienradar_woensdrecht'].attributes.weatherdescription; ]]]
show_name: true
name: >
  [[[ return variables.cond; ]]]
size: 100%
aspect_ratio: 1

extra_styles: |
  @keyframes marquee {
    from {transform: translateX(20%);}
    to {transform: translateX(-50%);}
  }
styles:
  name:
    - font-size: 13px
    - font-weight: bold
    - color: var(--primary-color)
    - overflow: visible
    - animation: >
        [[[ return variables.cond.length > 20? 'marquee 3s linear infinite' : 'none' ; ]]]

could anyone help me out seeing what’s wrong?

How to limit the translateX to remain inside the cards padding.

it’s not the overflow property, I need to set that as visible, or it will be truncated with the ..... if longer than the available space

Here’s my recipe. This is a gif capture; the actual result is much smoother.
Kept the states/variables/styles/extras, you can trim down as needed.
You can play with speed depending on your string lenght.
Took me while to figure out how to get that continuous loop without breaks.
doubling the string + 50% transition does the trick.
Hope this helps, cheers.

Animation

type: custom:button-card
name: |-
  [[[return `<div class="wrapper">
    <div class="marquee">
      <p>
        🚨TEMPERATURE:
        ${states['sensor.ss_temperature'].state}°C /
        ENERGY:
        ${ parseFloat(states['sensor.energymon3_home_power_total_kw'].state).toFixed(2) } kWh
      </p>
      <p>
        🚨TEMPERATURE:
        ${states['sensor.ss_temperature'].state}°C /
        ENERGY:
        ${ parseFloat(states['sensor.energymon3_home_power_total_kw'].state).toFixed(2) } kWh
      </p>
      </div>
      </div>`]]]
extra_styles: |
  .wrapper {
    max-width: 100%;
    overflow: hidden;
  }

  .marquee {
    white-space: nowrap;
    overflow: hidden;
    display: inline-block;
    animation: marquee 3s linear infinite;
  }

  .marquee p {
    display: inline-block;
  }

  @keyframes marquee {
    0% {
      transform: translatex(0);
    }
    100% {
      transform: translatex(-50%);
    }
  }
  @keyframes glow {
    50% {box-shadow: 0 0 20px 10px red;}
  }           
styles:
  card:
    - height: 3rem
    - padding: 5rem
    - background: black
    - animation: glow 1s linear infinite
  name:
    - font-size: 3rem
    - font-weight: bold
    - white-space: normal
    - background: black
    - color: red
4 Likes

thanks, experimenting a bit, and struggling to get the positioning on the button correctly. and need to force it using

styles:  name:
    - position: absolute
    - top: 73%
    - left: 5%
    - right: 5%

otherwise the scroll box simply isnt wide enough

… but its scrolling alright :wink:
I want to conditionally scroll and had

    - animation: >
        [[[ return variables.cond.length > 20? 'marquee 3s linear infinite' : 'none' ; ]]]

before as a test length. I really it should only scroll if the length of the string is longer than the available width, but for now I believe I can count the pixels :wink:
Andy thoughts how we can achieve conditional scrolling using the marquee class?

what exactly do you mean with:

I dont see you calculating the string length anywhere? or apply this in the styles?

fwiw, I now use this (left out all non relevant stuff):

type: custom:button-card
variables:
  cond: >
    [[[ return states['sensor.buienradar_woensdrecht'].attributes.weatherdescription; ]]]
show_name: true
name: >
  [[[return `<div class="wrapper">
               <div class="marquee"> <p> ${variables.cond}</p> </div>
             </div>`; ]]]
size: 100%
aspect_ratio: 1

extra_styles: |
  @keyframes marquee {
    from {transform: translateX(100%);}
    to {transform: translateX(-100%);}
  }

  .marquee {
    animation: marquee 3s linear infinite;
  }

styles:
  name:
    - position: absolute
    - top: 73%
    - left: 5%
    - right: 5%

to get this
Dec-06-2024 10-16-22

as you can see I forced the box for the wrapper, without the positioning it is

Dec-06-2024 10-17-46

What I wanted Is a continuous loop with no break. In your example above, the whole text has to be out of the frame before it starts again.
In my example, you will notice the text (“name” section) is duplicated once. So if you transition half of it left (-50%) and restart, you will get a continuous loop/no break.

right, I see what you mean now, thx.

I’ve moved some of that styling to the div and made it conditional (on a manual count of the max button width of 20…)

name: >
  [[[return variables.cond_length > 20
      ? `<div class="wrapper"
               style='margin: 0px 10px -15px 10px;'>
               <div class="marquee"> <p>${variables.cond}</p> </div>
             </div>`
       : variables.cond; ]]]

or, can also move it to the extra_styles for that element:

extra_styles: |
  @keyframes marquee {
    from {transform: translateX(100%);}
    to {transform: translateX(-150%);}
  }
  .marquee {
    animation: marquee 3s linear infinite;
    margin: -5px 10px -15px 10px;
  }

that styling moves the scrolling name to the desired spot more or less. Still feels hacky.

Here’s a trimmed down version for reference; just need to ensure the text is repeated twice.

type: custom:button-card
name: |-
  [[[return `
    <div class="marquee">
        🚨ANY TEXT YOU WANT HERE🚨ANY TEXT YOU WANT HERE
      </div>
      </div>`]]]
extra_styles: |

  .marquee {
    white-space: nowrap;
    display: inline-block;
    animation: marquee 3s linear infinite;
  }

  @keyframes marquee {
    0% {
      transform: translatex(0);
    }
    100% {
      transform: translatex(-50%);
    }
   
styles:
  card:
    - height: 5rem
    - padding: 2rem
    - background: black
  name:
    - font-size: 3rem
    - background: black
    - color: red

And you can use layout card to manage elements/locations/paddings/margins/etc:

Animation2

Using layout-card in a custom:button-card ? that is new to me, and seems a bit clumsy, when button-card has all the options to place the elements wherever we need them?

the trick I use from that class combination, is that the translateX is defined to the marquee class, which itself is inside the .wrapper.

without that .wrapper the traslateX overflows the name element itself, and with that, the paddings of the card itself.

keeping the marquee inside that wrapper, allows us to place it correctly.
that is why I decided to set the exact positioning on that element.

making the marquee properties truly dependent on the length and size of the screen (available space in the elements on Mobile and Desktop to name but 1 variable) would require a lot more work, and for this button that is overdoing it.

it is possible, and I have a few that do use that, see this How to make scroll-time/speed and TranslateX string length dependent in css animation - #14 by Mariusthvdb for some background…

For complex layouts, I tend to use layout-card instead of button-card as precisely positioning elements inside a button card can get tricky if you use multiple devices/screen sizes (ref: your link above). This is what I was referring to above, just a personal preference.

Core Update 2024.12.1 erro in flex Card

Custom element doesn’t exist: flex-horseshoe-card.
type: custom:flex-horseshoe-card
image

wrong thread, should be here