Controls
The entity card, the entity group card and the entity sections card can do more than show an entity: one key, control, adds a switch, a slider, a stepper, mode segments, buttons or a hold-to-confirm button to it. Every control is built from the library the cards already draw, so it looks like the display it replaces and takes the entity's colour and rules. The examples on this page are live: tap, drag and hold them.
One key
control: auto draws what the entity's domain calls for; a name picks a control. Nothing else changes: the name, the value, the rules and the actions stay as they are.
| Option | Default | Description |
|---|---|---|
control | auto (or true) picks the domain default; toggle, slider, stepper, segments, buttons, button, select or hold pick one; none draws nothing. | |
control_position | per control | end puts the control on the line, block under it, lead makes the icon the control (toggle, button, hold); a table field or ring has no icon, the control goes to the end. |
control_attribute | the shown mode, else the main one | What segments or a select set on a thermostat or fan: hvac_mode, preset_mode or fan_mode. |
control_step | entity step, else 1 (climate 0.5) | Step of a slider or stepper. |
control_options | the entity's modes or options | Options of segments and select: values, or { value, label, icon }. With control: buttons, your own buttons: { entity, icon, label, color, action }, see Your own buttons. |
control_confirm | false | The primary control becomes hold to confirm; every button of a group holds on its own. |
toggle: true from earlier versions still works and means control: toggle.
Domain defaults
What control: auto draws, and the service each control calls:
| Domain | Controls | Services |
|---|---|---|
light | toggle, brightness slider under the line (not for on/off lights) | homeassistant.toggle, light.turn_on with brightness_pct |
switch, input_boolean | toggle | homeassistant.toggle |
fan | toggle and speed segments (from percentage_step) | fan.set_percentage, fan.turn_off |
cover | open / stop / close buttons, position slider (when it has a position) | cover.open_cover, stop_cover, close_cover, set_cover_position |
climate | target temperature stepper; with attribute: hvac_mode mode segments | climate.set_temperature, set_hvac_mode, set_preset_mode |
lock | hold to lock / unlock | lock.lock, lock.unlock |
script, scene, button, input_button | Run chip (a round button in row items) | script.turn_on, scene.turn_on, button.press, input_button.press |
input_select, select | select | select_option |
input_number, number | slider under the line; a stepper where there is no room | set_value |
media_player | previous / play-pause / next, volume slider | media_previous_track, media_play_pause, media_next_track, volume_set |
Other domains get no control from auto; a named control on them needs a domain the table lists for that control, otherwise the card logs a warning and the control does nothing.
The controls
Toggle and lead tap
The library switch, 48 × 28, a smaller one in grid cells, column items and tables. With control_position: lead the icon itself is the switch: filled when on, grey when off.
The last tile sets control_confirm: true: the switch becomes a hold-to-confirm button.
Slider
The 8 px bar with a knob. Drag it, or focus it and use the arrow keys; a bubble shows the value while dragging. Under the line (block, the default in tiles, lists, grid cells and hero leads) it replaces a visual: bar; on the line (end) it is a short 6 px slider. The fill takes the entity colour, so rules colour the slider too. Brightness, position, volume and fan speed are always 0 to 100 %; min and max scale the visuals only, and bound the slider of a number or a thermostat.
Stepper
− value + for setpoints and numbers. The step comes from the entity (target_temp_step, step) or control_step and counts from the minimum, as Home Assistant counts it (min 1, step 2: 1, 3, 5 …); the buttons stop at the entity's bounds.
Segments
Modes, presets and speeds as a pill group; the active one is filled. Options come from the entity (hvac_modes, preset_modes, fan speeds from percentage_step) or from control_options, where every entry may carry a label and an icon. On a thermostat or fan, control_attribute says which mode the segments set; without it they follow the shown attribute when it is a mode, else the HVAC mode or the fan speed. The last row shows the current temperature and still switches the HVAC mode. A fan with more than six speeds gets a slider instead of segments.
Buttons
Round icon buttons: open / stop / close for covers, previous / play-pause / next for media players.
Your own buttons
With control: buttons, control_options replaces the domain's buttons with a list of your own, for the scenes of a room, a few scripts or the lights next to it. A button runs its entity (scenes and scripts turn on, buttons press) or switches it (a light, a switch, a fan: the button is filled while it is on); an action (any Home Assistant action, the shape of tap_action) runs instead; the button's entity is the entity of more-info and toggle, and the target of a perform-action that names nothing to act on itself (no target, and no entity_id, device_id, area_id, floor_id or label_id in its data). Every button takes its own color (default: the row's colour) and icon (default: the entity's icon); with a label it is a chip with text, without one a round icon button. A row of buttons needs no entity of its own: a name and an icon are enough.
| Key | Default | Description |
|---|---|---|
entity | What the button runs or switches; the entity of action (the target of a perform-action without one). Each button needs an entity or an action. | |
action | the entity's own | A Home Assistant action, run instead of the entity's service (perform-action, navigate, more-info …). |
color | the row's colour | Colour token, hex or var(); the button is a soft tint of it, filled while its entity is on (a lock unlocked, a cover open). |
icon | the entity's icon | mdi: icon. |
label | none (icon only) | Text beside the icon; the name a screen reader reads is the label, else the entity's name. |
An entity with nothing to run or switch (a sensor) opens its more-info dialog. control_confirm: true makes every button a hold of its own: round buttons fill their ring, chips fill from the left. control_position: block puts the buttons under the line, where many of them wrap. Row items and the header draw no buttons: there an item needs an entity or a value of its own.
Button
A Run chip for scripts, scenes and buttons; it says Done for a moment after the call. In a row layout it is a round button in place of the icon.
Select
A menu for input_select and select entities, or any options list on a domain with a select service.
Hold to confirm
Press and hold for a second; a ring fills around the button and the service runs when it is full. Letting go earlier cancels. The default for locks; control_confirm: true turns any toggle or button into one, and gives every button of a group (the garage door's open, stop and close) a hold of its own. control: hold on a light, switch, fan or media player toggles it; other domains have nothing to hold and grey the button out.
Where a control sits
Controls use the slots the entities already have. In tiles, lists and hero leads the end slot is where the toggle used to be and the block slot is under the line. Grid cells put small controls next to the icon and sliders under the value. Row items draw only lead controls (tap the icon, a round button, a hold button); column items and table fields put small controls on the right, and keep only the primary control of control: auto (a cover's buttons, a light's switch).
When a card gets narrow, a control on the line wraps under the name instead of squeezing it away, and in a narrow column a wide control goes under the name. A tile with a control sizes to its content, and asks the sections grid for room: at least 4 columns for a switch or hold button on its line, 6 for anything wider. Segments shrink to their icons and, as a last resort, scroll sideways, so no option is ever cut off.
Grid
Row and column
Table
A room
Sections combine them: a hero lead with a switch and a brightness slider, a grid of controls, scenes in a row and settings in a table.
States
A control shows what it asked for right away, as a ghost: the knob pulses, the fill is translucent, the segment is outlined, until the entity's state changes (or five seconds pass, when the device never answers). An unavailable entity greys its control out. The demo's attic light and lock take a moment to answer, so their ghosts are easy to see; the rest of the demo home answers at once.
Keyboard and screen readers
Every control works without a pointer. Tab reaches the row's own action first (a button behind the content, named after the entity), then the row's controls in order; the focus stays where it is while the card updates.
- Switch and lead tap: a switch (
role="switch"), Space or Enter flips it. - Slider: the arrow keys step, PageUp and PageDown jump ten steps, Home and End go to the ends; the call follows a short pause.
- Segments: a radio group with one tab stop; the arrow keys move along the segments and choose, Home and End jump to the ends.
- Stepper, buttons, Run: plain buttons.
- Select: the browser's own menu.
- Hold to confirm: keep Space or Enter pressed for a second. A screen reader cannot hold, so it presses twice: the first press arms the button ("Press again to …"), a second press within five seconds runs it.
A failed service call shows Home Assistant's toast with the error and fires the failure haptic.
Controls never ask for confirmation through Home Assistant's dialog; control_confirm: true is their way of asking. tap_action, hold_action and double_tap_action on the row keep working next to a control: the control swallows its own gestures, the rest of the row runs the actions.