Clearen van elementen met de clearfix class

Bron: http://www.sceneone.nl/tips_tricks/clearfix.php

Titel: HTML en CSS tutorials

Auteur: Wybe Weysters

Misschien ken je het probleem: je hebt een container met daarin een aantal floatende boxen (of andere elementen). De container zelf float niet en heeft dus geen body. Hij ziet immers de floatende boxen niet.

Als bovenstaande je een beetje boven je pet gaat moet je misschien dit nog even doornemen.

Stapelen is fijn

Wat je zou kunnen doen is de container zelf ook laten floaten. Floatende elementen zien elkaar namelijk wel. Op die manier zou de container dus de boxen wel zien.
Het probleem daarmee is dat je op die manier op een gegeven moment je hele website aan het floaten bent.
En dat wil je eigenlijk niet. Hoe meer elementen je in de natuurlijk flow van de pagina kunt laten meebewegen hoe beter het is.

Gewoon de ene box op de andere stapelen zonder ze verder te positioneren, dat is fijn. Dat doen we graag. Eenvoudiger is beter!
Maar dat kan lang niet altijd. Vaak zul je boxen moeten laten floaten om ze náást elkaar te kunnen positioneren.

Eerst nog maar even een voorbeeld van wat ik bedoel met gewoon "stapelen":

CSS: .container{
border: 1px solid orange;
padding: 0 10px;
margin: auto 0 10px 0;
}
HTML: <div class="container">
<p>Content voor div 1</p>
<p>Content voor div 1</p>
<p>Content voor div 1</p>
<p>Content voor div 1</p>
<p>Content voor div 1</p>
</div>

<div class="container">
<p>Content voor div 2</p>
<p>Content voor div 2</p>
<p>Content voor div 2</p>
<p>Content voor div 2</p>
<p>Content voor div 2</p>
</div>

<div class="container">
<p>Content voor div 3</p>
<p>Content voor div 3</p>
<p>Content voor div 3</p>
<p>Content voor div 3</p>
<p>Content voor div 3</p>
</div>

bekijk het resultaat

Je ziet het, geen positionering. Alleen wat marge en padding meer niet.........gewoon stapelen dus en de natuurlijke flow van de pagina zijn gang laten gaan.

Floaten is ook best fijn

Voordat hier misverstanden over ontstaan: met floaten is niets mis. Het is een onmisbaar instrument om elementen te positioneren. Zeker in de wat complexere layouts. Maar het is mooi als op een gegeven moment een einde komt aan de floatende elementen en je weer gewoon verder kunt "stapelen" en dus terug kunt keren naar de normale flow van de pagina. That's all.

Om die terugkeer naar de normale flow van de pagina te bereiken hebben we een aantal mogelijkheden. De mogelijkheid die ik hier wil bespreken wordt wel de "clearfix" genoemd.

Elementen clearen

Om terug te keren naar de normale flow van de pagina moeten we de floatende elementen clearen.
De reden dat ik voor de "clearfix" manier kies is omdat hij werkt op alle elementen, in alle browsers, in alle omstandigheden en in alle websites. Wat wil je nog meer.

Wat is eigenlijk het probleem

Ik wil eerst even een voorbeeld van het probleem geven. Dan zien we goed wat er fout gaat:

CSS: .container{
border: 1px solid orange;
padding: 0 10px;
margin: auto 0 10px 0;
}

.inner{
border: 1px solid black;
width: 200px;
float: left;
display: inline;
margin: 0 5px;
padding: 5px 10px;
}
HTML: <div class="container">

<div class="inner">
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
</div>

<div class="inner">
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
</div>

</div>

<div class="container">
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
</div>

bekijk het resultaat

Wat gaat er fout?

We zien een paar dingen fout gaan:

Oplossing

We kunnen de drie bovenstaande problemen terugbrengen tot 1 probleem: het feit dat de bovenste container geen body heeft. Geen inhoud lijkt te hebben.
We moeten hem dus vertellen dat hij wel degelijk inhoud heeft, namelijk die twee floatende boxen die hij niet kan zien.

Clearfix

De naam clearfix slaat op de naam van de class die we gaan aanmaken om het bovenstaande probleem op te lossen. Dat had dus net zo goed een andere naam kunnen zijn, maakt niet uit.
Maar omdat het probleem te maken heeft met floatende elementen die ge-cleared moeten worden is de naam clearfix wel logisch.

Aan de slag

Als je niet begrijpt wat het betekend om elementen te clearen moet je misschien dit nog even lezen.
Ik ga er vanuit dat je begrijpt wat de clear eigenschap doet.

Om te beginnen hebben we een element nodig waaraan we de clear eigenschap kunnen koppelen. We willen dit element altijd tot onze beschikking hebben en er altijd zeker van zijn dat het bestaat.
Nou wil het toeval (........) dat we daar een mooie css eigenschap voor hebben. We kunnen via css content toevoegen aan onze markup. Op deze manier:

CSS: .extra-content{
border: 1px solid red;
padding: 0 10px;
}

.clearfix:after{
content: "Een beetje extra content!";
}
HTML: <div class="extra-content clearfix">
<p>Content voor div</p>
<p>Content voor div</p>
<p>Content voor div</p>
<p>Content voor div</p>
<p>Content voor div</p>
</div>

bekijk het resultaat (in Firefox, Opera of Safari. Werkt niet in Internet Exporer).

Say what?

"clearfix" is dus de naam van de class. Het ":after" gedeelte kun je vergelijken met ":hover" van een linkje. Het is een psuedo-element en het zorgt ervoor dat er content toegevoegd wordt achter de bestaande content van het element waaraan de class gekoppeld wordt. Het wordt altijd gebruikt in combinatie met de declaratie "content":

Zoals je ziet zet ik 2 classes op 1 element. Ik zet ze gewoon achter elkaar door een spatie van elkaar gescheiden. Als dit de eerste keer is dat je dat ziet kun er hier wat meer over lezen.

Oke, nu kunnen we dus een stukje content toevoegen waarvan we zeker weten dat het bestaat, altijd en overal waar we de betreffende class toevoegen. Dit hoeft helemaal geen hele regel tekst te zijn. We hebben genoeg aan bijvoorbeeld een punt: content: ".";
Verder is het zo dat we die punt helemaal niet willen zien, dus: visibility: hidden; en we willen niet dat die punt hoogte in beslag gaat nemen, dus height: 0;. Maar om het stukje content een height te kunnen geven moeten we er eerst een block-level element van maken.

Onze class clearfix ziet er dus nu zo uit:

CSS: .extra-content{
border: 1px solid red;
padding: 0 10px;
}

.clearfix:after{
content: ".";
visibility: hidden;
display: block;
height: 0;
}
HTML: <div class="extra-content clearfix">
<p>Content voor div</p>
<p>Content voor div</p>
<p>Content voor div</p>
<p>Content voor div</p>
<p>Content voor div</p>
</div>

bekijk het resultaat (in Firefox, Opera of Safari. Werkt niet in Internet Exporer).

We zien helemaal niets meer van die punt, maar we weten dat hij er wel is. En we weten dat het een block element is. Nu voegen we nog 1 stijlregel toe aan onze class, de belangrijkste, de stijlregel waarmee we alle voorgaande elementen clearen: clear: both;.
We gebruiken dus de verborgen punt die zich gedraagt als een block-level element om alle voorgaande content te clearen, wat die voorgaande content ook mag wezen. we bekijken nog een keer het eerdere voorbeeld waarin het fout ging, maar nu voegen we de class clearfix toe:

CSS: .container{
border: 1px solid orange;
padding: 0 10px;
margin: auto 0 10px 0;
}

.inner{
border: 1px solid black;
width: 200px;
float: left;
display: inline;
margin: 0 5px;
padding: 5px 10px;
}

.clearfix:after{
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
HTML: <div class="container clearfix">

<div class="inner">
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
<p>Content voor inner div 1</p>
</div>

<div class="inner">
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
<p>Content voor inner div 2</p>
</div>

</div>

<div class="container">
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
<p>Content voor container div 2</p>
</div>

bekijk het resultaat (in Firefox, Opera of Safari. Werkt niet in Internet Exporer).

En ziedaar. Het probleem is opgelost. Dat wil zeggen als je in een fatsoenlijke browser kijkt. Zowel IE6 als IE7 snappen er niets van..........maar we hadden ook niet anders verwacht.

Er bestaat een stijl declaratie, die heet "zoom". Deze werkt alleen in Internet Explorer.
IE heeft die declaratie nodig in deze vorm: "zoom: 1;"

Als je aparte stylesheets serveert voor IE6 en IE7 via conditional comments kun je deze declaratie toevoegen aan die stylesheet(s), gewoon zo:

CSS: .clearfix{
zoom: 1;
}

Je kunt hem ook gewoon in je normale stylesheet kwijt. Echte browsers hebben geen last van die declaratie. Ze negeren hem gewoon.
Met deze declaratie toegevoegd werkt het ook in IE.

naar het begin van de pagina