Float wrapping

Artiklen gennemgår de problemer, der opstår når float'ede elementer clear'es på en sådan måde, at deres indhold bestemmer udstrækningen af det element, der indeholder de float'ede elementer.

Eksempel 1 illustrerer problemet. Du ser et element #floatcontainer med en kraftig stiplet rammekant (border). Dette element indeholder en left-float'et og right-float'et kolonne.

Din forventning er muligvis, at den stiplede røde rammekant skulle vises rundt om hele indholdet. Men det skal den faktisk ikke. For at det kan ske, skal de to float'ede elementer inde i #floatcontainer clear'es.

Der er forskellige løsninger på problemet:

Løsning 1 – et sidefodselement

Hvis du alligevel skal have et sidefodselement, kan du sætte det ind i float-containeren: Eksempel 2. Sidefodselementet skal clear'es på sædvanlig måde.

HTML-kildekode til eksempel 1

<div id="page">
  <h2>...</h2>
  <div id="floatcontainer">
    <div id="leftcol">
    ...
    </div>
    <div id="rightcol">
    ...
    </div>
    <div id="sidefod">
    <h3>...</h3>
    </div>
  </div>
</div>

Løsning 2 – et clear'ing element

Har du ikke et sidefodselement – det er jo ikke altid, at float-containeren kan dublere som en container for alt indhold på siden – kan du lave et clear'ing element:

<div class="cb">
</div>

– med tilhørende formdeklaration:

.cb {clear:both;}

Dette træder i stedet for sidefodselementet. Eksempel 3.

Mere puritanistisk indstillede websidekonstrukører synes ikke om den fordi der bruges html-kode til et præsentationsformål.

Løsning 3 – overflow

En stylesheet løsning er at tilføje følgende formregler til formdeklarationen for float-containeren.

overflow:auto;width:100%;

overflow-egenskaben tvinger float-containeren til at rumme det float'ede indhold.

Det er ikke helt nok for Internet Explorer. Denne browser har en Read-Only egenskab, hasLayout (Mere om denne på websiden hasLayout Property), der sættes af visse egenskaber, heriblandt width og height. Derfor skal vor float-container af hensyn til denne browser en bredde på 100 procent.

Browserkompatibilitet: IE5/Win, IE5.5/Win, IE6/Win, IE7/Win, Opera 9, Safari 2, Firefox 1.5, men ikke IE5/Mac.

Eksempel 4.

I IE5/Mac fungerer det med overflow:hidden;.

Hvis du ikke har behov for at understøtte IE5, og ikke ønsker at have en eller anden bredde på float-containeren, kan du bruge den Microsoft-specifikke egenskab zoom, ved at tilføje følgende egenskab til formdeklarationen for float-containeren:

zoom:1;

Eksempel 5.

Løsning 4 – :after pseudo-klassen

Denne har igennem et stykke tid været min foretrukne metode til at clear'e float'ede elementer, da det også er en stylesheet løsning, der kun kræver at float-containeren forsynes med klassen clearfix.

Eksempel 6.

Stylesheet'et, der definerer klassen clearfix ser således ud:

.clearfix:after {
  content: "."; 
  display: block; 
  height: 0; 
  clear: both; 
  visibility: hidden;
}
.clearfix {display: inline-table;}

/* Skjul for IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End skjul for IE-Mac */

Denne metode gør brug af :after pseudoklassen, der i standard-kompatible browsere opretter et blokelement efter det element, der er forsynet med en højde på nul, indsætter et punktum i dette blokelement og skjuler dette punktum ved hjælp af visibility-egenskaben. Elementet får en clear-egenskab.

Denne clearfix virker ikke i IE7. Denne browser læser ikke linien
* html .clearfix {height: 1%;},
– hvad heller ingen andre standard-kompatible browsere gør.

Hvorfor en højde? Jo, som forklaret ovenfor skal IE have egenskaben hasLayout for at tolke en clear'ing på den måde, vi er ude efter. Og den giver vi elementet via dette hack.

Ovenstående clearfix er opfundet af Holly & John, positioniseverything.net og har vundet betydelig udbredelse, blandt andet hos undertegnede.

Jeg har derfor været lidt i panik i nogle uger, indtil jeg via CSS-Discuss mailing-listen på Ed Eliots weblog fandt en noget lignende fix:

Løsning 5 – ny clearfix

#floatcontainer:after { 
  content: "."; 
  display: block; 
  height: 0; 
  clear: both; 
  visibility: hidden; }
#floatcontainer { 
  display: inline-block; 
  _height: 1%; }
/* Hides from IE-Mac \*/
#floatcontainer { 
  display: block; }
/* End skjul for IE-mac */

Eksempel 7.

Ligheder og forskelle: Den første formdeklaration, der er beregnet på alle “de andre” browsere, er ganske som før og indsætter en usynlig clearfix efter #floatcontainer. Men i stedet for den tidligere metode til at få det til at spille i IE – og som beroede på, at stjerne-hacket, som IE5 og IE6 fejlagtigt læste og dermed sætte en højde på 1 procent på elementet – bruges nu underscore-hacket til samme formål. Det læses af IE5 og IE6, men ikke af IE7 eller af nogen andre moderne browsere i øvrigt.

Vi er nu af hensyn til disse browsere nødt til at sætte display-egenskaben tilbage til block.

Og det er så det.

Hurra!

Hvad er problemet? Jo, det hænger sammen med at alle tidligere versioner af IE tolker en eksplicit højde på et blockelement som en minimumshøjde, mens IE7 fortolker 1 procents højde som – 1 procents højde.

Og det vil smadre de fleste af de websider, jeg har lavet det sidste år eller to.

Clearfix strategi.

Bemærk i ovenstående løsning, at det er selve elementet der får påtrykt dise formregler. I den tidligere version brugte vi en klasse til at bære formreglerne over på elementet.

Vi kan gøre nøjagtigt det samme med disse formregler:

.clearfix:after { 
  content: "."; 
  display: block; 
  height: 0; 
  clear: both; 
  visibility: hidden; }
.clearfix { 
  display: inline-block; 
  _height: 1%; }
/* Hides from IE-mac \*/
.clearfix { 
  display: block; }
/* End hide from IE-mac */

Så jeg kan nu vælge mellem to opdateringsstrategier for, hvad jeg skal tage mig til ind til julen 2006:

  1. Jeg kan finde alle forekomster i mine mange stylesheets (alt for mange, men det er ikke en diskussion, jeg vil indlede her) af formdeklarationer for .clearfix og erstatte dem med den sidst præsenterede udgave. Mine floatcontainere har jo alle i forvejen et class name clearfix. Eller
  2. Jeg kan finde ud af, hvilke id'er mine float-containere har (det har de allesammen, nærmest i sagens natur) og tilføje løsningen fra eksempel 7. Hvis jeg samtidig sletter den gamle clearfix, gør klassenavnet på disse containere jo ingen skade.

Denne side er senest opdateret: 8. January, 2009