CSS Container Size Queries (in Norwegian)

Webutviklere har forespurt container queries i snart 10 år, og nå er de endelig her! For øyeblikket kan vi kun kjøre queries på størrelse (size
). Og per idag (05.10.2022) er det kun Chrome 106 og Safari 16 som har støtte.
Can I Use har den beste oversikten over hvilke nettlesere som støtter hva til en hver tid.
Hva er en “container query”? #
Med container queries kan vi nå spørre ett enkelt element om en rekke verdier og egenskaper, og sette bestemte CSS regler basert på det. Dette blir kalt en container kontekst. I denne artikkelen vil jeg kun fokusere på inline-size
egenskapen, siden det er den eneste som har støtte i nettlesere nå.
Dersom du er vant med CSS Grid eller Flexbox, så vil du kanskje kjenne igjen kontekst konseptet med at HTML elementer sin layout blir bestemt på foreldre-elementet, som i display: flex
og display: grid
.
Lag en container #
For en container size query, så er de magiske ordene:
container-type: inline-size;
OBS! Se opp for artikler hvor contain blir brukt. Det er basert på tidligere versjoner av utkastet for container queries, da parameteret contain ble brukt.
Referer til en container #
Dette gjøres veldig likt hvordan vi bruker media queries, men istedenfor å måle bredden på selve nettleseren, kan vi nå måle bredden på et HTML element.
Ved å kun måle bredden på elementet, kan det samme elementet ha forskjellig layout og stil avhengig av hvor god plass det har på siden.

Hvilken container?! #
Hvordan vet CSS og nettleseren hvilken container den skal måle og sette kontekst ut ifra?
- Med media queries så er det hele nettleser vinduet.
- Med CSS Grid og Flexbox så er det det første, direkte, foreldre-elementet.
- Med container queries så er det nærmeste foreldre-elementet med en
container-type
. Det trenger altså ikke å være en 1-generasjons.

Eksempel #
Her er et eksempel på et card komponent:
<div class="card">
<div class="card__media">…</div>
<div class="card__content">…</div>
</div>
Når vi skal bruke container queries så trenger vi å legge til ett “wrapper” element. Dette er fordi vi kan kun sette stiler på element som er inni foreldreelementet. Så dersom vi ønsker å sette stil til selve .card elementet, trenger det en forelder.
<div class="card-wrapper">
<!-- Legg til wrapper -->
<div class="card">
<div class="card__media">…</div>
<div class="card__content">…</div>
</div>
</div>
Sette stil #
Og nå kan vi kose oss med CSS!
.card-wrapper {
container-type: inline-size; /* Sett kontekst */
}
/* Standard layout */
.card { … }
.card__media { … }
.card__content { … }
/* Design når .cardwrapper er over 480px bred */
@container (min-width: 480px) {
.card { … }
.card__media { … }
.card__content { … }
}
Når vi skriver @container
queries, så er det tilnærmet identisk med å skrive @media
queries. Men vi må huske å også fortelle nettleseren hvilket element som er containeren, som vi gjør ved å spesifisere container-type: inline-size
på den CSS klassen.
Valgfritt: container-name
#
Det er også mulig å gi containeren ett navn, og det navnet kan refereres til fra en container query. Dette kan være greit når det blir mange queries å holde orden i, eller at det er nøstet langt nedi hierarkiet.
Med konteksten på plass, så kan vi skrive queries som ser ut som vanlige media-queries. Men istedenfor å sjekke bredden på nettleseren, så sjekker den bredden på elementet med klassen .container
i dette eksemplet.
Så kan vi skrive @container
queryet som tidligere, men med navnet på containeren som ett ekstra parameter.
.wrapper {
container-type: inline-size;
container-name: sidebar; /* Legg til navn */
}
.card {
display: grid;
grid-template-columns: 1fr;
}
/* Se etter container med navn "sidebar" */
@container sidebar (min-width: 400px) {
.card {
grid-template-columns: 2fr 1fr;
}
}
Når skal jeg bruke container? #
Mye av det container queries gjør kan løses med Flexbox og CSS Grid. Men layout og kolonner er ikke det eneste som container query lar oss endre. Vi kan også inkludere andre design element, for eksempel:
- Visuell tyngde. Vi kan endre hvor visuelt uthevet et område er avhengig av hvor på siden det er plassert.
- Typografi. Gir enda mer kontroll enn vi allerede har med fleksibel/flytende typografi triks.
- Skjul, vis og endre elementer avhengig av størrelse, som f.eks. deler av en header med mye innhold.
- Endre bilde størrelser og aspect ratio.
Fordeler for oss utviklere #
Vi er vant med å bruke modifier klasser (”M” i BEM) for å gi et komponent forskjellige uttrykk. Nå har vi muligheten til å la størrelsen på komponentet gjøre det samme. Vi slipper å bruke JavaScript løsninger for å dynamisk legge til og trekke fra klasser i body
og andre steder.
Demonstrasjon #
NB! Dette virker kun i Chrome 106 og Safari 16 og oppover.
CodePen #
Det er best å åpne live kodeeksemplet direkte i CodePen: https://codepen.io/eystein/pen/wvjGejM
See the Pen Container size queries by Eystein Mack Alnaes (@eystein) on CodePen.
Skjermbilde #
Samme komponent, samme HTML, samme CSS, i 3 forskjellige format.

Video #
Videoen viser hvordan breakpoints i to container queries gir forskjellige design på et komponent, uten å endre bredden på nettleseren. I videoen viser jeg tre ting:
- Endrer størrelsen på det nederste komponentet, som veksler mellom de 3 designene.
- Legger til 2 komponenter i rad to, som tilpasser seg den nye størrelsen.
- Sletter 1 komponent fra den øverste raden, som tilpasser seg den nye størrelsen.
Oppsummering #
- Bruk Chrome 106 eller Safari 16 og oppover.
- Sett
container-type: inline-size;
egenskapen på foreldre-elementet. - Skriv CSS endringene i en query:
@container (min-width: 480px) {…}