Adattamento dei componenti semantici

Funzionalità web: Query di stile del container

Utilizza le query di stile (@container style()) per attivare variazioni contestuali senza impostare come hardcoded ciò che produce o reagisce a ogni contesto. In questo modo, si riduce l'accoppiamento del sistema di progettazione e si migliorano l'estensibilità e l'incapsulamento dei componenti.

Ad esempio, una regola section.featured { --surface: featured } può contrassegnare un contesto e una pagina di destinazione potrebbe anche utilizzarlo per impostazione predefinita tramite main { --surface: featured }. I componenti attivano quindi la reazione a --surface: featured: una scheda mostra un badge promozionale, un pulsante viene impostato per impostazione predefinita sulla sua variante con riempimento e così via.

Le query di stile consentono a entrambe le parti di rimanere separate: le piattaforme in primo piano non nominano mai gli elementi che si adattano a loro e i componenti non ispezionano mai ciò che ha prodotto il contesto. Entrambi i lati possono essere estesi in modo indipendente, con nuovi componenti e nuove piattaforme in primo piano, senza toccare l'altro. I selettori discendenti (ad es. .featured .button) impongono l'opposto: il selettore deve codificare entrambi i lati della relazione e deve cambiare ogni volta che cambia uno dei due lati.

Quando utilizzare questa guida

Questa guida illustra le modifiche comportamentali: un componente che decide cosa visualizzare, come organizzarsi o quale variante presentare in risposta al suo contesto, nascondendo o mostrando un badge, cambiando la direzione del layout o scambiando una variante di pulsante.

Se invece hai bisogno di modifiche a livello di token (modalità di densità, temi o altri token di ordine superiore che modificano in modo uniforme valori come spaziatura interna e colore in molti componenti), consulta Reattività dei token di progettazione.

Scegli lo strumento giusto

Utilizza una query di stile quando entrambi i lati di una relazione contestuale possono cambiare in modo indipendente: nuovi elementi potrebbero iniziare a produrre il contesto o nuovi componenti potrebbero iniziare a reagire. L'indirezione si ripaga in termini di estensibilità e incapsulamento, mentre le query di stile superano i confini dello shadow DOM che i selettori discendenti non possono superare. Quando questa flessibilità non è necessaria, preferisci lo strumento più semplice:

  • Selettori discendenti (.toolbar .button): una relazione fissa e una tantum che non è riutilizzabile o estensibile. Si applica il principio YAGNI: non aggiungere indirezioni che non utilizzerai.
  • Query sulle dimensioni (@container (min-width: …)): modifiche al layout e alla densità in base allo spazio disponibile, non allo stato semantico.
  • Query di stile (@container style(…)): stato semantico, ovvero ciò che un componente deve visualizzare, disporre o presentare in un determinato contesto.

Direttive per l'implementazione

  1. Definisci un flag di contesto semantico utilizzando una proprietà personalizzata CSS su un container.
  2. NON impostare container-type per le query di stile; queste eseguono query sulle proprietà personalizzate ereditate sull'antenato più vicino e non richiedono un contesto di contenimento esplicito.
  3. OBBLIGATORIO: utilizza @container style(--property: value) per applicare stili condizionali agli elementi discendenti. Le query sugli stili non possono corrispondere all'elemento su cui è impostata la proprietà, ma solo ai relativi discendenti.
  4. SÌ: preferisci le query di stile ai selettori discendenti quando la relazione deve rimanere estensibile o superare i confini dei componenti/del DOM shadow (vedi Scegliere lo strumento giusto sopra), ma mantieni i selettori discendenti per le relazioni fisse e una tantum in cui l'indirezione non offre alcun vantaggio.

Esempio di implementazione

/* 1. Set the context on a layout container */
.featured {
  --surface: featured; /* Semantic context flag for children */
}

/* 2. Component reacts to inherited flag */
.button {
  /* Default: Outlined informational style */
  background: transparent;
  border: 1px solid currentColor;
}

.badge {
  /* Default: Hidden — only revealed in featured surfaces */
  display: none;
}

@container style(--surface: featured) {
  .button {
    /* Automatic switch to Filled promotional style */
    background: var(--brand-accent);
    color: white;
    border: none;
  }

  .badge {
    /* Reveal decorative elements only in featured context */
    display: block;
  }
}

Strategie di fallback

Finché le query di stile dei container non saranno ampiamente disponibili, aggiungile come potenziamento progressivo: fornisci un valore predefinito basato su selettore che funzioni ovunque e consenti alla query di stile di eseguirne l'override quando supportata. Utilizza :where() nel selettore di contesto in modo che la query di stile (stessa specificità, più avanti nell'ordine di origine) vinca automaticamente.

/* Default styles — work everywhere */
.button {
  background: transparent;
  border: 1px solid currentColor;
}

.badge {
  display: none;
}

/* Selector-based contextual styles — broad browser support */
:where(.featured) .button {
  background: var(--brand-accent);
  color: white;
  border: none;
}

:where(.featured) .badge {
  display: block;
}

/* Progressive enhancement: style queries override when supported */
@container style(--surface: featured) {
  .button {
    background: var(--brand-accent);
    color: white;
    border: none;
  }

  .badge {
    display: block;
  }
}

Il selettore di riserva associa lo stile contestuale a un nome di classe, che accoppia il componente alla sua posizione nel DOM. Una volta che le query di stile saranno ampiamente supportate, la regola :where() potrà essere rimossa.