Met CSS-containerquery's kunt u stijlen toepassen op basis van de containergrootte van de component in plaats van op de volledige viewport.

Lange tijd waren mediaquery's de enige manier om UI-ontwerpen responsief te maken op verschillende schermformaten. Maar zelfs dat had zijn beperkingen. Een van de grootste problemen bij het gebruik van mediaquery's was dat je een element alleen kon stylen als reactie op veranderingen in de schermgrootte, niet het dichtstbijzijnde containerelement.

Om dit probleem op te lossen, zijn containerquery's geïntroduceerd. Ze zijn ook enorm gestegen met de populariteit van frameworks zoals React en Vue.js die werken door modulaire UI-"componenten" te creëren. Leer hoe u containerquery's kunt gebruiken om responsieve elementen in uw CSS te maken.

De code die in dit artikel wordt gebruikt, is hierin beschikbaar GitHub-opslagplaats en is gratis voor u om te gebruiken onder de MIT-licentie.

Waarom zou u CSS-containerquery's gebruiken?

Laten we, om het belang van containerquery's te begrijpen, een voorbeeld gebruiken dat het concept gemakkelijker maakt. Maar eerst moet u hieruit de startercode klonen

GitHub-opslagplaats.

Nadat u de repo met succes hebt gekloond, voert u de code uit. U vindt een webpagina die lijkt op de volgende afbeelding:

Hier heb je een rasterlay-out bestaande uit twee kolommen: het hoofdgedeelte en de zijbalk. Het hoofdgedeelte ziet er goed uit, maar de zijbalk (die veel kleiner is dan de hoofdinhoud) ziet er een beetje geplet uit.

De lay-out is responsief. Wanneer u de browser verkleint, kunt u zien dat de kaart verandert in een verticale kolom:

Met andere woorden, wanneer de inhoud onleesbaar begint te worden, verandert de lay-out in een verticale kolom waar de afbeelding bovenop de inhoud wordt gestapeld. Dit effect is het resultaat van de mediaquery's, wat de enige manier is waarop u de grootte van elementen kunt bepalen op basis van de volledige grootte van uw scherm.

In dit geval, wanneer uw scherm kleiner is dan 800px, stapelt u alles op elkaar met behulp van Flexbox uitlijning. Op grotere schermen plaatsen we de content naast elkaar:

@media(Maximale wijdte: 800px) {
.kaart {
flex-richting: kolom;
}
.card-header {
breedte: 100%;
}
}

Mediavragen zijn al heel lang een van de belangrijkste principes van webdesign voor het maken van responsieve lay-outs met CSS (en het is voor de meeste dingen goed genoeg geweest). Maar u zult ongetwijfeld scenario's tegenkomen waarin mediaquery's niet voldoende zijn, of in ieder geval geen handige oplossing zijn.

Een van die scenario's is wanneer u een zijbalk heeft (zoals in het bovenstaande voorbeeld). In deze gevallen waarin u een zijbalk heeft, moet u de zijbalkkaart rechtstreeks selecteren en proberen deze kleiner te maken:

.zijbalk.kaart {
/* Maak de zijbalkkaart kleiner */
}

@media(Maximale wijdte: 800px) {
/* Stijl de pagina wanneer het scherm smaller is dan 800px */
}

Het kan behoorlijk ingewikkeld zijn als u met veel elementen werkt, omdat u alle elementen handmatig moet selecteren en de grootte ervan moet aanpassen. Je zou eindigen met meer code en extra complexiteit.

Dit is waar containerquery's nuttig kunnen zijn. In plaats van gedwongen te worden om uw viewport als maat te gebruiken, kunt u elk element op uw pagina als container gebruiken. Dan kan die container zijn eigen breedtes hebben waarop u uw mediaquery's zou baseren.

Een containerquery maken

Als u een containerquery wilt maken, richt u zich eerst op het element dat u als container wilt gebruiken (in dit geval het hoofdgedeelte en de zijbalk). Binnen het blok moet je de instellen container-type naar inline-formaat:

voornaamst, .zijbalk {
container-type: inline-formaat
}

Wanneer u uw CSS-bestand opslaat, verandert er niets aan de pagina. Maar nu kunt u containerquery's gebruiken om de kaarten die zijn genest in het hoofdgedeelte en het zijbalkgedeelte, te vergroten of verkleinen en te restylen. In de volgende containerquery wijzigt u de kaarten in verticale kolommen op schermen van 500 px breed of minder:

@container(Maximale wijdte: 500px) {
.kaart {
flex-richting: kolom;
}
.card-header {
breedte: 100%;
}
}

Dit gaat werken als een normale mediaquery. Maar in plaats van de grootte van uw scherm te meten, meet u de grootte van uw containers (hoofd- en zijbalksecties). Dus als uw container nu 500px of meer is, gebruikt u de horizontale weergave. Anders gebruik je verticaal (standaard voor flexbox).

Uit de bovenstaande afbeelding kunt u zien dat de zijbalk een verticale vorm heeft omdat deze kleiner is dan 500px. Terwijl de hoofdinhoud zijn horizontale lay-out behoudt omdat deze groter is dan 500px. Als u uw browser verkleint, gebruiken uw zijbalk en hoofdinhoud beide de verticale uitlijning wanneer ze 500px of minder bereiken.

De containerquery is ongelooflijk krachtig omdat u hiermee het formaat van dingen kunt wijzigen op basis van de container in plaats van de volledige breedte van de browser. Dit is vooral handig bij het omgaan met componenten (zoals in React of Vue).

Met containerquery's kunt u eenvoudig de grootte van uw UI-componenten wijzigen op basis van hun container, zodat u volledig op zichzelf staande componenten kunt maken.

Containers benoemen

Wanneer u een @container query, zoekt het eerst naar de container van het element waarop u zich richt binnen de query. In ons geval zou dit de hoofdcontainer en de zijbalkcontainer zijn.

En zelfs als de kaarten in een andere container zaten, zou het de andere containers gewoon negeren en alleen de dichtstbijzijnde container kiezen. Dit maakt deel uit van een breder CSS-concept bekend als CSS-kiezers.

In het volgende voorbeeld hebben we het body-element omgezet in een container:

lichaam {
container-type: inline-formaat;
}

Nu hebben we drie aparte containers: body, main en side section. Standaard bevinden de kaarten waarop we ons richten in de containerquery zich dichter bij het hoofdgedeelte of de zijbalk dan bij de hoofdtekst. Het gebruikt dus de hoofd- en zijbalksecties als containers voor de containerquery.

Om dit gedrag op te heffen, moet u twee dingen doen. Eerst moet u uw body-element een containernaam geven:

lichaam {
container-type: inline-formaat;
containernaam: lichaam;
}

Wanneer u vervolgens uw containerquery maakt, moet u daarna de containernaam opgeven @container.

@container lichaam (Maximale wijdte:1000px){
/* CSS-regels die gericht zijn op de body-container */
}

Dit is handig als u een specifiek element als container wilt gebruiken in plaats van de container die het dichtst bij het element staat waarop u zich richt. Met andere woorden, u kunt elke specifieke container selecteren en uw lay-out verfijnen.

Containereenheden

Een andere leuke functie van containers is dat u containereenheden kunt gebruiken. Deze eenheden werken net als viewport-eenheden (ze zijn allemaal exact hetzelfde type eenheden). Containereenheden gebruiken echter cq (voor het instellen van de breedte) en cq (voor het instellen van de hoogte). Deze eenheden bepalen de exacte breedte en hoogte van uw container.

Met CSS-containerquery's kunt u specifieke elementen gebruiken als referentiepunten voor uw mediaquery's. Deze techniek is best handig voor het maken van modulaire, op zichzelf staande elementen die onafhankelijk kunnen staan, ongeacht de container waarin ze zich bevinden. Maar containerquery's gebruiken dezelfde principes als mediaquery's, en dit is iets dat u onder de knie moet krijgen als u een CSS-ontwikkelaar van één procent wilt zijn.