Waarom je cards ineens onder elkaar vallen

Je levert een trainingsopdracht in met een header, een rij “kaartjes” en een knop (“Start training”). Op desktop ziet het er oké uit, maar zodra het scherm smaller wordt, breekt alles: kaartjes schuiven half weg, tekst wordt te smal, en de header lijkt twee regels “rommel”. Dit is typisch het moment waarop je voelt: “Ik kan CSS stylen, maar ik kan het nog niet betrouwbaar laten meeschalen.”

Dit onderwerp is nu belangrijk omdat layout de plek is waar eerdere keuzes samenkomen: je box model bepaalt hoe groot elementen zijn, typografie bepaalt hoeveel ruimte tekst nodig heeft, en selectors/specificity bepalen welke regels werkelijk winnen. Flexbox is dan de eerste praktische stap naar: voorspelbare rijen, nette uitlijning, en een basis voor responsive gedrag zonder meteen ingewikkelde systemen te bouwen.

Vandaag leer je de flexbox-basis waarmee je de meeste training-layouts (nav, knoppen, card-rijen) strak en schaalbaar krijgt.

Flexbox in mensentaal: container, items en “vrije ruimte”

Flexbox is een layoutmethode voor het verdelen en uitlijnen van ruimte in een richting (meestal een rij of kolom). Het werkt met twee rollen:

  • Flex container: het element met display: flex;

  • Flex items: de directe children van die container

Belangrijke termen:

  • Main axis: de richting waarin items achter elkaar staan (standaard horizontaal).

  • Cross axis: de richting er loodrecht op (standaard verticaal).

  • Free space: ruimte die overblijft (of tekort) nadat de basisbreedtes zijn bepaald.

Flexbox is ideaal voor UI-patronen uit trainingsopdrachten: navigatiebalken, knoppen naast elkaar, icon + tekst, en card-rijen. Je gebruikt het niet om “random te schuiven”, maar om regels te formuleren: hoe items verdelen, waar ze uitlijnen, en wat er gebeurt bij weinig ruimte.

De koppeling met eerdere lessen is direct:

  • Box model: padding/border tellen mee in de afmetingen; met box-sizing: border-box; wordt flex-layout veel voorspelbaarder.

  • Specificity: flex-regels staan vaak op component-classes (.header, .cards, .card); als een element “niet flex’t”, is er vaak een specifieker rule die display of width overschrijft.

De kerninstellingen die 80% van je layout oplossen

1) display: flex en de keuze: rij of kolom

Zodra je display: flex; op een container zet, worden de children flex-items. Standaard staan die in een rij (flex-direction: row). Dat is perfect voor een header met links naast elkaar, maar kan fout aanvoelen bij content die onder elkaar hoort.

Met flex-direction maak je de intentie expliciet:

  • row: items naast elkaar (nav links, knop + icoon)

  • column: items onder elkaar (verticale menu’s, stacked UI op mobiel)

In training-layouts zie je vaak een misvatting: “flexbox is voor horizontale dingen”. In werkelijkheid is flexbox voor 1-dimensionale verdeling, dus ook voor kolommen. Het voordeel van expliciet kiezen is dat je responsive makkelijker maakt: op desktop row, op mobiel column, zonder je HTML te veranderen.

Een typische valkuil is dat je display: flex op het verkeerde element zet. Alleen de directe children worden flex-items. Als jouw kaartjes in een extra wrapper zitten, en je zet flex op main in plaats van op .cards, gebeurt er “niets” met je kaartjes. Debug dan door in DevTools te checken: welke container is flex? welke elementen zijn de items?

2) Uitlijnen: justify-content vs align-items

Flexbox geeft je twee hoofdknoppen voor uitlijning, en beginners draaien ze vaak om. Denk zo:

  • justify-content verdeelt items langs de main axis (de “achter elkaar”-richting).

  • align-items lijnt items uit langs de cross axis (loodrecht op de rij/kolom).

In een header (row) betekent dit:

  • justify-content: space-between; zet logo links en CTA rechts, met ruimte ertussen.

  • align-items: center; zet alles netjes op één hoogte (verticale centrering).

Het effect is causaal en voorspelbaar: als tekst in een knop groter wordt (typografie) of padding groeit (box model), dan kan de hoogte van items verschillen. Zonder align-items: center lijkt je header “scheef”, terwijl er technisch niets fout is. Flexbox maakt dat soort kleine verschillen zichtbaar en oplosbaar.

Veelgemaakte fout: align-items gebruiken om horizontaal te verdelen in een row. Dat werkt niet, omdat align-items de cross axis pakt. Als je merkt dat je aan het “proberen” bent met meerdere properties, stop even en benoem: wat is mijn flex-direction, en dus mijn main/cross axis? Dat is de snelste manier om zonder gokken de juiste property te kiezen.

3) Wrappen en basis-responsive: flex-wrap + gap

Voor rijen kaartjes is het verschil tussen “breekt chaotisch” en “schaalt netjes” vaak één regel: flex-wrap: wrap;. Zonder wrap probeert flex alles op één regel te houden. Dan krijg je extreem smalle cards of overflow zodra de container te smal wordt.

Met flex-wrap: wrap; mogen items naar de volgende regel. Combineer dat met gap om consistente ruimte tussen items te krijgen. gap is hier de moderne, onderhoudsvriendelijke keuze: je hoeft niet met margins te vechten die aan de buitenrand ook ruimte toevoegen.

Een belangrijke nuance: wrap is geen magie die je layout “afmaakt”. Je moet nog steeds nadenken over item-breedtes. Als cards geen flex-basis hebben, kan de browser ze heel klein knijpen om toch op de regel te passen. Daarom is het gebruikelijk om card-items een basis te geven zoals flex: 1 1 280px; (hierover zo meer). Dan zegt je card: ik wil ongeveer 280px, ik mag krimpen en groeien, en ik wrap als het niet past.

Best practice in trainingsopdrachten: combineer maximale tekstbreedte (vanuit typografie) met flex-wrap. Als je kaartjes te breed worden, krijg je lange regels tekst; als ze te smal worden, krijg je te veel afbreking. Flex-wrap + een redelijke basisbreedte houdt je leesbaarheid stabiel.

[[flowchart-placeholder]]

Flex-eigenschappen op items: groeien, krimpen en een “basismaat”

1) flex: grow shrink basis als korte taal

De flex shorthand bepaalt hoe een item zich gedraagt ten opzichte van andere items wanneer er ruimte over is of tekort is:

  • grow (flex-grow): mag het item extra ruimte pakken?

  • shrink (flex-shrink): mag het item kleiner worden bij ruimtegebrek?

  • basis (flex-basis): wat is de “startmaat” voordat groei/krimp start?

Een veelgebruikte en praktische instelling voor cards is:css .card { flex: 1 1 280px; }

Dit zegt:

  • 1: de card mag meegroeien en ruimte eerlijk verdelen met andere cards.

  • 1: de card mag krimpen als het moet.

  • 280px: de card start rond 280px; als het smaller moet, wrap of krimp, als het breder kan, groei mee.

Waarom dit zo goed werkt in training-layouts: je krijgt rijen die zichzelf vullen zonder dat je exact “3 cards per rij” hardcodeert. Dat maakt je layout robuuster bij wisselende schermbreedtes en wisselende aantallen cards.

Misvatting om te doorbreken: “Ik zet width: 33% en klaar.” Percentages werken, maar zijn vaak fragiel: gap/padding/ borders uit het box model zorgen al snel dat 3 × 33% + gaps net te breed wordt, waardoor één card ineens wrapt. Flex met basis + gap is meestal vergevingsgezinder.

2) Wanneer flex: 0 0 ... juist wél handig is

Soms wil je juist niet dat iets groeit of krimpt. Denk aan een kleine badge, een icoon, of een CTA-knop in een header. Dan kun je groei/krimp uitzetten, bijvoorbeeld:

  • flex: 0 0 auto; (houdt natuurlijke maat, niet meeschalen)

  • of flex: 0 0 120px; (vaste basis)

Dit voorkomt dat je knop ineens superbreed wordt omdat er ruimte over is. Het sluit ook aan op de typografie-les: knoppen moeten niet afhankelijk zijn van toevallige whitespace om “belangrijk” te lijken; je bepaalt hun padding, kleur en gewicht bewust.

Een valkuil hier is over-corrigeren met vaste maten. Als je te veel vaste widths gebruikt, wordt je layout minder responsive. Zie het als een budget: vaste maten spaarzaam, flexibele verdeling als standaard.

3) min-width: 0 en tekst die niet wil afbreken

Een verrassende flexbox-killer: tekst die overflowt in flex-items. Soms lijkt het alsof flex “niet luistert” en blijft een item breder dan je verwacht. Dit komt doordat flex-items standaard een minimumgrootte kunnen hebben gebaseerd op hun content.

Praktische fix in components met lange woorden/URLs:css .card, .card__body { min-width: 0; }

Dan mag het item écht kleiner worden en kan tekst netjes wrappen (mits je typografie en word-break normaal staan). Dit is geen trucje voor alles, maar een gerichte oplossing bij cards met lange titels of ononderbroken strings.

Hier zie je het samenspel met eerdere onderwerpen:

  • Box model: padding verkleint je effectieve tekstkolom; dat is goed voor leesbaarheid, maar verhoogt kans op wrapping.

  • Typografie: een betere line-height en max-width helpen; flexbox regelt de verdeling, niet de leesbaarheid zelf.

Flexbox keuzehulp: wat zet je waar?

Situatie (categorie) Container-regels (op de parent) Item-regels (op de children)
Header met logo links, CTA rechts display: flex; justify-content: space-between; align-items: center; gap: 16px; zodat hoogteverschillen niet “scheef” ogen. CTA vaak flex: 0 0 auto; zodat de knop niet onnodig uitrekt; nav kan juist flexibel zijn.
Rij kaartjes die netjes wrapt display: flex; flex-wrap: wrap; gap: 24px; om rijen te laten breken zonder margin-gedoe. Cards flex: 1 1 280px; als responsieve basis; eventueel min-width: 0; bij overflowproblemen.
Twee kolommen: sidebar + main display: flex; gap: 24px; align-items: flex-start; zodat items bovenaan starten. Sidebar flex: 0 0 240px; (of auto), main flex: 1 1 auto; zodat content ruimte pakt.
Knop met icoon + tekst display: inline-flex; align-items: center; gap: 8px; zodat icoon en tekst mooi centreren. Icoon vaak flex: 0 0 auto; om te voorkomen dat SVG/icoon vervormt of ruimte opeist.

Twee realistische trainingssituaties, stap voor stap

Voorbeeld 1: “Drie cards per rij” die toch rommelig wrapt

Je opdracht vraagt om een rij kaartjes met titel, beschrijving en “Lees meer”. Op grote schermen zijn het er drie naast elkaar, maar op laptopbreedtes wrapt er soms eentje naar beneden. Je eerste reflex is vaak: tekst kleiner maken of margins weghalen, maar dat is symptoombestrijding.

Stap voor stap breng je dit terug naar flexregels:

  1. Je zet flex op de juiste container, bijvoorbeeld .cards { display: flex; }, en je voegt gap toe voor consistente spacing. Dit voorkomt dat je met losse margins de buitenranden “opblaast”.
  2. Je kiest bewust voor responsive gedrag: .cards { flex-wrap: wrap; }. Nu mag de rij breken wanneer het niet past, in plaats van alles te proppen.
  3. Je geeft cards een basismaat: .card { flex: 1 1 280px; }. Daardoor ontstaan vanzelf 3 kolommen waar het kan, 2 waar het net niet kan, en 1 op smalle schermen, zonder dat je percentages hoeft te mikken.
  4. Je checkt box model en typografie: card padding + line-height maken cards hoger, maar dat is oké. Als één card veel meer tekst heeft, accepteer je hoogteverschil of je redigeert content; flexbox maakt inhoudsverschil zichtbaar, het “verbergt” het niet.

Impact:

  • Layout blijft stabiel bij verschillende schermen en aantallen cards.

  • Leesbaarheid blijft beter omdat je niet hoeft te “micro-fit”ten met kleine fonts.

Beperking:

  • Je hebt minder exacte controle over “precies 3 per rij” op elke breedte; flexbox kiest het meest logische patroon op basis van ruimte en basismaat.

Voorbeeld 2: Header met navigatie die niet mooi uitlijnt

Je header heeft een logo links, in het midden een set links, en rechts een CTA-knop. Wanneer je de CTA meer padding geeft (voor klikbaarheid) of het font-weight verhoogt (voor hiërarchie), lijkt alles verticaal uit lijn. Ook kan het gebeuren dat de nav-links samenklonteren en de knop naar beneden duwt.

Stap voor stap maak je het robuust:

  1. Je zet de header als flex container met duidelijke intentie: justify-content: space-between; align-items: center;. Dat lost “scheefstand” op die ontstaat door verschillende hoogtes (typografie + padding).
  2. Je maakt ruimte-uitdagingen expliciet met gap. Zonder gap gaan mensen vaak margins aan individuele links hangen, wat later conflicten geeft met specificity of onverwachte buitenruimte.
  3. Je beschermt de CTA tegen ongewenst stretchen: flex: 0 0 auto; op de knop. Zo blijft de knop op contentmaat, en pakt de nav de flexibele ruimte.
  4. Je accepteert dat écht kleine schermen een ander patroon nodig kunnen hebben (bijvoorbeeld stapelen). Flexbox maakt die switch eenvoudig met flex-direction, maar de keuze wanneer je dat doet hangt af van beschikbare breedte en de hoeveelheid nav-items.

Impact:

  • Header oogt direct “af”: alles gecentreerd, logische verdeling van ruimte, CTA blijft herkenbaar.

  • Je component blijft onderhoudbaar: styling op classes, weinig ad-hoc overrides.

Beperking:

  • Als je te veel nav-items hebt, gaat flexbox niet “magisch” ruimte creëren; je moet dan de inhoud beperken of een compacte variant kiezen.

Een flexbox-basis die je steeds opnieuw kunt gebruiken

  • Begin bij de container: display: flex, kies je richting, en regel verdeling met justify-content en uitlijning met align-items.

  • Maak responsive gedrag bewust: flex-wrap + een realistische flex-basis voorkomt prop-gedrag en onverwachte overflow.

  • Gebruik het box model en typografie als partners: padding en line-height maken je UI beter leesbaar, maar veranderen afmetingen; flexbox helpt die veranderingen netjes opvangen.

  • Debug zonder gokken: controleer altijd (1) wie is de flex container, (2) wat zijn de directe items, (3) welke rule wint via specificity.

Een checklist die je kunt vertrouwen

  • Je layouts worden voorspelbaarder omdat je ruimteverdeling (flex) scheidt van ruimte-inhoud (box model + typografie).

  • Je CSS blijft onderhoudbaar doordat je flexregels vooral op component-classes zet, in plaats van steeds specifieker te gaan nesten.

  • Je pagina’s voelen professioneler omdat uitlijning en spacing consistent worden, óók wanneer content of schermbreedte verandert.

Met deze flexbox-basis kun je in trainingsopdrachten de meest voorkomende layoutproblemen oplossen zonder je HTML ingewikkelder te maken.

Last modified: Tuesday, 10 March 2026, 3:33 PM