Alcune volte le query sulle dimensioni del contenitore mi avrebbero aiutato a realizzare la data intelligence di PlatoBlockchain. Ricerca verticale. Ai.

Alcune volte le query sulle dimensioni del contenitore mi avrebbero aiutato

Le CSS Container Queries stanno ancora guadagnando terreno e molti di noi si stanno bagnando le mani con esse, anche se è per piccoli esperimenti o altro. Hanno grandi, ma non del tutto pieno, supporto del browser - abbastanza da giustificare il loro utilizzo in alcuni progetti, ma forse non nella misura in cui potremmo essere tentati di iniziare a sostituirli query multimediali media da progetti passati con nuove brillanti query sulla dimensione del contenitore.

Sicuramente sono utili però! In effetti, mi sono già imbattuto in alcune situazioni in cui volevo davvero raggiungerli ma non sono riuscito a superare i requisiti di supporto. Se avessi potuto usarli, ecco come sarebbe apparso in quelle situazioni.

Tutte le seguenti demo saranno visualizzate al meglio in Chrome o Safari al momento della stesura di questo documento. Firefox prevede di supporto della nave nella versione 109.

Caso 1: griglia di carte

Dovevi aspettartelo, vero? È uno schema così comune che tutti noi sembriamo imbatterci ad un certo punto. Ma il fatto è che le query sulle dimensioni del contenitore mi avrebbero fatto risparmiare molto tempo con un risultato migliore se fossi stato in grado di utilizzarle rispetto alle query multimediali standard.

Diciamo che ti è stato assegnato il compito di costruire questa griglia di carte con il requisito che ogni carta deve mantenere le sue proporzioni 1:1:

Alcune volte le query sulle dimensioni del contenitore mi avrebbero aiutato

È più dura di quanto sembri! Il problema è che il dimensionamento dei contenuti di un componente sulla larghezza del viewport ti lascia in balia di come il componente risponde al viewport, così come il modo in cui qualsiasi altro contenitore antenato risponde ad esso. Se, ad esempio, desideri che la dimensione del carattere dell'intestazione di una carta si riduca quando la carta raggiunge una certa dimensione in linea, non esiste un modo affidabile per farlo.

È possibile impostare la dimensione del carattere in vw unità, suppongo, ma il componente è ancora legato alla larghezza del viewport del browser. E ciò può causare problemi quando la griglia della scheda viene utilizzata in altri contesti che potrebbero non avere gli stessi punti di interruzione.

Nel mio progetto del mondo reale, sono approdato a un approccio JavaScript che avrebbe:

  1. Ascolta un evento di ridimensionamento.
  2. Calcola la larghezza di ogni carta.
  3. Aggiungi una dimensione del carattere in linea a ogni carta in base alla sua larghezza.
  4. Modella tutto all'interno usando em unità.

Sembra un sacco di lavoro, vero? Ma è una soluzione stabile per ottenere il ridimensionamento richiesto su schermi di dimensioni diverse in contesti diversi.

Le query sui contenitori sarebbero state molto migliori perché ci forniscono unità di query del contenitore, come il cqw unità. Probabilmente l'hai già capito, ma 1cqw è uguale a 1% della larghezza di un contenitore. Abbiamo anche il cqi unità che è una misura della larghezza in linea di un contenitore e cqb per la larghezza del blocco di un contenitore. Quindi, se abbiamo un contenitore di carte che è 500px largo, A 50cqw valore calcola a 250px.

Se fossi stato in grado di utilizzare le query del contenitore nella griglia della mia carta, avrei potuto impostare il file .card componente come contenitore:

.card { 
  container: card / size;
}

Quindi avrei potuto impostare un involucro interno con padding che scala a 10% della .card's width usando il cqw Unità:

.card__inner { 
  padding: 10cqw; 
} 

Questo è un bel modo per ridimensionare la spaziatura tra i bordi della scheda e il suo contenuto in modo coerente, indipendentemente da dove viene utilizzata la scheda a una determinata larghezza della finestra. Nessuna media query richiesta!

Un'altra idea? Uso cqw unità per la dimensione del carattere dei contenuti interni, quindi applicare il riempimento em unità:

.card__inner { 
  font-size: 5cqw; 
  padding: 2em;
} 

5cqw è un valore arbitrario, solo uno su cui ho deciso. Quella imbottitura è ancora uguale a 10cqw poiché l' em l'unità è relativa a .card__inner dimensione del font!

L'hai preso? Il 2em è relativo a 5cqw dimensione del carattere impostata sullo stesso contenitore. I contenitori funzionano in modo diverso da quello a cui siamo abituati, come em le unità sono relative a quelle dello stesso elemento font-size value. Ma quello che ho subito notato è che le unità di query del contenitore si riferiscono a il genitore più vicino che è anche un contenitore.

Per esempio, 5cqw non scala in base al .card la larghezza dell'elemento in questo esempio:

.card { 
  container: card / size; 
  container-name: card; 
  font-size: 5cqw; 
}

Piuttosto, si ridimensiona in base al genitore più vicino definito come contenitore. Ecco perché ho creato un .card__inner involucro.

Caso 2: layout alternato

Avevo bisogno di un altro componente della carta in un progetto diverso. Questa volta, avevo bisogno che la carta passasse da un layout orizzontale a un layout verticale... quindi di nuovo in orizzontale e di nuovo in verticale man mano che lo schermo si rimpiccioliva.

Mostra quattro stati di un elemento della carta che cambia tra layout verticale e orizzontale in vari punti di interruzione.
Alcune volte le query sulle dimensioni del contenitore mi avrebbero aiutato

Ho fatto il lavoro sporco di fare in modo che questo componente andasse in verticale in quei due specifici intervalli di viewport (grida al nuova sintassi dell'intervallo di media query!), ma ancora una volta, il problema è che viene quindi bloccato alle media query impostate su di esso, sul suo genitore e su qualsiasi altra cosa che potrebbe rispondere alla larghezza del viewport. Vogliamo qualcosa che funzioni in qualsiasi condizione senza preoccuparci di chiederci dove si romperà il contenuto!

Le query sui contenitori lo avrebbero reso un gioco da ragazzi, grazie al @container regola:

.info-card {
  container-type: inline-size;
  container-name: info-card;
}

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

Una domanda, fluidità infinita:

Ma aspetta! C'è qualcosa a cui dovresti stare attento. Nello specifico, potrebbe essere difficile utilizzare una query contenitore come questa all'interno di un sistema di progettazione basato su oggetti di scena. Ad esempio, questo .info-card component potrebbe contenere componenti figlio che si basano su oggetti di scena per modificare il proprio aspetto.

Perché è un grosso problema? Il layout verticale della carta potrebbe richiedere uno stile alternativo, ma non puoi modificare gli oggetti di scena JavaScript con i CSS. Pertanto, rischi di duplicare gli stili richiesti. In realtà ho toccato questo e come aggirare il problema in un altro articolo. Se è necessario utilizzare le query contenitore per una quantità significativa del proprio stile, potrebbe essere necessario basare l'intero sistema di progettazione su di esse piuttosto che provare a inserirle in un sistema di progettazione esistente che è pesante sulle query multimediali.

Caso 3: colpi SVG

Ecco un altro modello super comune che ho utilizzato di recente in cui le query sulle dimensioni del contenitore avrebbero prodotto un prodotto più raffinato. Supponi di avere un'icona bloccata con un'intestazione:

Heading

È abbastanza semplice ridimensionare l'icona con le dimensioni del titolo, anche senza query multimediali. Il problema, però, è che i file SVG stroke-width potrebbe diventare troppo sottile per essere notato così bene a una dimensione più piccola, e forse attirare troppa attenzione con un tratto super spesso a una dimensione più grande.

Ho dovuto creare e applicare classi a ciascuna istanza di icona per determinarne le dimensioni e la larghezza del tratto. Va bene se l'icona è accanto a un'intestazione con uno stile con una dimensione del carattere fissa, immagino, ma non è così eccezionale quando si lavora con un tipo fluido che cambia costantemente.

Un blocco di un'icona esagonale e un'intestazione di tre diverse dimensioni, da grande a piccola.
Alcune volte le query sulle dimensioni del contenitore mi avrebbero aiutato

La dimensione del carattere dell'intestazione potrebbe essere basata sulla larghezza del viewport, quindi l'icona SVG deve essere regolata di conseguenza dove il suo tratto funziona a qualsiasi dimensione. Potresti rendere la larghezza del tratto relativa all'intestazione font-size inserendolo em unità. Ma se hai un set specifico di dimensioni del tratto a cui devi attenerti, allora questo non funzionerebbe perché altrimenti si ridimensiona linearmente - non c'è modo di adattarlo a uno specifico stroke-width valore in determinati punti senza ricorrere a media query sulla larghezza del viewport.

Ma ecco cosa avrei fatto se avessi avuto il lusso delle query sui contenitori in quel momento:

.icon {
  container: icon / size; 
  width: 1em; 
  height: 1em; 
}

.icon svg {
  width: 100%; 
  height: 100%; 
  fill: none; 
  stroke: #ccc; 
  stroke-width: 0.8; 
}

@container icon (max-width: 70px) {
  .icon svg {
    stroke-width: 1.5; 
  }
}
@container icon (max-width: 35px) {
  .icon svg {
    stroke-width: 3;
  }
}

Confronta le implementazioni e osserva come la versione della query del contenitore aggancia il tratto dell'SVG alle larghezze specifiche che desidero in base alla larghezza del contenitore.

Bonus: altri tipi di query sulla dimensione del contenitore

OK, quindi in realtà non mi sono imbattuto in questo in un vero progetto. Ma mentre stavo esaminando le informazioni sulle query del contenitore, ho notato che ci sono altre cose che possiamo interrogare su un contenitore che sono correlate alle dimensioni del contenitore o alle dimensioni fisiche.

La maggior parte degli esempi che ho visto interrogare il file width, max-widthe min-width, height, block-sizee inline-size come ho fatto in questo articolo.

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

Ma MDN delinea altre due cose possiamo interrogare contro. Uno è orientation il che ha perfettamente senso perché lo usiamo sempre nelle query multimediali. Non è diverso con le query sui contenitori:

@media screen (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

@container info-card (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

L'altro? È aspect-ratio, credici o no:

@container info-card (aspect-ratio: 3/2) { 
  .info-card__inner {
    /* Style away! */
  }
} 

Ecco una demo modificabile per giocare con entrambi gli esempi:

Non ho ancora trovato un buon caso d'uso per nessuno di questi ancora. Se hai qualche idea o ritieni che possa averti aiutato nei tuoi progetti, fammelo sapere nei commenti!

Timestamp:

Di più da Trucchi CSS