Een paar keer zoeken naar containergroottes zou me geholpen hebben PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Een paar keer vragen over de containergrootte zouden me hebben geholpen

CSS-containerquery's winnen nog steeds aan populariteit en velen van ons maken er natte handen van, ook al is het voor kleine experimenten of wat dan ook. Ze hebben geweldig, maar niet helemaal vol, browser ondersteuning - genoeg om het gebruik ervan in sommige projecten te rechtvaardigen, maar misschien niet in die mate dat we in de verleiding komen om te beginnen met vervangen mediaquery's van eerdere projecten met glimmende nieuwe zoekopdrachten voor containergroottes.

Maar handig zijn ze zeker! Ik ben zelfs al een paar situaties tegengekomen waarin ik ze echt wilde bereiken, maar de ondersteuningsvereisten gewoon niet kon overwinnen. Als ik ze had kunnen gebruiken, zou het er in die situaties zo hebben uitgezien.

Alle volgende demo's kunnen op het moment van schrijven het beste worden bekeken in Chrome of Safari. Firefox is van plan om schip ondersteuning in versie 109.

Geval 1: Kaartraster

Deze had je toch wel verwacht? Het is zo'n algemeen patroon dat we er allemaal op een gegeven moment tegenaan lijken te lopen. Maar feit is dat query's op containerformaat voor mij een enorme tijdbesparing zouden hebben opgeleverd met een beter resultaat als ik ze had kunnen gebruiken in plaats van standaard mediaquery's.

Laten we zeggen dat je de opdracht hebt gekregen om dit kaartraster te bouwen met de vereiste dat elke kaart zijn beeldverhouding van 1:1 moet behouden:

Een paar keer vragen over de containergrootte zouden me hebben geholpen

Het is moeilijker dan het lijkt! Het probleem is dat het aanpassen van de inhoud van een component aan de breedte van de viewport je overlaat aan hoe de component reageert op de viewport - en ook aan de manier waarop alle andere voorouderlijke containers erop reageren. Als u bijvoorbeeld de lettergrootte van een kaartkop wilt verkleinen wanneer de kaart een bepaalde inline-grootte bereikt, is er geen betrouwbare manier om dit te doen.

Je zou de lettergrootte kunnen instellen vw eenheden, neem ik aan, maar de component is nog steeds gebonden aan de viewport-breedte van de browser. En dat kan problemen veroorzaken wanneer het kaartraster anders wordt gebruikt in contexten die mogelijk niet dezelfde breekpunten hebben.

In mijn real-world project kwam ik terecht op een JavaScript-benadering die:

  1. Luister naar een resize-gebeurtenis.
  2. Bereken de breedte van elke kaart.
  3. Voeg een inline lettergrootte toe aan elke kaart op basis van de breedte.
  4. Style alles van binnen met behulp van em units.

Lijkt me veel werk, toch? Maar het is een stabiele oplossing om de vereiste schaling over verschillende schermformaten in verschillende contexten te krijgen.

Containerquery's zouden zoveel beter zijn geweest omdat ze ons voorzien van containerquery-eenheden, zoals de cqw eenheid. Je snapt het waarschijnlijk al, maar 1cqw is gelijk aan 1% van de breedte van een container. We hebben ook de cqi eenheid die een maat is voor de inline-breedte van een container, en cqb voor de blokbreedte van een container. Dus als we een kaartenbak hebben, tenminste 500px breed, een 50cqw waarde berekent naar 250px.

Als ik containerquery's in mijn kaartraster had kunnen gebruiken, had ik de .card component als container:

.card { 
  container: card / size;
}

Dan had ik er een binnenverpakking mee kunnen zetten padding dat schaalt op 10% van de .card's breedte met behulp van de cqw eenheid:

.card__inner { 
  padding: 10cqw; 
} 

Dat is een leuke manier om de afstand tussen de randen van de kaart en de inhoud consistent te schalen, ongeacht waar de kaart wordt gebruikt bij een bepaalde viewport-breedte. Geen mediaquery's vereist!

Een ander idee? Gebruiken cqw eenheden voor de lettergrootte van de interne inhoud en pas vervolgens opvulling toe em units:

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

5cqw is een willekeurige waarde - slechts een die ik heb gekozen. Die opvulling is nog steeds gelijk aan 10cqw omdat de em eenheid is relatief ten opzichte van de .card__inner lettertypegrootte!

Heb je dat opgevangen? De 2em is relatief ten opzichte van de 5cqw lettergrootte die is ingesteld op dezelfde houder. Containers werken anders dan we gewend zijn em eenheden zijn relatief ten opzichte van dezelfde elementen font-size value. Maar wat me al snel opviel, is dat containerquery-eenheden betrekking hebben op de dichtstbijzijnde ouder die ook een container is.

Bijvoorbeeld 5cqw schaalt niet op basis van de .card breedte van het element in dit voorbeeld:

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

In plaats daarvan schaalt het naar de dichtstbijzijnde ouder die is gedefinieerd als een container. Daarom heb ik een .card__inner wikkel.

Geval 2: Afwisselende lay-out

Ik had nog een ander kaartonderdeel nodig in een ander project. Deze keer had ik de kaart nodig om over te gaan van een liggende lay-out naar een staande lay-out... dan weer terug naar liggend en weer terug naar staand als het scherm kleiner wordt.

Toont vier statussen van een kaartelement die wisselen tussen staande en liggende lay-outs op verschillende breekpunten.
Een paar keer vragen over de containergrootte zouden me hebben geholpen

Ik heb het vuile werk gedaan om dit onderdeel naar portret te laten gaan op die twee specifieke kijkvensterbereiken (roep naar de syntaxis van het nieuwe mediaquerybereik!), maar nogmaals, het probleem is dat het vervolgens wordt vergrendeld op de mediaquery's die erop zijn ingesteld, de ouder en al het andere dat zou kunnen reageren op de breedte van de viewport. We willen iets dat onder alle omstandigheden werkt zonder dat we ons zorgen hoeven te maken over waar de inhoud kapot gaat!

Containerquery's zouden dit een fluitje van een cent hebben gemaakt, dankzij de @container regel:

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

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

Eén vraag, oneindige vloeibaarheid:

Maar wacht even! Er is iets waar je misschien op wilt letten. Het kan met name moeilijk zijn om een ​​dergelijke containerquery te gebruiken binnen een op props gebaseerd ontwerpsysteem. Bijvoorbeeld dit .info-card component kan onderliggende componenten bevatten die afhankelijk zijn van rekwisieten om hun uiterlijk te veranderen.

Waarom is dat erg? De staande lay-out van de kaart kan de alternatieve stijl vereisen, maar u kunt JavaScript-props niet wijzigen met CSS. Als zodanig loop je het risico de vereiste stijlen te dupliceren. Ik heb dit eigenlijk aangeraakt en hoe je dit kunt omzeilen in een ander artikel. Als u voor een aanzienlijk deel van uw styling containerquery's moet gebruiken, moet u uw hele ontwerpsysteem misschien daarop baseren in plaats van te proberen ze in een bestaand ontwerpsysteem te verwerken dat veel mediaquery's bevat.

Geval 3: SVG-streken

Hier is nog een veelvoorkomend patroon dat ik onlangs heb gebruikt, waarbij zoekopdrachten naar de containergrootte zouden hebben geresulteerd in een meer gepolijst product. Stel dat u een pictogram hebt opgesloten met een kop:

Heading

Het is vrij eenvoudig om het pictogram te schalen met de grootte van de titel, zelfs zonder mediaquery's. Het probleem is echter dat de SVG's stroke-width kan te dun worden om goed opgemerkt te worden bij een kleiner formaat, en misschien te veel aandacht trekken met een superdikke streek bij een groter formaat.

Ik heb klassen moeten maken en toepassen op elke pictograminstantie om de grootte en lijndikte te bepalen. Dat is OK als het pictogram naast een kop staat die is opgemaakt met een vaste lettergrootte, denk ik, maar het is niet zo geweldig als je werkt met een vloeiend type dat voortdurend verandert.

Een lock-up van een zeshoekig pictogram en een kop in drie verschillende formaten, van groot tot klein.
Een paar keer vragen over de containergrootte zouden me hebben geholpen

De lettergrootte van de kop kan zijn gebaseerd op de breedte van de viewport, dus het SVG-pictogram moet dienovereenkomstig worden aangepast waar de lijn op elke grootte werkt. U kunt de lijndikte relatief maken ten opzichte van de koppen font-size door het in te stellen em eenheden. Maar als je een specifieke reeks slaggroottes hebt waar je je aan moet houden, dan zou dit niet werken omdat het anders lineair schaalt - er is geen manier om het aan te passen aan een specifiek stroke-width waarde op bepaalde punten zonder toevlucht te nemen tot mediaquery's op de breedte van de viewport.

Maar dit is wat ik zou hebben gedaan als ik op dat moment de luxe had gehad van containervragen:

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

Vergelijk de implementaties en kijk hoe de versie van de containerquery de lijn van het SVG-bestand vastzet op de specifieke breedte die ik wil op basis van de breedte van de container.

Bonus: andere soorten vragen over containergrootte

OK, dus ik ben dit niet echt tegengekomen bij een echt project. Maar toen ik informatie over containerquery's doorzocht, merkte ik dat er nog meer dingen zijn die we op een container kunnen opvragen die verband houden met de grootte of fysieke afmetingen van de container.

De meeste voorbeelden die ik heb gezien vragen de width, max-width en min-width, height, block-size en inline-size zoals ik in dit artikel heb gedaan.

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

Maar MDN schetst nog twee dingen we kunnen vragen tegen. Een is orientation wat volkomen logisch is omdat we het de hele tijd gebruiken in mediaquery's. Het is niet anders met containerquery's:

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

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

De andere? Zijn aspect-ratio, geloof het of niet:

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

Hier is een bewerkbare demo om met beide voorbeelden te spelen:

Ik heb nog niet echt een goede use case voor een van deze gevonden. Als je ideeën hebt of het gevoel hebt dat het je had kunnen helpen bij je projecten, laat het me dan weten in de reacties!

Tijdstempel:

Meer van CSS-trucs