Button Card
custom:lcards-button
The Button card covers everything from simple labels and toggle buttons to complex interactive components like D-pads and multi-segment SVG controls. Elbows use the same base so every feature here is also available in the Elbow card.
Modes
The card operates in one of three modes, selected by which top-level key is present:
| Mode | Key | Use for |
|---|---|---|
| Preset | preset | Standard LCARS buttons — lozenge, bullet, capped, etc. |
| Component | component | Interactive multi-segment controls (D-pad, alert shape) |
| Custom SVG | svg | Your own SVG with interactive segments |
Top-Level Options
| Option | Type | Description |
|---|---|---|
type | string | custom:lcards-button (required) |
entity | string | Entity to monitor and control |
preset | string | Button shape preset — see Presets |
component | string | Component type: dpad or alert (component mode) |
svg | object | Custom SVG config — see Custom SVG Mode |
ranges_attribute | string | Entity attribute used for above:/below:/between: range conditions — see Range Conditions |
ranges | list | State-driven component preset switching — see Component Mode: Alert |
interactive | boolean | true by default. Set false to suppress hover colour changes and hover animations — useful for decorative buttons. Tap/hold actions still fire. |
control | object | Control behaviour — see Control |
show_icon | boolean | Show/hide the icon (default: true) |
icon | string | MDI icon (e.g. mdi:lightbulb) |
icon_area | string | Icon position: left, right, top, bottom, none (default: left) |
icon_area_size | number | Icon area width/height in px (default: 60) |
icon_area_background | string / object | Icon area background colour — state map supported (default: transparent) |
icon_style | object | Advanced icon styling — see icon_style Object |
divider | object | Divider between icon area and content area — see divider Object |
dpad | object | D-pad component config — see Component Mode: D-pad |
alert | object | Alert component config — see Component Mode: Alert |
style | object | Visual styles — see style Object |
shape_texture | object | SVG texture inside the button fill — see Shape Texture |
filters | list | CSS / SVG filters — see filters List |
id | string | Card ID for Rules Engine targeting |
tags | list | Tags for Rules Engine targeting |
height | number / string | Card height — see Sizing |
width | number / string | Card width — see Sizing |
min_height | number / string | Minimum card height — see Sizing |
min_width | number / string | Minimum card width — see Sizing |
text | object | Text label definitions — see Text Fields |
tap_action | object | Tap action — see Actions |
hold_action | object | Hold action — see Actions |
double_tap_action | object | Double-tap action — see Actions |
animations | list | Card animations — see Animations |
background_animation | list / object | Canvas background — see Background Animations |
data_sources | object | Named data source definitions — see Data Sources |
sounds | object | Per-card sound overrides — see Sound Effects |
triggers_update | list | Extra entity IDs that trigger re-render — see Data Sources |
grid_options | object | HA grid layout — see grid_options |
Control
| Field | Type | Description |
|---|---|---|
control.attribute | string | Entity attribute to control (leave blank to control entity state directly) |
control:
attribute: brightness # control light brightness directlystyle Object
style.card
| Field | Type | Description |
|---|---|---|
color.background | string / object | Card background — state map supported |
style.cursor
| Field | Type | Description |
|---|---|---|
cursor | string | CSS cursor shown on hover. Any valid CSS cursor value. Overrides the automatic cursor (which is pointer when interactive: true, default when interactive: false). Common values: pointer, default, none, not-allowed, crosshair, grab, zoom-in, help, wait, progress, move, copy, text. |
style.border
| Field | Type | Default | Description |
|---|---|---|---|
color | string / object | theme | Border colour — state map supported |
width | number / string / object | 0 | Border width in px, a theme token string, or { top, right, bottom, left } per-side |
radius | number / string / object | theme | Corner radius in px, a theme token string, or { top_left, top_right, bottom_right, bottom_left } per-corner |
style.text.default and style.text.<field>
Shorthand for setting text styles inside the style block (equivalent to top-level text.default.*):
| Field | Type | Description |
|---|---|---|
color | string / object | Text colour — state map supported |
font_size | number / string | Font size in px or CSS value |
font_weight | string / number | CSS font-weight |
font_family | string | CSS font-family |
See Text Fields for the full per-field options table.
style:
card:
color:
background:
default: "var(--ha-card-background)"
active: "alpha(var(--lcards-orange), 0.08)"
border:
color:
default: "var(--lcards-gray)"
active: "var(--lcards-orange)"
width: 2
radius: 12 # or per-corner: { top_left: 20, top_right: 4, bottom_left: 4, bottom_right: 20 }
text:
default:
color: "var(--lcards-moonlight)"
font_size: 13icon_style Object
Fine-grained control over the icon appearance and placement within its area.
| Field | Type | Default | Description |
|---|---|---|---|
type | string | mdi | Icon type: mdi, si (Simple Icons), or entity (entity state icon) |
icon | string / object | — | MDI icon name, or a state map of icon names — overrides the top-level icon field |
color | string / object | theme | Icon colour — state map supported |
size | number | 24 | Icon size in px |
position | string | center | Icon position within its area |
x | number | — | Absolute X offset in px (overrides position) |
y | number | — | Absolute Y offset in px (overrides position) |
x_percent | number | — | X as percentage of icon area width (0–100) |
y_percent | number | — | Y as percentage of icon area height (0–100) |
rotation | number | 0 | Icon rotation in degrees (-360 to 360) |
padding | number / object | — | Padding in px (number = all sides, or { top, right, bottom, left }) |
padding_left | number | — | Left padding in px — overrides padding |
padding_right | number | — | Right padding in px — overrides padding |
padding_top | number | — | Top padding in px — overrides padding |
padding_bottom | number | — | Bottom padding in px — overrides padding |
spacing | number | 8 | Space between icon and text area in px |
icon: mdi:thermometer
icon_area: left
icon_style:
color:
default: "var(--lcards-gray)"
active: "var(--lcards-orange)"
size: 32
padding: 8Per-State Icons
Set icon_style.icon to a state map to swap the icon based on entity state (including range conditions):
entity: light.tv
ranges_attribute: brightness_pct # range keys compare against brightness 0–100 %
icon: mdi:lightbulb # default / fallback icon
icon_style:
icon:
active: mdi:lightbulb
inactive: mdi:lightbulb-off
above:90: mdi:lightbulb-alert
below:20: mdi:lightbulb-outlineThe same resolution order as state-based colours applies (exact state → zero → ranges → non_zero → classified → default). See Range Conditions on Non-Numeric Entities for the ranges_attribute pattern.
divider Object
Thin line between the icon area and the content area.
| Field | Type | Default | Description |
|---|---|---|---|
color | string / object | theme | Divider colour — state map supported |
width | number | theme | Divider thickness in px |
divider:
color: "var(--lcards-orange)"
width: 2filters List
CSS and SVG filters applied to the card.
| Field | Type | Description |
|---|---|---|
mode | string | css (default) or svg |
type | string | CSS type (blur, brightness, contrast, saturate, drop-shadow) or SVG primitive |
value | string / number / object | Filter parameters |
filters:
- type: blur
value: 4
- type: brightness
value: 0.8
- type: saturate
value: 0.5Text Fields
Multiple text labels can be placed anywhere on the card. See Text Fields for the full reference.
text:
default:
font_family: "Antonio, sans-serif"
color: "var(--lcards-moonlight)"
name:
content: "Temperature"
position: top-left
font_size: 11
value:
content: "{entity.state}°C"
position: center
font_size: 28
font_weight: bold
color:
default: "var(--lcards-moonlight)"
unavailable: "var(--lcards-alert-red)"Presets
Standard Buttons
| Preset | Description |
|---|---|
lozenge | Fully rounded on both ends, icon area on left |
lozenge-right | Fully rounded on both ends, icon area on right |
bullet | Rounded right end, flat left — icon area on left |
bullet-right | Rounded left end, flat right — icon area on right |
capped | Rounded left end, flat right — icon area on left |
capped-right | Rounded right end, flat left — icon area on right |
barrel | Flat corners, no border, icon area on left |
barrel-right | Flat corners, no border, icon area on right |
filled | Transparent border, large text label on right |
filled-right | Transparent border, large text label on left |
outline | Transparent background, border only — Picard style |
outline-right | Transparent background, border only, icon area on right |
icon | Square icon-only button with large rounded corners |
text-only | No background or border — pure text label |
Bar Labels
Horizontal bars with an opaque text background that creates a "break" in the bar — classic LCARS header style.
| Preset | Description |
|---|---|
bar-label-base | Bar label foundation — filled button, auto-scaling text, centered |
bar-label-left | Bar label with left-aligned text |
bar-label-center | Bar label with centered text |
bar-label-right | Bar label with right-aligned text |
bar-label-square | Bar label with square corners |
bar-label-lozenge | Bar label with fully rounded ends |
bar-label-bullet-left | Bar label with flat left, rounded right |
bar-label-bullet-right | Bar label with rounded left, flat right |
bar-label-capped-left | Bar label with rounded left, flat right |
bar-label-capped-right | Bar label with flat left, rounded right |
Component Mode: D-pad
D-pad segments: center, up, down, left, right, up-left, up-right, down-left, down-right
The default key under segments applies shared config to all segments.
| Field | Type | Description |
|---|---|---|
entity | string | Entity for this segment (state-based colours, icons) |
tap_action | object | Action on tap — see Actions |
hold_action | object | Action on hold |
double_tap_action | object | Action on double-tap |
style.fill | string / object | Segment fill colour — state map supported |
style.stroke | string / object | Segment stroke colour — state map supported |
style.stroke-width | number / string / object | Stroke width in px, CSS string, or state-based map |
style.opacity | number / object | Segment opacity (0–1) or state-based map |
text | object | Per-segment text labels |
icon | string | MDI icon for this segment |
animations | list | Segment-specific animations |
type: custom:lcards-button
component: dpad
dpad:
segments:
default:
style:
fill:
default: "var(--lcards-gray)"
active: "var(--lcards-orange)"
center:
entity: media_player.tv
tap_action:
action: call-service
service: media_player.media_play_pause
target:
entity_id: media_player.tv
up:
tap_action:
action: call-service
service: media_player.volume_up
target:
entity_id: media_player.tv
down:
tap_action:
action: call-service
service: media_player.volume_down
target:
entity_id: media_player.tvComponent Mode: Alert
The alert component displays a Starfleet alert symbol with animated bar elements.
alert Object
| Field | Type | Description |
|---|---|---|
alert.color.shape | string | Fill colour override for the shield shape |
alert.color.bars | string | Stroke colour override for the bar lines |
alert.custom_presets | object | Custom or override presets merged over built-ins (keyed by preset name) |
alert.segments | object | Per-segment fine-grained style overrides (shape, bars) |
ranges List (state-driven preset switching)
| Field | Type | Description |
|---|---|---|
ranges[].preset | string | Component preset name to apply when this range matches (required) |
ranges[].attribute | string | Override ranges_attribute for this entry only |
ranges[].above | number | Match when value is ≥ this threshold |
ranges[].below | number | Match when value is < this threshold |
ranges[].equals | string / number / boolean | Match when value equals this |
ranges[].color.shape | string | Transient shape fill override while this range is active |
ranges[].color.bars | string | Transient bars stroke override while this range is active |
type: custom:lcards-button
component: alert
preset: default # default, red, yellow, blue, green, grey, black
# State-driven preset switching
entity: sensor.threat_level
ranges:
- preset: red
above: 80
- preset: yellow
above: 50
- preset: default
above: 0Custom SVG Mode
svg Object
| Field | Type | Description |
|---|---|---|
svg.content | string | Inline SVG markup |
svg.src | string | URL to an external SVG file |
svg.viewBox | string | Override the SVG viewBox attribute |
svg.preserveAspectRatio | string | SVG preserveAspectRatio value |
svg.enable_tokens | boolean | Resolve {theme:...} tokens inside the SVG markup |
svg.allow_scripts | boolean | Allow <script> elements inside the SVG (default: false) |
svg.segments | object | Interactive segment configs keyed by element id — use default for shared config |
type: custom:lcards-button
svg:
content: |
<svg viewBox="0 0 200 100">
<rect id="btn-a" x="10" y="10" width="80" height="80" fill="var(--lcards-orange)" rx="8"/>
<rect id="btn-b" x="110" y="10" width="80" height="80" fill="var(--lcards-blue)" rx="8"/>
</svg>
segments:
default:
style:
fill:
active: "var(--lcards-orange-medium)"
btn-a:
entity: light.zone_a
tap_action:
action: toggle
btn-b:
entity: light.zone_b
tap_action:
action: toggleSVG elements with id attributes become interactive segments.
Note: When using CSS custom properties in SVG
fillattributes, browser support can vary. UsingcurrentColorin the SVG with CSScolorstyling via JavaScript is a reliable cross-browser alternative. The example above works in modern browsers and the HA web app.
Shape Texture
shape_texture renders an SVG-native texture or animation inside the button shape fill — clipped to the shape boundary. Available in preset mode only. Elbow cards also support this feature.
shape_texture:
preset: fluid
opacity: 0.4 # 0–1, or state-based map
mix_blend_mode: screen
speed: 1.0 # 0 = static
config: {}Available Presets
| Preset | Description | Key Config |
|---|---|---|
grid | Scrolling orthogonal grid lines | line_spacing, pattern (both/horizontal/vertical) |
diagonal | Scrolling diagonal hatching | line_spacing |
hexagonal | Scrolling hexagonal grid | hex_radius |
dots | Scrolling dot grid | dot_radius, spacing |
fluid | Organic swirling fractalNoise | base_frequency, num_octaves |
plasma | Dual-colour turbulence wash | color_a, color_b, base_frequency |
shimmer | Directional light-sweep | angle, highlight_width, speed |
flow | Directional streaming currents | wave_scale, scroll_speed_x |
level | Fill bar with optional wave | fill_pct, direction, wave_height |
pulse | Breathing radial glow | radius, min_size, speed |
scanlines | CRT-style scan-line overlay | line_spacing, direction |
image | User-supplied image clipped to shape | url, size, position, repeat |
All color fields accept var(--lcards-*), {theme:...}, rgba(), hex, or a state-based map. |
For full parameter reference see Shape Texture System.
Background Animations
See Background Animations for full docs.
background_animation:
- preset: grid
config:
line_spacing: 40
color: "alpha(var(--lcards-orange), 0.3)"Decorative / Non-Interactive Buttons
By default every button shows a pointer cursor and changes colour on hover. For purely decorative panels that should not signal interactivity, set interactive: false.
| What changes | interactive: true (default) | interactive: false |
|---|---|---|
| Cursor on hover | pointer (hand) | default (arrow) |
| Background colour on hover | Changes to hover colour from preset/style | No change |
| Hover animations | Fire | Suppressed |
| Tap / hold actions | Fire normally | Fire normally |
type: custom:lcards-button
entity: light.corridor
preset: lozenge
interactive: false # decorative — no hand cursor or hover colour change
tap_action:
action: toggle # action still works if you want itTo keep hover effects but override only the cursor shape, use style.cursor independently:
type: custom:lcards-button
style:
cursor: crosshair # any valid CSS cursor stringAnnotated Example
A lozenge button with entity binding, state-based colours, templates, an animation, and actions:
type: custom:lcards-button
entity: light.workbench
preset: lozenge
text:
default:
font_family: "Antonio, sans-serif"
label:
content: Workbench
position: top-left
font_size: 11
text_transform: uppercase
color: "var(--lcards-moonlight)"
value:
content: "[[[return entity.state === 'on' ? Math.round(entity.attributes.brightness / 255 * 100) + '%' : 'Off']]]"
position: center
font_size: 26
font_weight: bold
color:
default: "var(--lcards-moonlight)"
inactive: "var(--lcards-gray)"
icon: mdi:desk-lamp
icon_area: left
icon_style:
color:
default: "var(--lcards-gray)"
active: "var(--lcards-orange)"
size: 28
style:
border:
color:
default: "var(--lcards-gray)"
active: "var(--lcards-orange)"
width2: 2
tap_action:
action: toggle
hold_action:
action: more-info
animations:
- trigger: on_tap
preset: bounce
params:
scale_max: 1.05
bounces: 2
duration: 400
- trigger: on_entity_change
entity: light.workbench
to_state: "on"
check_on_load: true
preset: glow
params:
color: "var(--lcards-orange)"
blur_max: 12
loop: true