Ett par gånger förfrågningar om containerstorlek skulle ha hjälpt mig med PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Ett par gånger förfrågningar om containerstorlek skulle ha hjälpt mig

CSS Container Queries vinner fortfarande dragkraft och många av oss blir blöta av dem, även om det är för små experiment eller vad inte. De är jättebra, men inte riktigt fulla, webbläsarsupport — tillräckligt för att motivera att använda dem i vissa projekt, men kanske inte i den utsträckningen att vi kan frestas att börja ersätta mediafrågor från tidigare projekt med skinande nya frågor om containerstorlek.

Fast de är säkert praktiska! Jag har faktiskt redan stött på några situationer där jag verkligen ville nå dem men bara inte kunde övervinna supportkraven. Om jag hade kunnat använda dem så hade det sett ut så här i de situationerna.

Alla följande demos visas bäst i Chrome eller Safari när detta skrivs. Firefox planerar att fartygsstöd i version 109.

Fall 1: Kortrutnät

Du var väl tvungen att förvänta dig den här? Det är ett så vanligt mönster att vi alla verkar stöta på det någon gång. Men faktum är att frågor om behållarestorlek skulle ha varit en enorm tidsbesparande för mig med ett bättre resultat om jag hade kunnat använda dem över vanliga mediefrågor.

Låt oss säga att du har fått i uppdrag att bygga det här kortrutnätet med kravet att varje kort måste behålla sitt bildförhållande 1:1:

Ett par gånger förfrågningar om containerstorlek skulle ha hjälpt mig

Det är tuffare än det ser ut! Problemet är att storleken på en komponents innehåll på visningsportens bredd överlåter dig på nåd av hur komponenten svarar på visningsporten – liksom hur andra förfaderbehållare reagerar på den. Om du till exempel vill att teckenstorleken på en kortrubrik ska minska när kortet träffar en viss inlinestorlek finns det inget tillförlitligt sätt att göra det.

Du kan ställa in teckenstorleken vw enheter, antar jag, men komponenten är fortfarande bunden till webbläsarens visningsportbredd. Och det kan orsaka problem när kortrutnätet används på annat sätt i sammanhang som kanske inte har samma brytpunkter.

I mitt verkliga projekt landade jag på en JavaScript-metod som skulle:

  1. Lyssna efter en händelse som ändrar storlek.
  2. Beräkna bredden på varje kort.
  3. Lägg till en inline teckenstorlek till varje kort baserat på dess bredd.
  4. Style allt inuti med hjälp av em enheter.

Det verkar vara mycket jobb, eller hur? Men det är en stabil lösning för att få den skalning som krävs över olika skärmstorlekar i olika sammanhang.

Containerförfrågningar skulle ha varit så mycket bättre eftersom de ger oss containerfrågeenheter, så som cqw enhet. Du förstår förmodligen redan, men 1cqw är lika med 1% av en containers bredd. Vi har också cqi enhet som är ett mått på en containers inline bredd, och cqb för en containers blockbredd. Så, om vi har en kortbehållare alltså 500px bred, a 50cqw värde beräknas till 250px.

Om jag hade kunnat använda containerfrågor i mitt kortrutnät hade jag kunnat ställa in .card komponent som en behållare:

.card { 
  container: card / size;
}

Då hade jag kunnat sätta ett inre omslag med padding som skalar på 10% av .card's bredd med hjälp av cqw enhet:

.card__inner { 
  padding: 10cqw; 
} 

Det är ett bra sätt att skala avståndet mellan kortets kanter och dess innehåll konsekvent oavsett var kortet används vid en given visningsportbredd. Inga mediafrågor krävs!

En annan idé? Använda sig av cqw enheter för teckenstorleken på det inre innehållet, applicera sedan utfyllnad em enheter:

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

5cqw är ett godtyckligt värde - bara ett som jag nöjt mig med. Den stoppningen är fortfarande lika med 10cqw eftersom em enhet är i förhållande till .card__inner textstorlek!

Har du fattat det? De 2em är relativt till 5cqw teckenstorlek som är inställd på samma behållare. Containers fungerar annorlunda än vad vi är vana vid, som em enheter är relativa till samma elements font-size value. Men vad jag snabbt märkte är att containerfrågeenheter relaterar till närmaste förälder som också är en container.

Till exempel, 5cqw skalas inte baserat på .card elementets bredd i detta exempel:

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

Snarare skalas den till den närmaste föräldern som definieras som en behållare. Det är därför jag satte upp en .card__inner omslag.

Fall 2: Alternerande layout

Jag behövde ännu en kortkomponent i ett annat projekt. Den här gången behövde jag kortet för att övergå från en liggande layout till en stående layout... sedan tillbaka till liggande och tillbaka till stående igen när skärmen blir mindre.

Visar fyra tillstånd för ett kortelement som växlar mellan stående och liggande layouter vid olika brytpunkter.
Ett par gånger förfrågningar om containerstorlek skulle ha hjälpt mig

Jag gjorde det smutsiga arbetet med att få den här komponenten att gå till stående vid de två specifika visningsområdena (ropa ut till ny syntax för mediafrågeintervall!), men återigen, problemet är att det sedan är låst till mediefrågorna som ställts in på det, dess förälder och allt annat som kan svara på visningsportens bredd. Vi vill ha något som fungerar i alla skick utan att oroa oss för att undra var innehållet kommer att gå sönder!

Containerförfrågningar skulle ha gjort detta till en lek, tack vare @container regel:

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

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

En fråga, oändlig flytbarhet:

Men håll ut! Det finns något du kanske vill se upp med. Specifikt kan det vara svårt att använda en containerfråga som denna inom ett rekvisitabaserat designsystem. Till exempel detta .info-card komponent kan innehålla underordnade komponenter som är beroende av rekvisita för att ändra sitt utseende.

Varför är det en stor grej? Kortets stående layout kan kräva den alternativa stilen men du kan inte ändra JavaScript-rekvisita med CSS. Som sådan riskerar du att duplicera de nödvändiga stilarna. Jag berörde faktiskt detta och hur man kan kringgå det i en annan artikel. Om du behöver använda containerförfrågningar för en betydande del av din styling, kan du behöva basera hela ditt designsystem kring dem istället för att försöka lägga in dem i ett befintligt designsystem som är tungt på mediefrågor.

Fall 3: SVG-slag

Här är ett annat supervanligt mönster jag nyligen har använt där frågor om behållarestorlek skulle ha resulterat i en mer polerad produkt. Säg att du har en ikon låst med en rubrik:

Heading

Det är ganska enkelt att skala ikonen med titelns storlek, även utan mediefrågor. Problemet är dock att SVG:erna stroke-width kan bli för tunn för att uppmärksammas så väl i en mindre storlek, och kanske fånga för mycket uppmärksamhet med ett supertjockt slag i en större storlek.

Jag har varit tvungen att skapa och tillämpa klasser på varje ikoninstans för att bestämma dess storlek och streckbredd. Det är OK om ikonen är bredvid en rubrik som har en fast teckenstorlek, antar jag, men det är inte så bra när man arbetar med flytande typ som ständigt ändras.

En låsning av en hexagonikon och rubrik i tre olika storlekar, från stor till liten.
Ett par gånger förfrågningar om containerstorlek skulle ha hjälpt mig

Rubrikens teckensnittsstorlek kan baseras på visningsportens bredd, så SVG-ikonen måste anpassas efter var dess linje fungerar oavsett storlek. Du kan göra slagbredden i förhållande till rubrikens font-size genom att sätta in den em enheter. Men om du har en specifik uppsättning slagstorlekar som du behöver hålla dig till, så skulle det här inte fungera eftersom det annars skalas linjärt - det finns inget sätt att justera det till en specifik stroke-width värde vid vissa punkter utan att tillgripa mediefrågor på visningsportens bredd.

Men här är vad jag skulle ha gjort om jag hade lyxen med containerfrågor vid den tiden:

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

Jämför implementeringarna och se hur behållarfrågaversionen fäster SVG:s linje till de specifika bredderna jag vill ha baserat på behållarens bredd.

Bonus: Andra typer av frågor om containerstorlek

OK, så jag har faktiskt inte stött på det här på ett riktigt projekt. Men när jag letade igenom information om containerförfrågningar, märkte jag att det finns ytterligare saker vi kan fråga på en container som är relaterade till containerns storlek eller fysiska dimensioner.

De flesta exempel jag har sett frågar efter width, max-widthoch min-width, height, block-sizeoch inline-size som jag har gjort genom hela den här artikeln.

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

Men MDN beskriver ytterligare två saker vi kan fråga mot. En är orientation vilket är helt vettigt eftersom vi använder det hela tiden i mediefrågor. Det är inte annorlunda med containerfrågor:

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

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

Den andra? Dess aspect-ratio, tro det eller ej:

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

Här är en redigerbar demo att leka med båda exemplen:

Jag har inte riktigt hittat ett bra användningsfall för någon av dessa än. Om du har några idéer eller känner att det kunde ha hjälpt dig i dina projekt, låt mig veta i kommentarerna!

Tidsstämpel:

Mer från CSS-tricks