Lay it out in YAML
Each skin is one Lovelace card: custom:dashhaus-orb for Orb, custom:dashhaus-field for Field. The card draws the
whole dashboard from its YAML.
The automatic layout
Section titled “The automatic layout”With nothing but its type, the card lays out every supported entity it can see, a row per area from Home
Assistant’s registries, and keeps up as you add devices. The dashboards the deploy tool creates start this way. Hidden,
configuration and diagnostic entities are left out; room sensors are paired with the humidity and battery sensors on the same device.
Your own layout
Section titled “Your own layout”Open the dashboard, ⋮ → Edit dashboard, the card’s pencil, then Show code editor. The preview redraws as you type, and every mistake is listed at once, with where it is and what you probably meant:
Dashhaus config has 2 problems:• rows[1].cards[0] (sensor.bedroom_temperature): unknown key "humdity" — did you mean "humidity"?• rows[2].cards[3]: media_player.tv: media_player.* entities have no card yetThe simplest layout is a list of cards, drawn in that order on one grid. columns sets how many fit across; leave
it out and the card fits as many as the screen holds. Add, remove or move a line and the page follows:
type: custom:dashhaus-orbtitle: Homecolumns: 2cards: - light.living_room - climate.living_room - cover.living_roomFor headings, write rows instead: one under another, each with its own title, columns and cards. A row is
flat: it holds cards, never other rows. Each card can say where it sits in its row:
width: how many columns it spans, orfullfor all of them. Never pixels.column: the column it starts in. Cards given the same column stack down it.footprint:compact,standardor (Orb)featured: the card’s fixed height.
And each row how it packs them:
flow: denselets a later card fill an earlier gap; the default keeps your order on screen.align: bottomsets a row’s shorter columns on its foot: a sidebar beside a tall hero ends where the hero does.
type: custom:dashhaus-orbtitle: Homerows: - title: At a glance columns: 3 align: bottom cards: - entity: climate.living_room column: 1 width: 2 footprint: featured - entity: alarm_control_panel.house column: 3 - entity: light.living_room column: 3 footprint: compact - title: Around the house columns: 3 flow: dense cards: - entity: weather.home width: 2 - entity: cover.living_room column: 3 footprint: compact - entity: sensor.living_room_temperature width: 2 - entity: switch.porch footprint: compact - bundle: joined label: Modes width: full cards: [input_boolean.guest_mode, input_boolean.dnd, switch.office]A row’s cards lists entities, either as the id alone or as a map with options, and
bundles: bundle: joined puts compact cards side by side in one outer card (lead and titled
are the others). Every footprint is a whole number of Orb’s 60 px units, so a compact card stacks beside a standard
one without gaps.
type: custom:dashhaus-fieldtitle: Homeshow_time: truefinish: home-assistantrows: - title: Quick note: Pressed most columns: 2 cards: - { entity: input_boolean.do_not_disturb, footprint: compact } - { entity: alarm_control_panel.house, footprint: compact } - title: Outside cards: - { entity: weather.home, width: 2 } - sensor.outside_temperature - title: Living room columns: 2 cards: - { entity: light.ceiling, column: 1 } - { entity: cover.living_room, column: 1, footprint: compact } - { entity: climate.living_room, column: 2 }Field’s columns is a most, not a count: columns come from the width, so a module never narrows below its own.
A row holds one footprint, or stacks mixed ones by column: give each module a column, as Living room does.
On a narrower screen a row keeps its cards and their heights and takes fewer columns: widths shrink to fit, and once
a row has fewer columns than it was written for, its cards flow in your order instead of keeping their column. A
row narrowed by its surroundings does the same. A state change never moves a card.


align: bottom), and the porch switch fills the space under the blinds (flow: dense).

Bundles (Orb)
Section titled “Bundles (Orb)”A bundle draws several cards as one outer card, so things that belong together read as one. It is an entry of a row’s
cards, with bundle: saying which of the three it is and its own cards listing the members:
type: custom:dashhaus-orbtitle: Homerows: - title: Nursery columns: 3 cards: - bundle: titled title: Sound machine area: Nursery cards: - entity: switch.sound_machine_power name: Power - entity: light.sound_machine_night_light name: Night light - entity: switch.sound_machine_white_noise card: sound name: White noise - bundle: lead label: Upstairs heating sheet_title: Also upstairs cards: [climate.second_floor, climate.dyson_heater] - bundle: joined label: Bedtime cards: [input_boolean.sleep_mode, input_boolean.do_not_disturb]titled: the parts of one thing, often one device split into several entities, under a lid that names it (title, required) and its room (area) once. Name each part for what it is on the thing (“Power”, “Night light”), not “Sound machine power”. A part in the lid’s room leaves the room off its line and says its own detail instead: since when, a light’s warmth, a sound’s volume. The lid is a heading and opens nothing; each part opens its own sheet. See it in Storybook.lead: one card that matters most, drawn standard, with related cards hanging under it as compact rows: a floor’s thermostat and the heater beside it. The lead’s sheet lists the rows again, live, undersheet_title(“Also in this bundle” when left out). See it in Storybook.joined: two or more equal compact cards side by side in one card, with no heading: a few modes, say. Once each would get less than about 170 px they stack instead. See it in Storybook.
label names a joined or lead bundle for screen readers; it isn’t drawn. Every member is still its own card, with its
own tap, press and hold, and sheet, and takes its own card’s keys (name, card:, history …), but the bundle sets
their footprints and places them: a member takes no footprint, its width and column go on the bundle, and a
bundle can’t hold another. A bundle is as tall as its members make, in the same 60 px units as every other card: a titled
bundle’s lid and three parts are as tall as a featured card. Field has no bundles; its card refuses the key, saying
so.
When the YAML is wrong
Section titled “When the YAML is wrong”The card checks the whole YAML before it draws, and lists every problem at once: where it is, what’s wrong, and what to write instead. This Orb card has five of the mistakes people make most:
type: custom:dashhaus-orbtitle: Homecards: - light.living_roomrows: - climate.living_room - title: Comfort columns: 2 cards: - entity: climate.living_room width: 3 - entity: light.living_room span: 2 - title: Outside columns: "3" cards: - weather.homeDashhaus config has 5 problems:• "cards" and "rows" both lay out this page: keep "cards" for one plain grid, or move those cards into a row under "rows"• rows[0] (climate.living_room): this is a card, not a row: put it in a row's "cards", or list the cards under "cards" at the top for one plain grid• rows[1].cards[0] (climate.living_room): "width: 3" is wider than this row's 2 columns: use width: full, or raise the row's columns to 3• rows[1].cards[1] (light.living_room): "span" isn't a key: a card spans columns with "width", a whole number or full• rows[2]: "columns" must be a whole number from 1 to 12, or auto — write columns: 3, without quotescardsandrowstogether. A page is one or the other:cardsfor one plain grid,rowsfor titled groups. Move the loose cards into a row of their own.- A card where a row belongs. Every entry under
rowsis a map with its owncards; an entity id there is a card. Indent it under a row’scards. - A card wider than its row.
widthcounts the row’s columns, so it can’t be more than the row’scolumns. Usewidth: fullfor all of them. span. A card’s columns arewidth.- A number in quotes.
"3"is text to YAML; writecolumns: 3.
In Field, a row holds one footprint, so a compact module beside standard ones needs either a row of its own or a
column on every module of the row, which stacks them by column:
type: custom:dashhaus-fieldtitle: Homerows: - title: Living room cards: - light.ceiling - entity: cover.living_room footprint: compactDashhaus config has 2 problems:• rows[0].cards[0] (light.ceiling): this row mixes standard and compact modules, so each stacks in a column: give it a "column", or move the compact ones into a row of their own• rows[0].cards[1] (cover.living_room): this row mixes standard and compact modules, so each stacks in a column: give it a "column", or move the compact ones into a row of their ownHome Assistant reads the YAML before the card does, so it reports a broken file itself (a bad indent, a tab, an
unclosed quote) and the card never sees it. A mistake that is still valid YAML, such as a missing - that turns a
list into one map, reaches the card as whatever it parsed to.
Which card draws an entity
Section titled “Which card draws an entity”The entity’s domain picks its card. Where two cards draw one domain, card: picks the other:
| Entity | Card |
|---|---|
light.* | light |
input_boolean.*, switch.* | toggle |
cover.* | cover |
switch.* with card: sound | sound, with its volume number.* found beside it |
climate.* | climate |
humidifier.* | humidifier |
fan.* | fan |
sensor.* | sensor, with its device's humidity and battery sensors |
weather.* | weather, with its air-quality sensor and sun.sun |
sensor.*_voucher | guestWifi, with its join QR code image and what refreshes it and makes a new one; card: guestWifi for one named otherwise |
alarm_control_panel.* | alarm |
lock.* | lock, with its device's battery sensor |
sensor.*_sleep_state | owlet, with its heart rate, oxygen, charging and base station sensors; card: owlet for one named otherwise |
An entity with no card is an error that says so, rather than an empty space.
| Where | Orb | Field |
|---|---|---|
| The card | title, subtitle, show_time, hour_cycle, viewing, theme, accent, nav, pages | title, subtitle, show_time, hour_cycle, viewing, finish, footprint, quiet, pages, nav |
| The page (the card, or one of its pages) | cards, rows, columns, flow; columns from 1 to 12, or auto | cards, rows, columns, flow; columns from 1 to 4, or auto |
| A row | title, note, columns, flow, align, cards | title, note, columns, flow, align, cards |
| Any card | entity, card, name, area, footprint, width, column, show_control, history | entity, card, name, area, footprint, width, column, history |
| A bundle | bundle (joined, lead, titled), cards, width, column, label (joined, lead), sheet_title (lead), title (titled), area (titled) | none |
Each card adds its own:
| Card | Orb | Field |
|---|---|---|
| light | none | none |
| toggle | icon, description | icon, description |
| cover | none | none |
| sound | volume | volume |
| climate | unit | unit |
| humidifier | none | none |
| fan | none | none |
| sensor | humidity, battery, outdoor, unit | humidity, battery, outdoor, unit |
| weather | aqi, aqi_scale, sun, forecasts | aqi, aqi_scale, sun, forecasts |
| guestWifi | access, network, qr, new_code, refresh | access, network, qr, new_code, refresh |
| alarm | read_only, exit_delay, entry_delay, open_sensors | read_only, exit_delay, entry_delay, open_sensors |
| lock | battery | battery |
| owlet | heart_rate, oxygen, charging, base_station, alerts, stale_after | heart_rate, oxygen, charging, base_station, alerts, stale_after |
viewing: far is for a wall panel read from across the room: larger status lines and captions, heavier figures,
the same card heights. A key Orb takes and Field doesn’t (theme, accent, show_control, bundles) is
refused with the reason, for YAML copied from one card to the other.
The specification’s deploy page has every value and default.
Pages and the nav
Section titled “Pages and the nav”A nav docks at the bottom of the screen, one pill or key per destination. Without nav, it lists the card’s pages,
or else its titled rows. pages are more pages in the same card, each with its own cards or rows; the URL keeps
the page open (#page=nursery), so the back button returns.
type: custom:dashhaus-orbtitle: Homerows: - title: Quick actions cards: [light.living_room, climate.living_room]pages: - id: nursery title: Nursery cards: - sensor.owlet_sock_ac000w0123_sleep_state - { entity: switch.nursery_music, card: sound }nav: - page: home - page: nursery - navigate: /energy label: EnergyA destination is a section: of the main page, a titled row by its title, a page: by its id (home is the main page), or
navigate: to another Home Assistant dashboard by its path. nav: false turns the nav off; a wall panel has none
unless nav lists one.
Both skins take the same pages and nav.