Text¶
Use layout.texts for headings, captions, button labels, units, and composed entity information placed anywhere on a card. Text can be literal, generated by JavaScript, or taken from an existing name, area, or state item.
A text item does not need an entity. Its default action is none, so a label placed over a rectangle does not block the rectangle's action.
Basic text¶
Set text to a string for a simple label:
layout:
texts:
- id: history-title
text: History
xpos: 50
ypos: 15
styles:
font-size: 1.2em
font-weight: bold
text-anchor: middle
Use localize_tag instead of text to display a label from Home Assistant in the user's selected language:
layout:
texts:
- id: duration-title
localize_tag: ui.dialogs.helper_settings.timer.duration
xpos: 50
ypos: 15
The tag must be an existing Home Assistant translation key. For example, ui.dialogs.helper_settings.counter.step displays the translated label for "Step size". FHS does not provide its own translation or fallback for a tag.
Multipart text¶
Set text to a list when parts need different styles or should appear on separate lines:
layout:
texts:
- id: history-label
xpos: 50
ypos: 45
styles:
text-anchor: middle
dominant-baseline: middle
text:
- value: History
styles:
fill: var(--secondary-text-color)
- value: 7 days
new_line: true
styles:
fill: var(--primary-text-color)
font-weight: bold
Parts on the same line are placed directly after each other. Add spaces to the part values where needed:
text:
- localize_tag: ui.dialogs.helper_settings.timer.duration
- value: ': '
- value: 7 days
styles:
font-weight: bold
Each part has its own localize_tag, so translated labels and dynamic values can be combined and styled independently.
new_line: true starts a new line. Use dy to change the line spacing; its default is 1.2 em. dx and dy can also move individual parts.
Dynamic parts¶
Each part can use its own entity, JavaScript template, state map, color stops, styles, and animation. Text uses fill by default. Select show.item_style: colorstop for hard value ranges or show.item_style: colorstopgradient to blend between adjacent stops. The complete TextTool and each individual part can use their own mode. When entity_index is omitted from a part, it uses the entity from the complete text item when one is configured.
texts:
- id: active-period
xpos: 50
ypos: 50
entity_index: 0
text:
- value: 'Period: '
- value: |
[[[
return `${state} day${Number(state) === 1 ? '' : 's'}`;
]]]
styles:
font-weight: bold
A state map can replace the displayed value and other settings for a part:
text:
- value: Unknown
entity_index: 1
state_map:
map:
- state: 'on'
value: Active
styles:
fill: var(--success-color)
- state: 'off'
value: Inactive
styles:
fill: var(--secondary-text-color)
Reusing names, areas, and states¶
A text part can reuse the displayed content of an existing item from layout.names, layout.areas, or layout.states. Select the source with its type and id:
layout:
names:
- id: room-name
entity_index: 0
visibility: hidden
states:
- id: room-temperature
entity_index: 0
visibility: hidden
show:
uom: end
texts:
- id: room-summary
xpos: 50
ypos: 50
text:
- type: name
id: room-name
- value: ': '
- type: state
id: room-temperature
styles:
font-size: 1em
uom:
styles:
font-size: 0.75em
The source keeps processing its entity while hidden. Its formatted content, styles, color stops, and active animation are reused, but its position, group, actions, and visibility are not.
Set source_styles: false when only the formatted content is needed:
- type: state
id: room-temperature
source_styles: false
Styles on the text part override the source. A referenced state also includes its unit according to the source's show.uom setting. Use show.uom and uom on the text part to override its display or styling.
Ellipsis¶
Use ellipsis on the complete text item to limit every visual line. The limit is shared by all parts on that line and starts again after new_line.
texts:
- id: compact-label
xpos: 50
ypos: 50
ellipsis: 16
text:
- value: 'History period: '
- value: 7 days
styles:
font-weight: bold
A part may also have its own ellipsis. That limit is applied before the limit of the complete text item.
Wrapping¶
Use text_overflow to wrap long text at spaces. The first line always remains at the configured ypos; continuation lines are added below it.
texts:
- id: weather-summary
xpos: 50
ypos: 20
text_overflow:
mode: wrap
wrap:
max_width: 40
max_lines: 3
dy: 1.4
text: A longer weather summary that may use up to three lines
max_width uses the actual displayed width in card dimensions. Use characters instead when an approximate character limit is preferred. Set one of these two fields, not both. dy controls the line spacing in em.
Wrapping only occurs at spaces, so words are never split. When max_lines is set, remaining text on the final line ends with ... and still fits within max_width. Without max_lines, TextTool creates as many lines as needed.
Use ellipsis with max_width to shorten every visual line to its displayed width:
text_overflow:
mode: ellipsis
ellipsis:
max_width: 40
Use ellipsis.characters instead for a character limit. Set either characters or max_width, not both. The existing ellipsis: 40 shorthand remains supported for character-based ellipsis.
Use fit to reduce the complete TextTool when its widest line exceeds a configured width:
text_overflow:
mode: fit
fit:
max_width: 40
min_font_size: 0.7em
Fit mode works with single-line and manually configured multiline text. Every line and styled part is reduced by the same amount, so their relative font sizes and spacing remain intact. Text is never enlarged, wrapped, or shortened. Omit min_font_size to keep reducing until the widest line fits. When a minimum is configured, text may remain wider than max_width after reaching that font size.
Configuration fields¶
Text item¶
| Field | Required | Default | Description |
|---|---|---|---|
id | Generated | Identifies the item for same_as, animations, and references. | |
text | Alternative | A string or list of text parts. Not required when localize_tag supplies a simple label. | |
localize_tag | Alternative | Home Assistant translation key for a simple label. | |
xpos | Horizontal position on the card canvas. | ||
ypos | Vertical position on the card canvas. | ||
entity_index | None | Entity used by the item and inherited by parts without their own entity. | |
ellipsis | None | Maximum number of characters on each visual line. | |
text_overflow | None | Wraps, shortens, or fits text using the selected mode. TextTool only. | |
styles | Styles inherited by all parts, including alignment and font settings. | ||
color_stops | None | Colors the complete text item from its entity value. | |
show.item_style | colorstop | Selects a hard or blended color-stop color. | |
colorstop.fill / .stroke | true / false | Selects which text properties receive the hard color. | |
colorstopgradient.fill / .stroke | true / false | Selects which text properties receive the blended color. | |
tap_action | none | Action for the complete text item. | |
hold_action | None | Hold action for the complete text item. | |
double_tap_action | None | Double-tap action for the complete text item. | |
group | Card | Places the text in a configured group. | |
same_as | None | Reuses an earlier item from layout.texts. |
Text overflow¶
| Field | Required | Default | Description |
|---|---|---|---|
mode | Selects wrap, ellipsis, or fit. | ||
wrap.characters | Alternative | Approximate maximum number of characters per visual line. Do not combine with wrap.max_width. | |
wrap.max_width | Alternative | Maximum displayed width of every wrapped line in card dimensions. Do not combine with wrap.characters. | |
wrap.max_lines | Unlimited | Maximum number of wrapped lines. Remaining text ends with .... | |
wrap.dy | 1.2 | Distance between automatically wrapped lines in em. | |
ellipsis.characters | Alternative | Maximum number of characters per visual line. Do not combine with ellipsis.max_width. | |
ellipsis.max_width | Alternative | Maximum displayed width of every visual line in card dimensions. Do not combine with ellipsis.characters. | |
fit.max_width | For fit | Maximum width of the complete TextTool in card dimensions. | |
fit.min_font_size | None | Smallest base font size in em used by fit mode. |
Text part¶
| Field | Required | Default | Description |
|---|---|---|---|
value | For text | Text or a JavaScript template that returns text. | |
localize_tag | Alternative | Home Assistant translation key used as this part's value. | |
type | text | Uses literal text, or references a name, area, or state. | |
id | For a reference | Item id in the corresponding names, areas, or states section. | |
source_styles | true | Set to false to reuse content without source styles, color stops, or animations. | |
entity_index | Item entity | Entity used by templates, state maps, and color stops for this part. | |
new_line | false | Starts the part on a new line. | |
dx | 0 | Horizontal offset in em. | |
dy | 0, or 1.2 for a new line | Vertical offset in em. | |
ellipsis | None | Maximum number of characters for this part. | |
styles | Overrides inherited styles for this part. | ||
state_map | None | Changes the part for matching entity states. | |
color_stops | None | Colors the part from its entity value. | |
show.item_style | colorstop | Selects a hard or blended color-stop color for this part. | |
colorstop.fill / .stroke | true / false | Selects which text properties receive the hard color. | |
colorstopgradient.fill / .stroke | true / false | Selects which text properties receive the blended color. | |
animation_id | None | Connects this part to a text animation. | |
show.uom | Source setting | Overrides the UOM position for a referenced state. | |
uom | Source setting | Overrides UOM offsets and styles for a referenced state. |
Reusing labels¶
Text items support same_as and the usual numeric delta fields. This makes a row of button labels concise:
texts:
- id: one-day
text: 1 day
xpos: 25
ypos: 50
- id: two-days
same_as: one-day
text: 2 days
same_as_dxpos: 25
- id: seven-days
same_as: two-days
text: 7 days
same_as_dxpos: 25