Box model: spacing en sizing
Waarom “even wat padding” ineens alles verschuift
Je werkt aan een trainingsopdracht: een pagina met een navigatiebalk, een call-to-action knop en een contentblok met kaartjes. Je zet netjes width: 300px; op een kaart, voegt padding: 20px; toe voor lucht, en ineens past je kaart niet meer in de rij. Of je knop wordt hoger dan verwacht en de tekst “springt” uit het midden. Dit voelt vaak alsof CSS “willekeurig” is, maar het is eigenlijk een heel vaste rekenregel: het box model.
Dit onderwerp is precies nu belangrijk, omdat spacing en sizing vaak het moment zijn waarop layouts in opdrachten “net niet lekker” aanvoelen: te krap, te rommelig, of net één pixel over waardoor dingen wrappen. Als je het box model beheerst, kun je doelbewust ruimte toevoegen zonder dat je verrast wordt door onverwachte breedtes, hoogtes en verschuivingen.
Vandaag leer je hoe de browser afmetingen berekent, welke onderdelen wél meetellen in de grootte, en hoe je dit voorspelbaar houdt in je eigen CSS.
Het box model in mensentaal: wat de browser echt meet
Elk HTML-element is een rechthoekige box. Die box bestaat uit vier lagen, van binnen naar buiten:
-
Content: de echte inhoud (tekst, afbeelding, etc.).
-
Padding: ruimte binnen de box rondom de content (achtergrondkleur loopt hier door).
-
Border: de rand om het element.
-
Margin: ruimte buiten de box, tussen dit element en andere elementen.
De verwarring ontstaat meestal bij één vraag: als ik width: 300px zet, is dat dan de totale buitenbreedte? Het antwoord hangt af van één instelling: box-sizing. Standaard (default) is content-box: dan is width alleen de content, en komen padding en border er bovenop. Met border-box wordt width juist de “hele box” inclusief padding en border. Dat is vaak veel voorspelbaarder in trainingsopdrachten waar je met kolommen, kaarten en knoppen werkt.
Dit sluit direct aan op het debug-denken uit de les over selectors en specificity: ook hier geldt dat CSS niet “zomaar” iets doet. Als padding “niet lijkt te passen” of widths “ineens te groot” worden, is er een concrete regel die wint: óf een default (content-box), óf een instelling die je (of een template) al eerder zette, óf een specifieke component-regel die je overschrijft.
Spacing is niet één ding: margin, padding, border en hun bijwerkingen
Margin en padding lijken allebei “ruimte”, maar ze voelen anders omdat ze op een andere plek zitten. Padding is onderdeel van het element zelf: het vergroot de klikruimte van een knop en laat een achtergrondkleur “meelopen”. Margin is juist de afstandhouder naar buiten toe: handig om kaarten uit elkaar te zetten zonder hun eigen kleurvlak groter te maken.
Een belangrijk gevolg is dat je met padding de visuele massa van een component verandert, terwijl je met margin vooral de relatie tussen componenten verandert. Een kaart met veel padding voelt luxer en leesbaarder, maar wordt ook sneller te breed in een grid. Een kaart met veel margin kan juist veel “witruimte” creëren tussen kaarten, maar lost geen probleem op als de tekst tegen de rand plakt.
Border is de derde speler die sizing beïnvloedt. Een border: 2px solid lijkt klein, maar telt in veel situaties wél mee voor de totale afmeting (zeker bij content-box). Hierdoor kan een set kaarten die exact paste, ineens net niet meer passen zodra je een border toevoegt voor “nettere” styling. Beginners denken dan vaak dat de flex/grid “stuk” is, terwijl de optelsom simpelweg niet meer klopt.
Misverstanden die vaak terugkomen:
-
“Padding duwt andere elementen weg.” Nee: padding vergroot je eigen box; het effect op anderen is indirect (je box wordt groter).
-
“Margin is altijd veilig.” Margin kan verrassingen geven bij verticale marges, omdat margin-collapsing kan optreden: twee verticale margins kunnen samensmelten tot één grotere margin.
-
“Border is decoratie en telt niet mee.” Border is een echte laag met echte pixels; de browser telt hem vaak mee in breedte/hoogteberekeningen.
Hieronder zie je de belangrijkste verschillen naast elkaar, zodat je sneller de juiste keuze maakt.
| Dimensie | Margin | Padding | Border |
|---|---|---|---|
| Waar zit het? | Buiten de box, “lucht” tussen elementen. Beïnvloedt vooral de afstand tot buren. | Binnen de box, tussen content en rand. Vergroot de ‘binnenruimte’ van een component. | Tussen padding en margin. Is letterlijk de randlijn/dikte rond het element. |
| Achtergrondkleur? | Nee, achtergrond loopt niet door in margin. Daardoor blijft de “kleurvlek” gelijk. | Ja, achtergrond loopt door over padding. Handig voor knoppen/kaarten met een blok-achtergrond. | Border zelf is zichtbaar; achtergrond stopt bij de rand. Border kan de component visueel “zwaarder” maken. |
| Typische inzet | Afstand tussen kaarten, ruimte tussen header en content, spacing tussen secties. Houdt componenten los van elkaar. | Leesbaarheid (tekst niet tegen rand), grotere klikzones, consistent “binnenkader” voor cards. | Scheiding/lijnen, focus states, subtiele rand om cards. Ook bruikbaar voor debugging (tijdelijk). |
| Veelvoorkomende valkuil | Verticale margin-collapsing: boven/onder-margins kunnen samenvallen, waardoor spacing “anders” voelt dan verwacht. | Bij content-box maakt padding je element breder/ hoger dan gedacht. Kan layout laten wrappen. |
Kan net 1–4px “over de grens” duwen in grids/rijen. Bij content-box komt het bovenop je width/height. |
Sizing die je kunt vertrouwen: content-box, border-box en rekenregels
De kern van voorspelbare sizing is begrijpen wat de browser optelt. Met box-sizing: content-box (default) geldt grofweg:
-
Totale breedte =
width+padding-left/right+border-left/right(margin staat daar nog buiten) -
Totale hoogte =
height+padding-top/bottom+border-top/bottom
Dat betekent: als je kaart width: 300px heeft en je zet padding: 20px en border: 2px, dan wordt de totale buitenbreedte 300 + 40 + 4 = 344px (margin niet eens meegerekend). In een rij van drie kaarten kan dat het verschil zijn tussen “past precies” en “springt naar een nieuwe regel”. Het voelt als een klein detail, maar het is exact het soort detail dat een trainingsopdracht er ineens “slordig” uit laat zien.
Met box-sizing: border-box verschuift de betekenis: width en height zijn dan de maat inclusief padding en border. Dus width: 300px blijft 300px totaal, en de contentruimte wordt automatisch kleiner als je meer padding toevoegt. Dit is vaak de reden dat veel teams standaard zetten:css
* {
box-sizing: border-box;
}
Best practice in opdrachten is: kies vroeg een consistente aanpak, zodat je componenten voorspelbaar zijn. border-box maakt het makkelijker om in “kolombreedtes” te denken, en voorkomt dat een kleine design-aanpassing (iets meer padding voor leesbaarheid) je hele layout breekt. De beperking is wel dat contentruimte kleiner kan worden; bij kleine componenten (bijv. een smalle badge) kan te veel padding de tekst sneller laten wrappen of afkappen.
Een typische misconceptie is dat border-box “alles oplost”. Het maakt sizing voorspelbaarder, maar het verandert niets aan slechte totals: als je drie kaarten van 33.33% breedte geeft én je zet grote margins, dan kan het nog steeds krap worden. Het helpt je vooral om te weten wáár je ruimte vandaan komt en waar je hem kunt corrigeren.
[[flowchart-placeholder]]
Twee trainingssituaties stap voor stap: kaarten in een grid en een CTA-knop die “te groot” wordt
Voorbeeld 1: kaartjes die ineens wrappen na extra padding
Stel: je hebt een contentblok met drie kaartjes naast elkaar. Je hebt een vaste breedte gekozen omdat het in de opdracht overzichtelijk is, en je wil wat meer lucht voor leesbaarheid. Je CSS voelt logisch:css
.card {
width: 300px;
padding: 20px;
border: 2px solid #ddd;
margin: 10px;
}
De stap-voor-stap verklaring waarom het misgaat is puur box model-rekenen. Met de default content-box is de totale breedte per kaart: 300 + 40 padding + 4 border + 20 margin = 364px aan “ruimte claimen” in de rij (margin telt mee in de afstand die nodig is). Als je container bijvoorbeeld rond de 1100px breed is, passen er geen drie meer (3 × 364 = 1092; dat lijkt net te passen, maar in de praktijk spelen ook gaps, rounding en eventuele container-padding mee). Eén kleine extra pixel kan dan genoeg zijn om de laatste kaart naar beneden te duwen.
De nette oplossing in trainingswerk is meestal niet “alles kleiner maken”, maar de sizing voorspelbaar maken. Door box-sizing: border-box te gebruiken, wordt de totale kaartbreedte inclusief padding/border exact 300px, en blijft je grid stabiel terwijl je binnenruimte aanpast. De impact: je kunt design tweaks doen (meer padding, dikkere border) zonder elke keer opnieuw kolombreedtes te herberekenen. De beperking: je contentruimte wordt kleiner dan 300px; dus lange titels kunnen sneller op twee regels komen—wat weer invloed heeft op hoogte-consistentie tussen kaarten.
In een workflow met feedbackmomenten (beoordelaar/coach) helpt dit ook communicatief: je kunt uitleggen dat “300px de kaartmaat is” en dat spacing intern geregeld wordt, in plaats van dat breedte “stiekem” verandert door padding. Dat maakt je componenten herbruikbaarder en je aanpassingen sneller.
Voorbeeld 2: een CTA-knop die hoger wordt dan verwacht (en waarom padding de boosdoener is)
Je hebt een call-to-action knop in de header. Je wil dat hij lekker klikbaar is, dus je verhoogt padding. Daarna lijkt de knop niet meer mooi uitgelijnd met de navigatie, of hij duwt de header hoger dan gepland. Bijvoorbeeld:css
.btn {
padding: 16px 24px;
border: 2px solid transparent;
}
.btn--cta {
border-color: green;
}
Wat gebeurt er? Ten eerste: padding vergroot de box. Dus als je header een vaste hoogte heeft (of visueel strak moet blijven), maakt een grote verticale padding (16px) je knop hoog. Ten tweede: je border telt ook mee (2px boven en onder). De knop heeft dus niet alleen extra “lucht”, maar ook extra “dikte”. Als je nav-items bijvoorbeeld kleinere line-height of padding hebben, ontstaat scheefstand: de knop heeft een andere totale hoogte dan de links.
De stap-voor-stap aanpak is: bepaal welke maat je wil “controleren”. Wil je dat alle items in de header dezelfde hoogte hebben? Dan is het vaak beter om consistentie in padding/line-height te kiezen, en de CTA te laten variëren in kleur/border in plaats van in hoogte. Als je wél een grotere knop wil, accepteer dan dat de headerhoogte meebeweegt, of geef de header ruimte. Het box model helpt je hierbij, omdat je bewust kiest: “maak ik de knop groter (padding) of creëer ik meer ruimte eromheen (margin)?” Dat zijn twee verschillende effecten.
Het voordeel van deze denkwijze in trainingsopdrachten is dat je sneller verklaart waarom iets verschuift, en je minder gaat “tweaken op gevoel”. De beperking is dat er soms meerdere juiste oplossingen zijn, afhankelijk van het design: een compacte header met kleine CTA of een ruimere header met duidelijke focus. Het box model geeft je de taal en de rekenregels om die keuze bewust te maken.
De kern die je meeneemt naar je stylesheet
Het box model is geen theorieblokje; het is de rekenmachine achter elke layout. Als je begrijpt wat content, padding, border en margin doen, kun je spacing toevoegen zonder verrassingseffecten en kun je sizing stabiel houden—zeker in kaarten, knoppen en navigatie waar opdrachten vaak op beoordeeld worden.
Belangrijkste punten om te onthouden:
-
Padding vergroot je component van binnenuit; margin regelt afstand tussen componenten; border telt vaak mee als echte pixels.
-
Met
content-boxkomt padding/border bovenop jewidth/height; metborder-boxblijft de totale maat stabiel. -
Als iets “net niet past” of wrappet, is er bijna altijd een optelsom die groter is dan je dacht—niet een mysterieuze CSS-bug.
This sets you up perfectly for Typografie & kleur voor leesbaarheid [25 minutes].