Text Fields & Zones — LCARdS Dynamic and Customizable Text Layout System #325
snootched
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
One of the inconsistencies and (logged) issues in LCARdS are text fields and their placement across the different card types. Text can come from several places (components, presets, user-defined) and getting these placed precisely and consistently can be hard (and buggy.)
That changes with release 2026.04.3+. LCARdS now ships a first-class text field + zone system across the three main card types that use text fields: Button, Slider, and Elbow.
Here's a quick tour.
What Are Zones?
A zone is a named rectangular region of a card's SVG surface. You can now target a named zone and the card handles the geometry for you — padding, relative positioning, and font sizing all operate within the zone bounds.
The key insight is that each card ships with meaningful rectangular sub-regions: a button has its face, an elbow has its vertical bar and its horizontal bar, a slider has its track and its border caps. Zones make those regions addressable.
Auto-calculated Zones
No configuration needed — each supported card automatically builds a zone map when it renders. These are dynamic and calculate at runtime making them responsive to card size changes.
Button
A button in preset mode exposes a single zone:
body— the full card face. In component mode (SVG component packs) the component itself declares named zones that match its internal geometry.bodyEx. ALERT component has
alert_lineandsub_linezones.Slider
The slider exposes its inner track and one zone per enabled border cap.
trackleftrighttopbottomElbow
Elbows have the richest zone vocabulary because the card type itself has the most distinct visual regions.
Simple elbow:
vertical_barhorizontal_barbodySegmented elbow:
outer_vertical_barinner_vertical_barouter_horizontal_barinner_horizontal_barbodyFrame elbow:
top,bottom,left,rightbodyRouting Text Fields to Zones
Every text field now accepts a
zone:key. Drop a field into any auto-zone without touching a pixel value:font_size_percent — Fill the Height
The
font_size_percentproperty sets text size relative to the zone height rather than a fixed pixel value.100means the cap-height of your glyphs spans the full height of the zone;60means 60%, and so on.This is fully responsive: resize the card in the HA dashboard and the text scales with it.
Example of 80% height from the elbow example:
The math uses a measured
cap_height_ratioof0.86for the Antonio font — this corrects for the gap between the SVGfont-sizeattribute and the actual visible cap height, so100%is genuinely full-height, not overshooting or leaving a gap.stretch — Fill the Width Too
Pair
font_size_percentwithstretch: trueand the text fills both axes simultaneously. The zone height governs glyph size;stretchthen expands or compresses glyph spacing to span the zone width using SVGtextLength.A numeric value like
stretch: 0.7targets 70% of zone width instead of 100%.User-Defined Zones
Auto-zones cover the card's structural regions. For custom layouts, you can define your own zones in
config.zones.Values accept pixels, percent, or a mix per axis:
Custom zone names that match an auto-zone name (e.g.
body) replace the auto-calculated bounds entirely, so you can shrink or reposition the primary zone too.Zones can also be managed visually in the Zones tab of the card editor — draw, resize, and name zones without touching YAML.
Debug Overlay
When designing a layout, add
debug_zones: trueto the card config to render a colour-coded overlay of every zone with its name:The toggle is in Zones → Developer Tools in the editor. Remove it (or set to
false) before saving your final dashboard config.What Works With Zones
Zones are supported on all three cards today. Here's the compatibility matrix:
zone:routingfont_size_percentstretchconfig.zones(custom)debug_zonesoverlayAll template syntaxes (token
{...}, JavaScript[[[...]]], Jinja2{{...}}, DataSource{ds:...}) work inside thecontentproperty of any text field.Further Reading
Beta Was this translation helpful? Give feedback.
All reactions