Guida introduttiva alle query Stili

Una Kravets
Una Kravets

La possibilità di eseguire query sulle dimensioni in linea di un elemento padre e sui valori delle unità di query del container di recente ha raggiunto un supporto stabile in tutti i motori dei browser moderni.

Supporto dei browser

  • 105
  • 105
  • 110
  • 16

Fonte

Tuttavia, la specifica di contenimento non include solo query sulle dimensioni e consente anche di eseguire query sui valori di stile di un elemento padre. A partire dalla versione 111 di Chromium, potrai applicare il contenimento degli stili per i valori delle proprietà personalizzate ed eseguire query su un elemento principale per ottenere il valore di una proprietà personalizzata.

Supporto dei browser

  • 111
  • 111
  • x
  • x

Fonte

Ciò significa che abbiamo un controllo ancora più logico degli stili in CSS e consente una migliore separazione della logica e del livello dati di un'applicazione dai suoi stili.

La specifica di livello 3 del modulo di contenimento CSS, che copre le query su dimensioni e stile, consente di eseguire query su qualsiasi stile da un elemento padre, incluse coppie di proprietà e valori come font-weight: 800. Tuttavia, nell'implementazione di questa funzionalità, al momento le query di stile funzionano solo con i valori delle proprietà personalizzate CSS. Questa opzione è ancora molto utile per combinare gli stili e separare i dati dalla progettazione. Diamo un'occhiata a come utilizzare le query di stile con le proprietà personalizzate CSS:

Introduzione alle query di stile

Supponiamo di avere il seguente codice HTML:

<ul class="card-list">
  <li class="card-container">
    <div class="card">
      ...
    </div>
  </li>
</ul>

Per utilizzare le query di stile, devi prima impostare un elemento contenitore. Ciò richiede un approccio leggermente diverso a seconda del fatto che tu stia eseguendo una query su un elemento padre diretto o indiretto.

Esecuzione di query con i genitori diretti

Diagramma di una query di stile.

A differenza delle query di stile, non è necessario applicare il contenimento utilizzando la proprietà container-type o container a .card-container per consentire a .card di eseguire query sugli stili dell'elemento principale diretto. Tuttavia, dobbiamo applicare gli stili (in questo caso i valori delle proprietà personalizzate) a un contenitore (.card-container in questo caso) o a qualsiasi elemento contenente l'elemento a cui abbiamo assegnato lo stile nel DOM. Non possiamo applicare gli stili a cui eseguiamo query sull'elemento diretto a cui stiamo definendo gli stili utilizzando la query perché ciò potrebbe causare loop infiniti.

Per eseguire una query direttamente su un elemento padre, puoi scrivere:

/* styling .card based on the value of --theme on .card-container */
@container style(--theme: warm) {
  .card {
    background-color: wheat;
    border-color: brown; 
    ...
  }
}

Potresti aver notato che la query di stile inserisce style() nella query. per distinguere i valori delle dimensioni dagli stili. Ad esempio, puoi scrivere una query per la larghezza del container come @container (min-width: 200px) { … }. Lo stile viene applicato se il contenitore principale è largo almeno 200 px. Tuttavia, min-width può anche essere una proprietà CSS e puoi eseguire query sul valore CSS di min-width utilizzando query di stile. Ecco perché dovresti utilizzare il wrapper style() per chiarire la differenza: @container style(min-width: 200px) { … }.

Stile dei genitori non diretti

Se vuoi eseguire query sugli stili per qualsiasi elemento che non è un elemento principale diretto, devi assegnare un container-name all'elemento. Ad esempio, possiamo applicare gli stili a .card in base agli stili di .card-list assegnando un valore container-name a .card-list e facendo riferimento alla query relativa allo stile.

/* styling .card based on the value of --moreGlobalVar on .card-list */
@container cards style(--moreGlobalVar: value) {
  .card {
    ...
  }
}

È generalmente consigliabile assegnare un nome ai container per chiarire quali sono le query e avere più facilmente la possibilità di accedervi. Ad esempio, puoi sfruttare questa funzionalità se vuoi applicare uno stile agli elementi direttamente in .card. Senza un container denominato su .card-container, non è possibile eseguire una query diretta.

Ma tutto questo ha molto più senso nella pratica. Vediamo alcuni esempi:

Applicare uno stile alle query

Immagine demo con più schede di prodotto, alcune con tag &#39;nuovo&#39; o &#39;disponibilità ridotta&#39; e la scheda &#39;disponibilità ridotta&#39; su sfondo rosso.

Le query di stile sono particolarmente utili quando disponi di un componente riutilizzabile con più varianti o quando non hai il controllo su tutti gli stili, ma in alcuni casi devi applicare modifiche. Questo esempio mostra un insieme di schede di prodotto che condividono lo stesso componente della scheda. Alcune schede di prodotto presentano dettagli/note aggiuntivi, come "Novità" o "Disponibilità in esaurimento", attivati da una proprietà personalizzata denominata --detail. Inoltre, se un prodotto è in "Disponibilità in esaurimento", assume un bordo rosso scuro. È probabile che questo tipo di informazioni venga visualizzato sul server e possa essere applicato alle schede tramite stili incorporati, ad esempio:

 <div class="product-list">
  <div class="product-card-container" style="--detail: new">
    <div class="product-card">
      <div class="media">
        <img .../>
      <div class="comment-block"></div>
    </div>
  </div>
  <div class="meta">
    ...
  </div>
  </div>
  <div class="product-card-container" style="--detail: low-stock">
    ...
  </div>
  <div class="product-card-container">
    ...
  </div>
  ...
</div>

Dati questi dati strutturati, puoi trasmettere i valori a --detail e utilizzare questa proprietà personalizzata CSS per applicare gli stili:

@container style(--detail: new) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'New';
    border: 1px solid currentColor;
    background: white;
    ...
  }
}

@container style(--detail: low-stock) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'Low Stock';
    border: 1px solid currentColor;
    background: white;
    ...
  }
  
  .media-img {
    border: 2px solid brickred;
  }
}

Il codice riportato sopra ci consente di applicare un chip per --detail: low-stock e --detail: new, ma potresti aver notato una certa ridondanza nel blocco di codice. Al momento, non è possibile eseguire query solo per la presenza di --detail con @container style(--detail), il che consentirebbe una migliore condivisione degli stili e meno ripetizioni. Questa funzionalità è attualmente in discussione nel gruppo di lavoro.

Schede meteo

L'esempio precedente utilizzava un'unica proprietà personalizzata con più valori possibili per applicare gli stili. Tuttavia, puoi eseguire query per eseguire query per più proprietà personalizzate. Prendiamo l'esempio di questa scheda meteo:

Demo schede meteo.

Per applicare uno stile alle icone e ai gradienti di sfondo di queste schede, cerca le caratteristiche del tempo, ad esempio "nuvoloso", "piovoso" o "soleggiato":

@container style(--sunny: true) {
  .weather-card {
    background: linear-gradient(-30deg, yellow, orange);
  }
  
  .weather-card:after {
    content: url(<data-uri-for-demo-brevity>);
    background: gold;
  }
}

In questo modo, puoi modificare lo stile di ogni scheda in base alle sue caratteristiche uniche. Tuttavia, puoi anche definire lo stile per le combinazioni di caratteristiche (proprietà personalizzata), utilizzando il combinatore and come per le query supporti. Ad esempio, una giornata sia nuvoloso che soleggiata avrebbe il seguente aspetto:

@container style(--sunny: true) and style(--cloudy: true) {
    .weather-card {
      background: linear-gradient(24deg, pink, violet);
    }
  
  .weather-card:after {
      content: url(<data-uri-for-demo-brevity>);
      background: violet;
  }
}

Separazione dei dati dalla progettazione

In entrambe le demo, c'è un vantaggio strutturale di separare il livello dati (DOM che verrebbe visualizzato nella pagina) dagli stili applicati. Gli stili sono scritti come possibili varianti che risiedono all'interno dello stile dei componenti, mentre un endpoint potrebbe inviare i dati in base a cui utilizzare per definire lo stile del componente. Puoi utilizzare un solo valore, ad esempio nel primo caso, aggiornare il valore --detail oppure più variabili, come nel secondo caso (impostando --rainy, --cloudy o --sunny. E la parte migliore è che puoi anche combinare questi valori, il controllo di --sunny e --cloudy potrebbe mostrare uno stile parzialmente nuvoloso.

L'aggiornamento dei valori delle proprietà personalizzate tramite JavaScript può essere eseguito senza problemi durante la configurazione del modello DOM (ovvero durante la creazione del componente in un framework) oppure puoi aggiornarlo in qualsiasi momento utilizzando <parentElem>.style.setProperty('--myProperty’, <value>). I

Ecco una demo che, in poche righe di codice, aggiorna il --theme di un pulsante e applica gli stili utilizzando query di stile e quella proprietà personalizzata (--theme):

Definisci la scheda utilizzando query di stile. Il codice JavaScript utilizzato per aggiornare i valori delle proprietà personalizzate è:

const themePicker = document.querySelector('#theme-picker')
const btnParent = document.querySelector('.btn-section');

themePicker.addEventListener('input', (e) => {
  btnParent.style.setProperty('--theme', e.target.value);
})

Le funzionalità descritte in questo articolo sono solo l'inizio. Puoi aspettarti di più dalle query container per creare interfacce dinamiche e adattabili. Per quanto riguarda le query di stile in particolare, ci sono ancora alcuni problemi irrisolti. Uno è l'implementazione di query di stile per gli stili CSS al di là delle proprietà personalizzate. Questa funzionalità fa già parte del livello di specifica attuale, ma non è ancora implementata in nessun browser. La valutazione del contesto booleano dovrebbe essere aggiunta al livello della specifica corrente quando il problema in sospeso sarà risolto, mentre le query sull'intervallo sono pianificate per il livello successivo della specifica.