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.
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
enmin-width: 300px
). - Bereikquery's (
200px < width < 400px
enwidth < 400px
). - Container relatieve lengte-eenheden (
cqw
,cqh
,cqi
,cqb
,cqmin
encqmax
) 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 van
@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
enem
worden ondersteund in queryvoorwaarden. - Uitgebreide syntaxis van containerquery's:
- Syntaxis van bereik (bijvoorbeeld
(200px < width < 400px)
). - Gelijkheidsquery's (bijvoorbeeld
(width = 200px)
).
- Syntaxis van bereik (bijvoorbeeld
- Pseudo-elementen zoals
::before
en::after
. - Browsers zonder
:is(...)
/:where(...)
worden ondersteund via een optionele oplossing - De
orientation
enaspect-ratio
functiequery's. - Query's correct filteren op basis van kenmerken (bijvoorbeeld
height
van de query opcontainer: 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 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
encqh
) 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
enstyle
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 eencontainer-type: inline-size
waarschijnlijk zal veranderen na het evalueren van een query, maarResizeObserver
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
:where()
oplossing is vereist voor de 2,23% gebruikers van browsers ouder dan:- Safari 14
- Chroom 88
- Rand 88
- Samsung Internet 15
- Firefox 78