As do I, but haven’t observed any breaking changes.
Per @Mariusthvdb/@parautenbach, are you sure the states exist?
As do I, but haven’t observed any breaking changes.
Per @Mariusthvdb/@parautenbach, are you sure the states exist?
The fault is probably in this part, for debug try not to use the decluttering template, but use a clean template for button-card.
Here it is confusing that for decluttering template is used for variable [[ ]]
, and button card everything that is in [[[ ]]]
is javascript, for some variables it can happen that it doesn’t return the correct value and therefore error occurs
This is quite normal with a button card within a decluttering card.
@tismondo The double quotes seems odd though. I would have:
(states['[[sensor1-2]]'].state == '[[state1-2]]')
^ ^ single quote here
here
please do as we’ve asked you twice now, test without the decluttering card
you need to eliminate the root cause, and can do by verifying the direct config works. I thats ok, then build the decluttering bit by bit
also, make life easy on yourself, and use better variable names, because the ones you use now are prone to mixup and confusion
For a test I tried a similar decluttering template with button card, it works with double quotes. Probably in his case the sensor will be unavailable.
my templates looks like this
decluttering template
test_template:
card:
type: custom:button-card
entity: '[[sensor1-2]]'
show_name: false
show_state: false
show_label: true
show_icon: false
label: >
[[[
if (states['[[sensor1-2]]'].state == "[[state1-2]]") {
return `<ha-icon icon="mdi:[[icon1-2]]"></ha-icon> Turn Off`;
} else {
return `<ha-icon icon="mdi:[[icon1-1]]"></ha-icon> Turn On`;
}
]]]
button-card
cards:
- type: custom:decluttering-card
template: test_template
variables:
- sensor1-2: light.ceiling_lights
- state1-2: 'on'
- icon1-2: lightbulb-on
- icon1-1: lightbulb-off
compound post I previously posted in card-mod.… since I have found no card-mod solution but do all in button-card now, Ill repost the set below:
this could be posted in a tile card or custom:button-card thread too, but since I am trying to find the right card-mod, I’ll start here…
I have this tile card mod
type: tile
icon: mdi:water
name: ' '
vertical: true
tap_action:
action: more-info
card_mod:
style: |
.icon-container {
border-radius: 24px;
background: radial-gradient(var(--card-background-color) 60%,transparent calc(60% + 1px)),
conic-gradient(var(--tile-color) {{states(config.entity)}}% 0%,
var(--card-background-color) 0% 100%);
}
which draws a perfect border according to the percentage of the entity:
I’d love to do the same with my light buttons, but cant find the right mod to do so:
I have some of these on a custom field:
custom_fields:
info: &info_light
>
[[[ if (entity.state === 'on' && entity.attributes.brightness) {
var brightness = Math.round(entity.attributes.brightness/2.54);
const radius = 20.5;
const circumference = radius * 2 * Math.PI;
return `
<svg viewBox="0 0 50 50">
<circle cx="25" cy="25" r="${radius}"
stroke="var(--button-card-light-color,var(--active-color))" stroke-width="2" fill="none"
style="transform: rotate(-90deg);transform-origin: 50% 50%;
stroke-dasharray: ${circumference};
stroke-dashoffset: ${circumference - brightness / 100 * circumference};" />
<text x="50%" y="54%" fill="black" font-size="16" font-weight= "bold"
text-anchor="middle" alignment-baseline="middle">
${brightness}<tspan font-size="10">%</tspan>
</text>
</svg>
`;
}
]]]
and that works fine:
. but in this case I want the border to be drawn on the img_cell of the button-card, or, checking the element in the dom, the .img-cell
so I copied that tile card mod over to
card_mod:
style: |
.img-cell {
border-radius: 24px;
background: radial-gradient(var(--card-background-color) 60%,transparent calc(60% + 1px)),
conic-gradient(var(--button-card-light-color) {{states(config.entity)}}% 0%,
var(--card-background-color) 0% 100%);
}
note I did change to the button-card-light-color, but nothing is happening…
this is the original button with a regular style section on the image_cell:
img_cell:
- justify-content: center
- background: >
[[[ var rgb = (entity.state === 'on')
? entity.attributes.rgb_color : '211,211,211';
return 'rgba(' + rgb + ',0.2)'; ]]]
- border-radius: 24px
- place-self: start
- width: 42px
- height: 42px
but when I take that out, and change to the card-mod there is nothing:
tbh, I wouldn’t yet know how to write the background in styles syntax native to the custom:button-card, thats why I tried it with card-mod
please have a look what could be done to fix this?
Follow up
- background: >
[[[ var rgb = (entity.state === 'on')
? entity.attributes.rgb_color : '211,211,211';
var rgba = 'rgba(' + rgb + ',0.2)';
if (entity.state === 'on')
return `radial-gradient(${rgba} 80%,transparent calc(60% + 1px)),
conic-gradient(var(--button-card-light-color) ${Math.round(entity.attributes.brightness/2.55)}% 0%,
var(--card-background-color) 0% 100%)`;
return `${rgba}`; ]]]
and
triggers_update:
- entity
does a lot of good, thanks to @khaisilk1910 for helping me in Discord!
the final thing I need now is get rid of the actual conic, and have the background inside the img_cell only show that conic in the outer border…
just like in the print cartridge buttons…
I cant see it though
alternative since there is no apparent way to do as I hoped:
img_cell:
- justify-content: center
- background: >
[[[ var rgb = entity.state === 'on'
? entity.attributes.rgb_color : '211,211,211';
var rgba = 'rgba(' + rgb + ',0.2)';
return entity.state === 'on'
? `radial-gradient(var(--card-background-color) 60%,transparent calc(60% + 1px)),
conic-gradient(var(--button-card-light-color) ${Math.round(entity.attributes.brightness/2.55)}% 0%,
${rgba} 0% 100%)`
: `${rgba}`; ]]]
___ And finally at least 1 solution___
it has to do with the left over section of the overlay (but no, it didnt make any difference in solar I could find out)
I’ve found another solution now though:
I am using the same info custom field, and I overlay it exactly over the icon img_cell of the button-card. It feels a bit hacky, and ofc its not 100% linked to the img_cell itself (not all as a matter of fact, it’s just a custom field after all) but is is the best I could come up with for now.
custom_fields:
info: >
[[[ if (entity.state === 'on' && entity.attributes.brightness) {
var brightness = Math.round(entity.attributes.brightness/2.54);
var rgb = (entity.state === 'on')
? entity.attributes.rgb_color : '211,211,211';
var rgba = 'rgba(' + rgb + ',0.2)';
const radius = 20.5;
const circumference = radius * 2 * Math.PI;
return `
<svg viewBox="0 0 50 50">
<circle cx="25" cy="25" r="${radius}"
stroke="var(--button-card-light-color,var(--active-color))" stroke-width="2" fill="${rgba}"
style="transform: rotate(-90deg);transform-origin: 50% 50%;
stroke-dasharray: ${circumference};
stroke-dashoffset: ${circumference - brightness / 100 * circumference};" />
</svg>
`;
}
]]]
styles:
custom_fields:
info:
- position: absolute
- left: 2%
- top: 4%
- width: 48px
OMT:
I can omit the
triggers_update:
- entity
after all. It was unexpected I needed it before, but now the templates are working, the card successfully triggers automatically
Love it! Great CSS work…
Brilliant - thanks for sharing!
small update, because there were some anomalies in the on state without rgb_color attribute (showing the 211,211,211 color…) and I added some unavailable/unknown colors.
custom_fields:
info: >
[[[ if (entity.state === 'on' && entity.attributes.brightness) {
var brightness = Math.round(entity.attributes.brightness/2.54);
var rgb = (entity.attributes.rgb_color)
? entity.attributes.rgb_color : '254,181,13' ;
}
if (entity.state === 'off') {
var rgb = '211,211,211';
}
if (entity.state in ['unknown','unavailable']) {
var rgb = '189,189,189';
}
var rgba = 'rgba(' + rgb + ',0.2)';
const radius = 20.5;
const circumference = radius * 2 * Math.PI;
return `
<svg viewBox="0 0 50 50">
<circle cx="25" cy="25" r="${radius}"
stroke="var(--button-card-light-color,var(--active-color))"
stroke-width="3"
fill="${rgba}"
style="transform: rotate(-90deg);transform-origin: 50% 50%;
stroke-dasharray: ${circumference};
stroke-dashoffset: ${circumference - brightness / 100 * circumference};" />
</svg>
`;
]]]
styles:
custom_fields:
info:
- position: absolute
- left: 1%
- top: 4%
- width: 50px
also notice the styling/position change… it had to be 50 because of the viewbox using 50px too…
next to that, you’ve got to be aware the button-card’s background still exists. So, when using a darker theme the color of the circle gets frustrated by that darker background color.
Ive tried background transparent, but obviously that doesnt help, as it makes the card background even more prominent
so for now I’ve settled to do something like:
img_cell:
- justify-content: center
- background: >
[[[ if (entity.state === 'on') return 'ivory';]]]
but, that isnt optimal either (as it leaves the unused brightness area in that color. o well, its not simple at all
light theme is perfect though:
Other options to play with:
set the color of the img_cell background to the exact same color as the fill of the custom-field, not really any help
set
fill-opacity:1
fill-rule="nonzero"
to the svg view box, and play with that. doesn’t really help either.
Hey all, I’m trying to get colors represented on my button card when entity state changes and it seems to be ignoring the entire section where that is defined.
type: custom:button-card
name: Mark
show_name: false
show_state: false
show_icon: true
show_entity_picture: true
entity: person.mark_ramos
tap_action:
action: perform-action
perform_action: icloud3.find_iphone_alert
data:
device_name: abcdef0123456
entity_id: device_tracker.mark_iphone
styles:
card:
- background-color: var(--contrast2)
- padding: 10px 10px 10px 0px
grid:
- grid-template-areas: "\"icon name btn\" \"icon state btn\""
- grid-template-columns: 60px 1fr min-content
- grid-template-rows: min-content
img_cell:
- justify-content: start
- position: absolute
- width: 40px
- height: 40px
- left: 0
- bottom: 0
- margin: 0 0 8px 10px
- border-radius: 50%
- border: |
[[[
if (entity.state == 'home') {
return '1px solid var(--green)';
} else {
return 'none';
}
]]]
entity_picture:
- justify-content: start
- position: absolute
- width: 40px
- height: 40px
- left: 0
- bottom: 0
- margin: 0 0 0 0
- border-radius: 500px
icon:
- width: 50px
- color: var(--contrast1)
custom_fields:
name:
- align-self: start
- justify-self: start
- background: none
- padding: 0
state:
- align-self: start
- justify-self: start
- background: none
- padding: 0
- margin-top: "-5px"
btn:
- align-self: end
- justify-self: end
icon:
- align-self: start
- justify-self: start
badge:
- position: absolute
- left: 38px
- top: 7px
custom_fields:
name:
card:
type: custom:button-card
name: Mark
styles:
card:
- color: var(--contrast20)
- font-size: 14px
- font-weight: 600
- background: none
state:
card:
type: custom:button-card
entity: "[[[ return entity.entity_id ]]]"
show_icon: false
name: |
[[[
return states['person.mark_ramos'].state;
]]]
state:
- value: home
name: Home
- value: not_home
name: Away
styles:
card:
- color: var(--contrast20)
- font-size: 12px
- background: none
- opacity: "0.7"
badge:
card:
type: custom:button-card
entity: "[[[ return entity.entity_id ]]]"
show_icon: true
show_name: false
icon: mdi:home
state:
- value: home
icon: mdi:home
styles:
card:
- background: var(--green)
- value: not_home
icon: mdi:home-export-outline
styles:
card:
- background: var(--red)
styles:
card:
- border-radius: 50%
- width: 16px
- height: 16px
- background: none
icon:
- color: black
- width: 12px
btn:
card:
type: custom:mushroom-chips-card
chips:
- type: entity
tap_action:
action: more-info
entity: sensor.mark_iphone_battery_3
content_info: none
card_mod:
style: |
ha-card {
--chip-background: {{ 'var(--contrast4)' if states('sensor.mark_iphone_battery_3') | float > 10 else 'var(--red)' }};
--color: {{ 'var(--contrast20)' if states('sensor.mark_iphone_battery_3') | float > 10 else 'var(--black)' }};
padding: 0px!important;
border-radius: 100px!impportant;
--primary-text-color: var(--contrast20);
Didn’t you try to set a specific color for debug instead of css variables? Isn’t there a problem with them?
Thanks, that got me a bit further. I do think it’s related to an override somewhere in my dashboard, not within the card. I’m searching…
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…
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>`; ]]]
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.
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
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
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
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
as you can see I forced the box for the wrapper, without the positioning it is
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: