Glassmorphism i Home Assistant — CSS der faktisk virker

De seks CSS-konstanter på tværs af alle kort i mine HA-dashboards, plus mønstre for statusbjælker, map-kort og undertrykkelse af Frosted Glass Dark ::before.

#dashboard #design #card-mod #lovelace #home-assistant
13. december 2024
Glassmorphism i Home Assistant — CSS der faktisk virker

Jeg genopbyggede mine Home Assistant-dashboards tre gange inden de så ud til at høre sammen. Den første version var flade kort. Fin. Den anden var for mange farver. Den tredje landede på glassmorphism — halvgennemsigtige frosne kort på en dyb marineblå baggrund — og den har jeg ikke rørt siden.

Det der følger er den præcise CSS, med forklaringer på de ting der snublede mig.

Home Assistant dashboard med glassmorphism-kort på en mørk marineblå baggrund

De seks CSS-konstanter for hvert glassmorphism-kort

Hvert ydre kort bruger nøjagtigt disse værdier. Ingen variation.

border-radius: 28px;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(15px);
-webkit-backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.10);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);

Og den du vil gå glip af hvis ingen fortæller dig det:

ha-card::before { display: none !important; }

Frosted Glass Dark-temaet (tilgængeligt i HACS under Themes, og adskillige lignende temaer) injicerer et ::before-overlay på hvert ha-card. Hvis du ikke undertrykker det, får din brugerdefinerede baggrund et halvgennemsigtigt lag ovenpå. Symptomet er at dine kort ser lidt forkerte ud — lidt for uigennemsigtige, lidt forkert farvet — og du kan ikke finde ud af hvorfor. Jeg brugte et godt stykke tid på at lede det sted forkert sted inden jeg fandt det.

Ydre kort-skabelonen

type: custom:stack-in-card
card_mod:
  style: |
    ha-card {
      background: rgba(255,255,255,0.05) !important;
      backdrop-filter: blur(15px) !important;
      -webkit-backdrop-filter: blur(15px) !important;
      border: 1px solid rgba(255,255,255,0.10) !important;
      box-shadow: 0 8px 32px rgba(0,0,0,0.3) !important;
      border-radius: 28px !important;
    }
    ha-card::before { display: none !important; }
cards:
  # indhold herunder

custom:stack-in-card (HACS) er indpakningen. Al visuel styling bor her. Indre kort får ingen af det. card_mod (også HACS) er det der gør CSS-injektionen mulig.

Indre kort — kun gennemsigtighed

Kort pakket ind i glasindpakningen skal forsvinde visuelt:

card_mod:
  style: |
    ha-card {
      background: transparent !important;
      box-shadow: none !important;
      border: none !important;
    }
    ha-card::before { display: none !important; }

::before-undertrykkelsen er nødvendig på indre kort også. Temaet anvender det overalt.

Mellem indre kort bruger jeg en svag skillelinje:

border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;

Lysere end du ville forvente. Er den for synlig skærer den glasoverfladen over. Ved 0,06 opacitet læses den som et sektionsskift uden at tiltrække opmærksomhed.

Statusbjælker via ::after

::before er optaget af tema-undertrykkelse. ::after er fri til indhold.

card_mod:
  style: |
    ha-card {
      overflow: hidden !important;
      position: relative !important;
    }
    ha-card::before { display: none !important; }
    ha-card::after {
      content: '' !important;
      position: absolute !important;
      left: 0; top: 0;
      width: {{ states('sensor.batteriniveau') | int(0) }}% !important;
      height: 100% !important;
      background: linear-gradient(90deg,
        rgba(76, 175, 80, 0.18),
        rgba(129, 199, 132, 0.05)) !important;
      pointer-events: none !important;
    }

Gradienten toner ud mod højre, så et kort ved 30% ser anderledes ud end et ved 80% på en måde der læses intuitivt. Jeg bruger det til EV-batteri, støvsugerbatteri og klipperbatteri. For vedligeholdelsessensorer inverterer jeg farvelogikken — tæt på 0% er advarsel, så rød gradient.

Kortkort

Kortkort har deres egne renderingsregler. Sæt et direkte ind i en glas stack-in-card uden at justere det, og du får kantede hjørner der stikker ud over den afrundede indpakning.

Løsningen: overflow: hidden på det ydre kort, border-radius: 0 på det indre kortkort. Det ydres overflow klarer klipningen.

type: custom:stack-in-card
card_mod:
  style: |
    ha-card {
      /* standard glasværdier */
      overflow: hidden !important;
    }
    ha-card::before { display: none !important; }
cards:
  - type: custom:xiaomi-vacuum-map-card
    entity: vacuum.robot
    card_mod:
      style: |
        ha-card {
          border-radius: 0 !important;
          box-shadow: none !important;
          border: none !important;
        }

Badge-undertrykkelse

Mushroom-kort viser farvede badges ved visse tilstande — det orange “utilgængeligt” badge på en enhed der er offline er den hyppigste synder.

card_mod:
  style:
    ".": |
      mushroom-badge-icon.unavailable {
        display: none !important;
      }

"."-nøglen er den rigtige for mushroom-kort i HA 2024+. Ikke ha-card, ikke komponentnavnet — ".". Jeg testede for mange andre selektorer inden denne virkede.

Opnå visuel konsistens på tværs af HA-dashboards

YAML har ikke variabler. Hvert kort der bruger glasbehandlingen får sin egen kopi af de seks CSS-linjer. Vil jeg justere baggrundsopaciteten på tværs af dashboardet, ændrer jeg det 25 steder.

Min løsning: en lokal snippets.yaml-fil med den fulde ydre kortskabelon som en kommentarblok. Indsæt derfra ved oprettelse af nye kort. Det er ikke elegant, men det er til at vedligeholde.

Den rigtige løsning er CSS-custom properties i temaet — var(--glass-bg) defineret én gang, refereret overalt. Det virker i dag hvis dit tema definerer dem. Det spring har jeg ikke taget endnu.