Skip to content

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:

ModeKeyUse for
PresetpresetStandard LCARS buttons — lozenge, bullet, capped, etc.
ComponentcomponentInteractive multi-segment controls (D-pad, alert shape)
Custom SVGsvgYour own SVG with interactive segments

Top-Level Options

OptionTypeDescription
typestringcustom:lcards-button (required)
entitystringEntity to monitor and control
presetstringButton shape preset — see Presets
componentstringComponent type: dpad or alert (component mode)
svgobjectCustom SVG config — see Custom SVG Mode
ranges_attributestringEntity attribute used for above:/below:/between: range conditions — see Range Conditions
rangeslistState-driven component preset switching — see Component Mode: Alert
interactivebooleantrue by default. Set false to suppress hover colour changes and hover animations — useful for decorative buttons. Tap/hold actions still fire.
controlobjectControl behaviour — see Control
show_iconbooleanShow/hide the icon (default: true)
iconstringMDI icon (e.g. mdi:lightbulb)
icon_areastringIcon position: left, right, top, bottom, none (default: left)
icon_area_sizenumberIcon area width/height in px (default: 60)
icon_area_backgroundstring / objectIcon area background colour — state map supported (default: transparent)
icon_styleobjectAdvanced icon styling — see icon_style Object
dividerobjectDivider between icon area and content area — see divider Object
dpadobjectD-pad component config — see Component Mode: D-pad
alertobjectAlert component config — see Component Mode: Alert
styleobjectVisual styles — see style Object
shape_textureobjectSVG texture inside the button fill — see Shape Texture
filterslistCSS / SVG filters — see filters List
idstringCard ID for Rules Engine targeting
tagslistTags for Rules Engine targeting
heightnumber / stringCard height — see Sizing
widthnumber / stringCard width — see Sizing
min_heightnumber / stringMinimum card height — see Sizing
min_widthnumber / stringMinimum card width — see Sizing
textobjectText label definitions — see Text Fields
tap_actionobjectTap action — see Actions
hold_actionobjectHold action — see Actions
double_tap_actionobjectDouble-tap action — see Actions
animationslistCard animations — see Animations
background_animationlist / objectCanvas background — see Background Animations
data_sourcesobjectNamed data source definitions — see Data Sources
soundsobjectPer-card sound overrides — see Sound Effects
triggers_updatelistExtra entity IDs that trigger re-render — see Data Sources
grid_optionsobjectHA grid layout — see grid_options

Control

FieldTypeDescription
control.attributestringEntity attribute to control (leave blank to control entity state directly)
yaml
control:
  attribute: brightness   # control light brightness directly

style Object

style.card

FieldTypeDescription
color.backgroundstring / objectCard background — state map supported

style.cursor

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

FieldTypeDefaultDescription
colorstring / objectthemeBorder colour — state map supported
widthnumber / string / object0Border width in px, a theme token string, or { top, right, bottom, left } per-side
radiusnumber / string / objectthemeCorner 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.*):

FieldTypeDescription
colorstring / objectText colour — state map supported
font_sizenumber / stringFont size in px or CSS value
font_weightstring / numberCSS font-weight
font_familystringCSS font-family

See Text Fields for the full per-field options table.

yaml
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: 13

icon_style Object

Fine-grained control over the icon appearance and placement within its area.

FieldTypeDefaultDescription
typestringmdiIcon type: mdi, si (Simple Icons), or entity (entity state icon)
iconstring / objectMDI icon name, or a state map of icon names — overrides the top-level icon field
colorstring / objectthemeIcon colour — state map supported
sizenumber24Icon size in px
positionstringcenterIcon position within its area
xnumberAbsolute X offset in px (overrides position)
ynumberAbsolute Y offset in px (overrides position)
x_percentnumberX as percentage of icon area width (0–100)
y_percentnumberY as percentage of icon area height (0–100)
rotationnumber0Icon rotation in degrees (-360 to 360)
paddingnumber / objectPadding in px (number = all sides, or { top, right, bottom, left })
padding_leftnumberLeft padding in px — overrides padding
padding_rightnumberRight padding in px — overrides padding
padding_topnumberTop padding in px — overrides padding
padding_bottomnumberBottom padding in px — overrides padding
spacingnumber8Space between icon and text area in px
yaml
icon: mdi:thermometer
icon_area: left
icon_style:
  color:
    default: "var(--lcards-gray)"
    active: "var(--lcards-orange)"
  size: 32
  padding: 8

Per-State Icons

Set icon_style.icon to a state map to swap the icon based on entity state (including range conditions):

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

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

FieldTypeDefaultDescription
colorstring / objectthemeDivider colour — state map supported
widthnumberthemeDivider thickness in px
yaml
divider:
  color: "var(--lcards-orange)"
  width: 2

filters List

CSS and SVG filters applied to the card.

FieldTypeDescription
modestringcss (default) or svg
typestringCSS type (blur, brightness, contrast, saturate, drop-shadow) or SVG primitive
valuestring / number / objectFilter parameters
yaml
filters:
  - type: blur
    value: 4

  - type: brightness
    value: 0.8

  - type: saturate
    value: 0.5

Text Fields

Multiple text labels can be placed anywhere on the card. See Text Fields for the full reference.

yaml
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

PresetDescription
lozengeFully rounded on both ends, icon area on left
lozenge-rightFully rounded on both ends, icon area on right
bulletRounded right end, flat left — icon area on left
bullet-rightRounded left end, flat right — icon area on right
cappedRounded left end, flat right — icon area on left
capped-rightRounded right end, flat left — icon area on right
barrelFlat corners, no border, icon area on left
barrel-rightFlat corners, no border, icon area on right
filledTransparent border, large text label on right
filled-rightTransparent border, large text label on left
outlineTransparent background, border only — Picard style
outline-rightTransparent background, border only, icon area on right
iconSquare icon-only button with large rounded corners
text-onlyNo 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.

PresetDescription
bar-label-baseBar label foundation — filled button, auto-scaling text, centered
bar-label-leftBar label with left-aligned text
bar-label-centerBar label with centered text
bar-label-rightBar label with right-aligned text
bar-label-squareBar label with square corners
bar-label-lozengeBar label with fully rounded ends
bar-label-bullet-leftBar label with flat left, rounded right
bar-label-bullet-rightBar label with rounded left, flat right
bar-label-capped-leftBar label with rounded left, flat right
bar-label-capped-rightBar 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.

FieldTypeDescription
entitystringEntity for this segment (state-based colours, icons)
tap_actionobjectAction on tap — see Actions
hold_actionobjectAction on hold
double_tap_actionobjectAction on double-tap
style.fillstring / objectSegment fill colour — state map supported
style.strokestring / objectSegment stroke colour — state map supported
style.stroke-widthnumber / string / objectStroke width in px, CSS string, or state-based map
style.opacitynumber / objectSegment opacity (0–1) or state-based map
textobjectPer-segment text labels
iconstringMDI icon for this segment
animationslistSegment-specific animations
yaml
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.tv

Component Mode: Alert

The alert component displays a Starfleet alert symbol with animated bar elements.

alert Object

FieldTypeDescription
alert.color.shapestringFill colour override for the shield shape
alert.color.barsstringStroke colour override for the bar lines
alert.custom_presetsobjectCustom or override presets merged over built-ins (keyed by preset name)
alert.segmentsobjectPer-segment fine-grained style overrides (shape, bars)

ranges List (state-driven preset switching)

FieldTypeDescription
ranges[].presetstringComponent preset name to apply when this range matches (required)
ranges[].attributestringOverride ranges_attribute for this entry only
ranges[].abovenumberMatch when value is ≥ this threshold
ranges[].belownumberMatch when value is < this threshold
ranges[].equalsstring / number / booleanMatch when value equals this
ranges[].color.shapestringTransient shape fill override while this range is active
ranges[].color.barsstringTransient bars stroke override while this range is active
yaml
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: 0

Custom SVG Mode

svg Object

FieldTypeDescription
svg.contentstringInline SVG markup
svg.srcstringURL to an external SVG file
svg.viewBoxstringOverride the SVG viewBox attribute
svg.preserveAspectRatiostringSVG preserveAspectRatio value
svg.enable_tokensbooleanResolve {theme:...} tokens inside the SVG markup
svg.allow_scriptsbooleanAllow <script> elements inside the SVG (default: false)
svg.segmentsobjectInteractive segment configs keyed by element id — use default for shared config
yaml
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: toggle

SVG elements with id attributes become interactive segments.

Note: When using CSS custom properties in SVG fill attributes, browser support can vary. Using currentColor in the SVG with CSS color styling 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.

yaml
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

PresetDescriptionKey Config
gridScrolling orthogonal grid linesline_spacing, pattern (both/horizontal/vertical)
diagonalScrolling diagonal hatchingline_spacing
hexagonalScrolling hexagonal gridhex_radius
dotsScrolling dot griddot_radius, spacing
fluidOrganic swirling fractalNoisebase_frequency, num_octaves
plasmaDual-colour turbulence washcolor_a, color_b, base_frequency
shimmerDirectional light-sweepangle, highlight_width, speed
flowDirectional streaming currentswave_scale, scroll_speed_x
levelFill bar with optional wavefill_pct, direction, wave_height
pulseBreathing radial glowradius, min_size, speed
scanlinesCRT-style scan-line overlayline_spacing, direction
imageUser-supplied image clipped to shapeurl, 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.

yaml
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 changesinteractive: true (default)interactive: false
Cursor on hoverpointer (hand)default (arrow)
Background colour on hoverChanges to hover colour from preset/styleNo change
Hover animationsFireSuppressed
Tap / hold actionsFire normallyFire normally
yaml
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 it

To keep hover effects but override only the cursor shape, use style.cursor independently:

yaml
type: custom:lcards-button
style:
  cursor: crosshair          # any valid CSS cursor string

Annotated Example

A lozenge button with entity binding, state-based colours, templates, an animation, and actions:

yaml
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