De câteva ori interogări privind dimensiunea containerului m-ar fi ajutat să descopăr PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

De câteva ori interogări privind dimensiunea containerului m-ar fi ajutat

Interogările de containere CSS încă câștigă acțiune și mulți dintre noi ne udă mâinile cu ele, chiar dacă este pentru mici experimente sau altceva. Au fost grozave, dar nu chiar pline, suport pentru browser — suficient pentru a justifica folosirea lor în unele proiecte, dar poate nu în măsura în care am putea fi tentați să începem să înlocuim interogări media din proiectele anterioare cu noi interogări strălucitoare privind dimensiunea containerului.

Cu siguranță sunt totuși la îndemână! De fapt, m-am confruntat deja cu câteva situații în care îmi doream foarte mult să ajung la ele, dar pur și simplu nu puteam depăși cerințele de asistență. Dacă aș fi putut să le folosesc, așa ar fi arătat în acele situații.

Toate demonstrațiile următoare vor fi vizualizate cel mai bine în Chrome sau Safari în momentul scrierii acestui articol. Firefox intenționează să sprijinul navei în versiunea 109.

Cazul 1: Grila cardului

Trebuia să te aștepți la asta, nu? Este un tipar atât de comun încât toți parcă ne întâlnim cu el la un moment dat. Dar adevărul este că interogările de dimensiunea containerului ar fi fost o economie imensă de timp pentru mine, cu un rezultat mai bun dacă aș fi putut să le folosesc peste interogări media standard.

Să presupunem că ați fost însărcinat să construiți această grilă de carduri cu cerința pe care fiecare card are nevoie pentru a-și păstra raportul de aspect 1:1:

De câteva ori interogări privind dimensiunea containerului m-ar fi ajutat

E mai dur decât pare! Problema este că dimensionarea conținutului unei componente pe lățimea ferestrei de vizualizare vă lasă la mila modului în care componenta răspunde la fereastra - precum și a modului în care orice alte containere strămoși răspund la acesta. Dacă, de exemplu, doriți ca dimensiunea fontului unui titlu de card să se reducă atunci când cardul atinge o anumită dimensiune în linie, nu există nicio modalitate fiabilă de a face acest lucru.

Puteți seta dimensiunea fontului în vw unități, presupun, dar componenta este încă legată de lățimea ferestrei de vizualizare a browserului. Și asta poate cauza probleme atunci când grila cardului este utilizată în alte contexte în care este posibil să nu aibă aceleași puncte de întrerupere.

În proiectul meu din lumea reală, am ajuns la o abordare JavaScript care ar:

  1. Ascultați un eveniment de redimensionare.
  2. Calculați lățimea fiecărei cărți.
  3. Adăugați o dimensiune de font în linie la fiecare card în funcție de lățimea acestuia.
  4. Modelați totul în interior folosind em de unități.

Pare multă muncă, nu? Dar este o soluție stabilă pentru a obține scalarea necesară pe diferite dimensiuni de ecran în diferite contexte.

Interogările de containere ar fi fost mult mai bune pentru că ne oferă unități de interogare container, la fel ca cqw unitate. Probabil că îl înțelegi deja, dar 1cqw este egal cu 1% de lăţimea unui container. Avem și cqi unitate care este o măsură a lățimii în linie a unui container și cqb pentru lățimea blocului unui container. Deci, dacă avem un container pentru carduri, acesta este 500px lat, a 50cqw valoarea se calculează la 250px.

Dacă aș fi putut folosi interogări de container în grila cardului, aș fi putut configura .card componentă ca container:

.card { 
  container: card / size;
}

Atunci aș fi putut pune un înveliș interior cu padding care scala la 10% a .cardlățimea lui folosind cqw unitate:

.card__inner { 
  padding: 10cqw; 
} 

Acesta este un mod frumos de a scala distanța dintre marginile cardului și conținutul acestuia în mod constant, indiferent de locul în care cardul este utilizat la orice lățime dată de vizualizare. Nu sunt necesare interogări media!

O altă idee? Utilizare cqw unități pentru dimensiunea fontului conținutului interior, apoi aplicați umplutură em Unități:

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

5cqw este o valoare arbitrară - doar una pe care am stabilit-o. Căptușeala este încă egală cu 10cqw din moment ce em unitatea este relativă la .card__inner marimea fontului!

Ai prins asta? The 2em este relativ la 5cqw dimensiunea fontului care este setată pe același recipient. Containerele funcționează diferit de ceea ce ne-am obișnuit, ca em unitățile sunt relativ la aceleași elemente font-size value. Dar ceea ce am observat rapid este că se referă unitățile de interogare a containerelor cel mai apropiat părinte care este și container.

De exemplu, 5cqw nu scala pe baza .card lățimea elementului în acest exemplu:

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

Mai degrabă, se extinde la orice părinte cel mai apropiat care este definit ca un container. De aceea am înființat un .card__inner împachetare.

Cazul 2: Aspect alternativ

Aveam nevoie de încă o componentă de card într-un proiect diferit. De data aceasta, aveam nevoie de card pentru a trece de la un aspect peisaj la un aspect portret... apoi înapoi la peisaj și din nou la portret pe măsură ce ecranul devine mai mic.

Afișează patru stări ale unui element de card care se schimbă între aspectul portret și peisaj la diferite puncte de întrerupere.
De câteva ori interogări privind dimensiunea containerului m-ar fi ajutat

Am făcut treaba murdară de a face ca această componentă să treacă la portret la acele două intervale specifice de vizualizare (strigă sintaxă a intervalului de interogare media nouă!), dar din nou, problema este că este apoi blocat la interogările media setate pe el, părintele său și orice altceva care ar putea răspunde la lățimea ferestrei de vizualizare. Ne dorim ceva care să funcționeze în orice condiție, fără a ne îngrijora să ne întrebăm unde se va sparge conținutul!

Interogările privind containerele ar fi făcut acest lucru o briză, datorită @container regulă:

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

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

O singură interogare, fluiditate infinită:

Dar stai! Este ceva la care ai putea dori să fii atent. Mai exact, ar putea fi dificil să utilizați o interogare de container ca aceasta într-un sistem de proiectare bazat pe suport. De exemplu, aceasta .info-card componenta ar putea conține componente secundare care se bazează pe recuzită pentru a-și schimba aspectul.

De ce e mare lucru? Aspectul portret al cardului poate necesita stilul alternativ, dar nu puteți schimba elementele de recuzită JavaScript cu CSS. Ca atare, riscați să duplicați stilurile necesare. De fapt m-am atins de asta și cum să o rezolvi într-un alt articol. Dacă trebuie să utilizați interogări container pentru o parte semnificativă a stilului dvs., atunci poate fi necesar să vă bazați întregul sistem de design în jurul lor, mai degrabă decât să încercați să le încadrați într-un sistem de design existent, care este greu de interogări media.

Cazul 3: lovituri SVG

Iată un alt model foarte comun pe care l-am folosit recent, în cazul în care interogările privind dimensiunea containerului ar fi dus la un produs mai lustruit. Să presupunem că aveți o pictogramă blocată cu un titlu:

Heading

Este destul de simplu să scalați pictograma cu dimensiunea titlului, chiar și fără interogări media. Problema, însă, este că SVG-urile stroke-width ar putea deveni prea subțire pentru a fi observat atât de bine la o dimensiune mai mică și poate atrage prea multă atenție cu o lovitură super groasă la o dimensiune mai mare.

A trebuit să creez și să aplic clase pentru fiecare instanță de pictogramă pentru a-i determina dimensiunea și lățimea trazei. Este în regulă dacă pictograma este lângă un titlu care are un stil cu o dimensiune fixă ​​a fontului, cred, dar nu este atât de grozav când lucrezi cu tipul fluid care se schimbă constant.

Un bloc al unei pictograme hexagon și un titlu la trei dimensiuni diferite, de la mare la mic.
De câteva ori interogări privind dimensiunea containerului m-ar fi ajutat

Dimensiunea fontului titlului se poate baza pe lățimea ferestrei de vizualizare, așa că pictograma SVG trebuie să se ajusteze în consecință unde funcționează cursa sa la orice dimensiune. Puteți face lățimea cursei în raport cu cea a titlului font-size punându-l în interior em unitati. Dar dacă aveți un anumit set de dimensiuni ale cursei de care trebuie să respectați, atunci acest lucru nu ar funcționa, deoarece altfel se scalează liniar - nu există nicio modalitate de a-l ajusta la un anumit stroke-width valoare în anumite puncte fără a recurge la interogări media pe lățimea ferestrei de vizualizare.

Dar iată ce aș fi făcut dacă aș fi avut luxul de interogări de container la acel moment:

.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;
  }
}

Comparați implementările și vedeți cum versiunea de interogare a containerului fixează cursa SVG-ului la lățimile specifice pe care le doresc, în funcție de lățimea containerului.

Bonus: alte tipuri de interogări privind dimensiunea containerului

OK, deci nu m-am întâlnit cu asta într-un proiect real. Dar, în timp ce căutam informații despre interogările containerului, am observat că există lucruri suplimentare pe care le putem interoga pe un container care sunt legate de dimensiunea sau dimensiunile fizice ale containerului.

Cele mai multe exemple pe care le-am văzut interogă width, max-width, și min-width, height, block-size, și inline-size așa cum am făcut pe parcursul acestui articol.

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

dar MDN subliniază încă două lucruri putem interoga împotriva. Unul este orientation ceea ce are perfect sens pentru că îl folosim tot timpul în interogări media. Nu este diferit cu interogările container:

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

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

Celălalt? este aspect-ratio, crezi sau nu:

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

Iată o demonstrație editabilă pentru a te juca cu ambele exemple:

Nu am găsit încă un caz de utilizare bun pentru niciunul dintre acestea. Dacă ai idei sau simți că te-ar fi putut ajuta în proiectele tale, spune-mi în comentarii!

Timestamp-ul:

Mai mult de la CSS Trucuri