Containerquery's beginnen in stabiele browsers terecht te komen, terwijl de polyfill een grote update krijgt

Containervragen zijn hier!

Spannend nieuws: een van de meest gevraagde ontwikkelaarsfuncties is nu in webbrowsers terechtgekomen! Vanaf Chromium 105 en Safari 16 kunt u in deze browsers nu op grootte gebaseerde containerquery's maken en eenheidswaarden voor containerquery's gebruiken. Om het nog eenvoudiger te maken om op grootte gebaseerde containerquery's en cq -eenheden te gebruiken, heeft het Aurora-team bij Chrome hard gewerkt aan het updaten van de Container Query Polyfill om meer browsers en gebruiksscenario's te ondersteunen, zodat u deze krachtige functie vandaag met vertrouwen kunt gebruiken.

Wat zijn containerquery's?

Containerquery's zijn een CSS-functie waarmee u stijllogica kunt schrijven die zich richt op kenmerken van een ouderelement om de onderliggende elementen op te maken. U kunt een echt op componenten gebaseerd responsief ontwerp maken door de grootte van een ouder op te vragen. Dit is veel gedetailleerdere en nuttigere informatie dan zoiets als mediaquery's die alleen informatie over de grootte van de viewport verschaffen.

ALT_TEXT_HIER

Met containerquery's kunt u herbruikbare componenten schrijven die er anders kunnen uitzien, afhankelijk van waar ze zich op de pagina bevinden. Dit maakt ze veel veerkrachtiger en responsiever op alle pagina's en sjablonen.

Containerquery's gebruiken

Stel dat je wat HTML hebt:

<!-- card parent -->
<div class=”card-parent”>
  <div class=”card>
     <!-- card contents -->
      …
  </div>
</div>

Als u een containerquery wilt gebruiken, moet u eerst de inperking instellen op het bovenliggende element dat u wilt bijhouden. Doe dit door de container-type eigenschap in te stellen, of door de container steno te gebruiken om tegelijkertijd het containertype en de containernaam in te stellen.

.card-parent {
  /* query the inline-direction size of this parent */
  container-type: inline-size;
}

Nu kunt u de @container -regel gebruiken om stijlen in te stellen op basis van de dichtstbijzijnde ouder. Voor een ontwerp zoals de afbeelding hierboven, waarbij een kaart van één kolom naar twee kolommen kan gaan, schrijft u zoiets als:

@container (min-width: 300px) {
  .card {
    /* styles to apply when the card container (.card-parent in this case) is >= 300px */
    /* I.e. shift from 1-column to 2-column layout: */
    grid-template-columns: 1fr 1fr;
  }
}

Om het netter en explicieter te maken, geeft u de container van het bovenliggende element een naam:

.card-parent {
  container-type: inline-size;
  /* set name here, or write this in one line using the container shorthand */
  container-name: card-container;
}

Herschrijf vervolgens de vorige code als:

@container card-container (min-width: 300px) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}

Containerquery-eenheden

Om containerquery's nog nuttiger te maken, kunt u ook op containers gebaseerde eenheidswaarden gebruiken. De volgende tabel toont de mogelijke waarden voor containereenheden en hoe deze overeenkomen met de grootte van een container:

eenheid ten opzichte van
cqw 1% van de breedte van een querycontainer
cqh 1% van de hoogte van een querycontainer
cqi 1% van de inlinegrootte van een querycontainer
cqb 1% van de blokgrootte van een querycontainer
cqmin De kleinere waarde van cqi of cqb
cqmax De grotere waarde van cqi of cqb

Een voorbeeld van hoe u op containers gebaseerde eenheden zou gebruiken, is responsieve typografie. De op viewport gebaseerde eenheden (zoals vh , vb , vw en vi ) kunnen worden gebruikt om de grootte van elk element op het scherm te bepalen.

.card h2 {
  font-size: 15cqi;
}

Deze code zorgt ervoor dat de lettergrootte 15% van de inlinegrootte van de container bedraagt, wat betekent dat deze groter wordt naarmate de inlinegrootte (breedte) groter wordt, of kleiner naarmate deze kleiner wordt. Om nog verder te gaan, gebruikt u de functie clamp() om uw typografie een minimum- en maximumgroottelimiet te geven, en deze responsief te rangschikken op basis van de containergrootte:

.card h2 {
  font-size: clamp(1.5rem, 15cqi, 3rem);
}

Nu zal de header nooit groter worden dan 3rem of kleiner dan .5rem maar er zal ergens tussenin 15% van de inline-grootte van de container nodig zijn.

Deze demo gaat nog een stap verder en werkt de bredere kaarten bij zodat ze een kleiner formaatbereik hebben, aangezien ze in een weergave met twee kolommen worden weergegeven.

De polyfill van de containerquery

Omdat containerquery's zo'n krachtige functie zijn, willen we dat u zich op uw gemak voelt bij het opnemen ervan in uw projecten, en dat u weet dat browserondersteuning daar een groot deel van uitmaakt. Daarom hebben we gewerkt aan verbeteringen aan de Container Query Polyfill . Deze polyfill heeft algemene ondersteuning bij:

  • Firefox 69+
  • Chroom 79+
  • Rand 79+
  • Safari 13.4+

Het is minder dan 9 kb groot wanneer het wordt gecomprimeerd, en gebruikt ResizeObserver met MutationObserver om de volledige @container-querysyntaxis te ondersteunen die momenteel beschikbaar is in stabiele browsers:

  • Discrete zoekopdrachten ( width: 300px en min-width: 300px ).
  • Bereikquery's ( 200px < width < 400px en width < 400px ).
  • Container relatieve lengte-eenheden ( cqw , cqh , cqi , cqb , cqmin en cqmax ) in eigenschappen en sleutelframes.

Met behulp van de polyfill van de containerquery

Om de polyfill te gebruiken, voegt u deze scripttag toe aan de kop van uw document::

<script type="module">
  if (!("container" in document.documentElement.style)) {
    import("https://unpkg.com/container-query-polyfill@^0.2.0");
  }
</script>

Mogelijk wilt u ook een service gebruiken om de polyfill voorwaardelijk te leveren op basis van User-Agent , of deze zelf hosten op uw eigen oorsprong.

Voor de beste gebruikerservaring wordt aanbevolen dat u de polyfill in eerste instantie alleen gebruikt voor inhoud onder de vouw en @supports query's gebruikt om deze tijdelijk te vervangen door een laadindicator totdat de polyfill klaar is om deze weer te geven:

@supports not (container-type: inline-size) {
  .container,
  footer {
    display: none;
  }

  .loader {
    display: flex;
  }
}

Op voldoende snelle netwerken en apparaten, of apparaten die standaard containerquery's ondersteunen, wordt deze laadindicator nooit weergegeven.

Nieuwe Polyfill-functies

De bijgewerkte polyfill ondersteunt:

  • Geneste @container regels.
  • Het nesten @container regels onder @supports en @media -query's en vice versa wordt ondersteund.
  • Voorwaardelijke CSS zoals @supports (container-type: inline-size) wordt doorgegeven nadat de polyfill is geladen.
  • Volledige CSS-syntaxisondersteuning (er is geen enkel probleem meer met het plaatsen van opmerkingen waar ze syntactisch geldig zijn).
  • Verticale schrijfmodi (via schrijfmodus).
  • Container Relative Units ( cqw , cqh , etc) worden ondersteund binnen queryvoorwaarden, eigenschapsdeclaraties en animatiehoofdframes. rem en em worden ondersteund in queryvoorwaarden.
  • Uitgebreide syntaxis van containerquery's:
    • Syntaxis van bereik (bijvoorbeeld (200px < width < 400px) ).
    • Gelijkheidsquery's (bijvoorbeeld (width = 200px) ).
  • Pseudo-elementen zoals ::before en ::after .
  • Browsers zonder :is(...) / :where(...) worden ondersteund via een optionele oplossing
  • De orientation en aspect-ratio functiequery's.
  • Query's correct filteren op basis van kenmerken (bijvoorbeeld height van de query op container: inline-size is correct niet toegestaan ​​bij een horizontale schrijfmodus).
  • DOM-mutatie (bijvoorbeeld <style> en <link> -elementen die tijdens runtime worden verwijderd).

Beperkingen en waarschuwingen voor polyfill

Als u de polyfill voor containerquery's gebruikt, zijn er enkele ontbrekende functies waar u op moet letten:

  • De Shadow DOM wordt nog niet ondersteund.
  • Container relatieve eenheden (bijvoorbeeld cqw en cqh ) worden niet ondersteund in @media queryvoorwaarden.
    • Safari: Container Relative Units worden niet ondersteund in animatiehoofdframes vóór 15.4.
  • calc() , min() , max() of andere wiskundige functies worden nog niet ondersteund in queryvoorwaarden.
  • Deze polyfill werkt alleen met inline en CSS van dezelfde oorsprong. Cross-origin stylesheets en stylesheets in iframes (tenzij een polyfill handmatig wordt geladen) worden niet ondersteund.
  • layout en style vereist onderliggende browserondersteuning:
    • Safari 15.4+
    • Firefox ondersteunt momenteel geen stijlbeperking, maar werkt eraan.

Waarschuwingen

  • Om impact op FID en CLS te voorkomen, geeft de polyfill geen garanties over wanneer de eerste lay-out zal plaatsvinden, zelfs als deze synchroon wordt geladen, behalve dat hij zal proberen onredelijke vertraging van LCP te voorkomen. Met andere woorden, u moet er nooit op vertrouwen voor de eerste verfbeurt.
  • Genereert ResizeObserver Loop Errors . De originele polyfill doet dit ook, maar het is de moeite waard om te noemen. Dit gebeurt omdat de blokgrootte van een container-type: inline-size waarschijnlijk zal veranderen na het evalueren van een query, maar ResizeObserver kan op geen enkele manier vertellen dat veranderingen in de blokgrootte ons niet interesseren.
  • Deze polyfill is getest aan de hand van webplatformtests en heeft een slagingspercentage van 70% bereikt, aangezien bepaalde functies, zoals JavaScript-API's, niet polyfill zijn, en het slagingspercentage dus opzettelijk dichter bij de 70% ligt.
  • De oplossing :where() is vereist voor de 2,23% gebruikers van browsers ouder dan:
    • Safari 14
    • Chroom 88
    • Rand 88
    • Samsung Internet 15
    • Firefox 78