Er was eens een HTML-element. Wat voor HTML-element is hier niet zo van belang, het enige dat telt is dat het om een block-level element gaat. Laten we het een naam geven, we noemen het Blokje. Blokje heeft van zichzelf een aantal eigenschappen, gewoon omdat het een block-level element is. Waarvan hier belangrijk:
- het gebruikt in z’n eentje de gehele beschikbare breedte van zijn parent
- het negeert alle elementen met een float
- laat z’n marges overlappen met die van aangrenzende elementen
- top- en bottom margins van ingesloten block-level elementen steken block-level parent uit en overlappen de marges ervan
Maar Blokje wil meer, Blokje wil:
- niet alle omliggende floated blocks negeren
- meerekken met zijn ingesloten floated blocks in plaats van dat deze buiten Blokje uitsteken
Float
De meest voor de hand liggende manier voor Blokje om mee te gaan met de floats van omliggende elementen is als het zelf ook een float krijgt. Op die manier komt Blokje (hier rood) er naast of tussen te staan in plaats van dat het eronder ligt. Maar wat nu als je wilt dat het element na Blokje, niet naast Blokje aansluit (1) of eronder komt te liggen (2), maar op de volgende regel komt te staan (3)? Dan geef je die laatste natuurlijk een clear, want daar is clear tenslotte voor bedoeld. Maar clear is niet de enige oplossing, hetzelfde effect kan ook met andere eigenschappen bereikt worden. En dat kan heel handig zijn.

Clear
Om een block te laten meerekken met zijn ingesloten floated blocks plaatsen we gewoon een extra element onderin (ja, inderdaad, doen we alleen als het niet anders kan), geven deze een clear… en klaar. Maar met die clear beëindig je ook de floats van de eerdere elementen in de HTML-code.
Zie het voorbeeld hieronder, waarbij het kleine ingesloten vierkant een float heeft en Blokje (zijn blocklevel parent, hier felgroen) hem simpelweg negeert (1). Geef Blokje onderin een element met clear en de float van de linkerkolom (die in de HTML-code eerder komt), wordt tegelijk ook gecleart (2). Dat laatste willen we niet, bedoeling is dat Blokje alleen meerekt met zijn ingesloten floated block, verder niets (3).

Hier red je het dus niet met clear, je hebt echt een andere oplossing nodig. En daar gaat dit artikel over.
CSS layouts
Inline en block-level
De eenvoudigste manier om het gedrag van de elementen in je CSS layouts te begrijpen, is om die elementen onder te verdelen in block-level en inline. Als je weet wat de specifieke eigenschappen zijn van beide, zal je veel van wat je ziet gebeuren op het beeldscherm kunnen verklaren. Vervolgens is de oplossing meestal gauw gevonden.
Block Formatting Context
Als aanvulling is er een andere benadering mogelijk. Misschien is deze uitleg iets complexer maar als je die eenmaal onder de knie hebt, verklaart het de vragen rondom CSS layouts die nog overbleven. Want waarom vallen margins de ene keer binnen een div en de andere keer erbuiten, wat is de oorzaak van de ruimte tussen bijvoorbeeld die H1 en de div eronder? En waarom treden die verschijnselen niet op in IE7 en ouder?
Het antwoord is Block Formatting Context (BFC). Misschien kan je Block Formatting Context het beste vertalen met ‘opmaak van een kader in samenhang met de omliggende kaders’; we hebben het hier over layouten dus. Ieder block-level element heeft zijn eigen BFC. Ik stel me daar het volgende bij voor.
Block Formatting Context – Theorie
Een block-level element is van zichzelf zo breed als de beschikbare breedte en het staat geen andere elementen naast zich toe op dezelfde regel. Met float voeg je nieuwe BFC toe aan een element. Hiermee doe je een (ingrijpende) aanpassing in de layout: het element gaat uit de flow van de pagina en zweeft daar nu zo’n beetje boven. Net zo ingrijpend is het als je het een position: absolute geeft, een andere display of een overflow, ook allemaal toegevoegde BFC. Je voegt met CSS eigenschappen met bepaalde waardes toe die betekenis hebben voor de opmaak van het element in relatie tot de de omliggende elementen. Dus het gaat hier niet om een kleur, een rand, de afmeting of een lettertype of iets dergelijks.
Alle CSS stijlen die BFC toevoegen hebben een aantal BFC eigenschappen gemeen. Waarmee je, als je eenmaal een layout op deze manier kunt benaderen, onverwacht gedrag kunt verklaren en over een aantal extra opties voor je layout beschikt.
Block Formatting Context – Eigenschappen
Je kunt twee vormen onderscheiden: het block-level element met zijn standaard BFC en een block-level element met toegevoegde BFC. Hier volgt een overzicht van de specifieke eigenschappen die een block-level element kan krijgen als er BFC is toegevoegd.
- parent met BFC sluit zichtbaar zijn (klein)kinderen met float in (rekt dus mee met de inhoud)
- overlappen niet, ook de margins overlappen niet maar sluiten naast elkaar aan
- top- en bottom margins van geneste elementen zijn ook zichtbaar ingesloten (dus binnen de parent met BFC)
Uiteraard gaat dit niet uitsluitend op voor divs maar voor alle block-level elementen. Ook zal het soms zoeken blijven naar de juiste oplossing omdat iedere CSS-stijl zijn eigen specialiteit heeft en die kunnen op de bewuste plaats juist weer ongewenst zijn. Een voorbeeld: stel je wilt een parent geen vaste breedte geven omdat hij zich moet voegen in de beschikbare breedte. Dan zal het toekennen van een float aan die parent ervoor zorgen dat de deze meerekt met zijn ingesloten floated blocks, doel bereikt zou je denken. Maar tegelijk zal de bewuste parent beneden zijn floated buurman springen:
- omdat hij de volledige breedte van zijn parent gebruikt
- want hij heeft geen breedte gekregen die past naast zijn buurman
- en een block met toegevoegde BFC niet overlapt
Block Formatting Context – Toepassen
Omdat deze benadering in bepaalde layouts dus bepaalde CSS-stijlen uitsluit als oplossing is de beste aanpak om eerst de CSS-stijl te kiezen die het meest voor de hand ligt en dan te kijken welke de gezochte oplossing biedt. Als je het principe begrijpt dan vind je je weg en kan je onverwacht gedrag uiteindelijk verklaren. De volgende combinaties van eigenschap en waarde kennen nieuwe BFC toe aan een block-level element:
- float: left
- float: right
- position: absolute
- display: inline-block
- display: inline-table
- display: table-cell
- display: table
- overflow: auto
- overflow: scroll
- overflow: hidden
Iedere combinatie heeft zijn eigen specifieke eigenschappen. Welke je moet kiezen in welke omstandigheid is afhankelijk van wat er op een bepaalde plek nodig is. Je zult bijvoorbeeld kiezen voor overflow: auto bij een block met een vaste afmeting waar je een scrollbalk wilt zien als de inhoud niet meer erin past. En dan kunnen verklaren wat er nog meer verandert in je layout.
Block Formatting Context – Voorbeelden
In de voorbeelden aan het begin van dit artikel heeft het Blokje (rood) uiteindelijk een overflow: hidden gekregen. Door de toegevoegde BFC overlapt het niet met het bruine blokje met float en komt het ernaast te staan. Omdat het geen float heeft staat het rechts van zich nog steeds geen ander element toe, dus springt geel naar beneden.
Blokje (felgroen) in het andere voorbeeld kan zowel een float: left als een overflow: hidden krijgen. Door deze toegevoegde BFC rekt Blokje alleen mee met het ingesloten floated block. Omdat met de toegevoegde BFC Blokje niet meer overlapt met de linkerkolom, komt het deel dat eerst onder de linkerkolom viel er nu naast te staan. Om de layout dezelfde breedte te laten behouden, is ook de breedte verkleind van Blokje.
IE 7 en ouder
IE 7 en ouder ziet de toegevoegde width of een height aan een element ook als toegevoegde BFC. Dat levert grote verschillen op met de moderne browsers waar dat niet zo is. Want hierdoor zal een div met een width in IE7 en ouder meerekken met een ingesloten floated block en in de moderne browsers niet. En vallen bijvoorbeeld de marges van een ingesloten H1 in IE7 binnen de div en in de moderne browsers erbuiten. Bekijk een voorbeeld met toelichting van een layout waarin een div in IE6 en IE7 wel zonder clear meerekt met een ingesloten floated block en in de moderne browsers niet
Meer weten?
- Waarom marges bij float niet overlappen
- Een layout met overfow: hidden in plaats van clear
- Een layout met 3 kolommen met BFC in plaats van clear
Zie ook de artikelen van Zoe Gillenwater en Philippe Wittenbergh en Thierry Koblentz over dit onderwerp.
No related posts.