Double margin chyba pri floatovaných elementoch a Internet Explorer 6

Double margin chyba pri floatovaných elementoch a Internet Explorer 6

Testovanie pre Internet Explorer 6 je v našich končinách stále nutným zlom. Zabezpečiť, aby sa webstránky zobrazovali správne v IE6  je pri dobrom chápaní fungovania jeho špecifických bugov pomerne jednoduché – treba sa skrátka pri kódovaní vyvarovať špecifických nastavení a štýlovania.

Jedným zo známych problémov je takzvaný Double margin bug, teda chyba dvojitého okraja.

Tento bug spôsobí, že floatovaný element s nastaveným marginom v smere floatu je v IE6-tke zobrazený s marginom dvojnásobným. Tým sa spravidla rozbije celý dizajn a chybu treba pre IE6 vyriešiť.

Čo je double margin bug

Predstavme si, že máme v nejakom kontajneri (vonkajšom dive #container) vnútri element floatovaný doprava (napríklad ďalší div, #right). Floatovaný element chceme odsadiť od pravého okraja vonkajšieho elementu o 20 px:

Normálne zobrazenie marginu 20px

Jednoducho teda nastavíme pre vnútorný element

margin-right: 20px;

a tešíme sa, keďže vidíme, ako sa stalo presne to, čo sme prehliadaču zadali – odsadil vnútorný element sprava o 20 px od vonkajšieho elementu.

Lenže – ako správni kóderi, čo neustále testujú, sa na zadaný layout pozrieme v Exploreri 6 a uvidíme toto:

Zobrazenie s double-margin chybou v IE6

Internet Explorer 6 namiesto nami zadaného marginu 20 px zobrazuje 40 px. Tento bug sa objavuje pri floatovaní doprava aj doľava. Zobrazí sa na elemente, ktorý je priamo pri okraji vonkajšieho elementu, v ktorom sa nachádza. Ak by sa v tom istom riadku floatovaných elementov vyskytovali ďalšie floatované elementy, dvojitá chyba sa na nich už nevyskytne. Chyba sa vždy prejaví na margine, ktorý je v smere floatu.

Tu si môžete pozrieť demo double-margin bugu. Samozrejme, potrebujete Internet Explorer 6.

Kde sa s touto chybou môžeme stretnúť a prečo nám vadí

Môžeme si povedať, no a čo? Tak je pri nejakom div-e o 20 px viac, na obrázku vyššie to zas nijako tragicky nevyzerá.

Vzniknutý problém možno najlepšie pochopiť na konkrétnom príklade.

Predstavme si, že robíme dvojstĺpcový layout stránky. Vonkajší div #container obaľuje dva floatované vnútorné div-y, #left a #right. Vnútorné div-y chceme odsadiť od okraja vonkajšieho div-u.

Dvojstĺpcový layout s floatovanými elementami

Double-margin chyba má teda šancu prejaviť sa dokonca dvakrát – pri ľavom floate aj pravom floate.

Aby sme sa nerozprávali len teoreticky o nejakých obdĺžnikoch v iných obdĺžnikoch, aplikujme túto schému na skutočnú stránku, ktorá obsahuje v ľavom stĺpci menu s bannermi a v pravom stĺpci text:

Layout stránky s floatovanými elementami

Kliknite na obrázok pre zväčšenie na výšku obrazovky, alebo otvorte klasicky v novom okne pre plnú veľkosť (cca 900 kB). Použitý screenshot je zo stránky www.goskivancouver.com

Zjednodušené HTML relevantnej časti stránky môže vyzerať takto:

<div id=“container“>
      <div id=“left“>
            menu a bannery
      </div>
      <div id=“right“>
            text
      </div>
</div>

Príslušné CSSká potom vyzerajú takto:

#container {width: 810px;}

#left {
      float: left;
      width: 210px;
      margin: 20px 0 20px 20px;
}

#right {
      float: right;
      width: 540px;
      margin: 20px 20px 20px 0;
}


Ak by stránka mala floatované objekty jednoducho odsadené od okraja pravým a ľavým marginom ako v uvedenom kóde, pri otvorení v Exploreri 6 by stránka vyzerala takto:

Layout stránky s floatovanými elementami a marginom v IE6

Problém je teraz zrejmý – ak sa zobrazia oba floatované elementy s dvojnásobným marginom, vo vonkajšom elemente už skrátka na oba elementy nie je miesto. Div-y #left a #right sa teda zarovnajú pod seba, lebo inak sa do #containera nezmestia. Stránka je teda v IE6 rozbitá.

Čo s tým?

Pozrime sa na dve jednoduché riešenia (a ich problémy):

  • použitie CSS hacku na ošetrenie pre IE6
  • použitie paddingu namiesto marginu

Použitie CSS hacku na ošetrenie pre IE6

Veľmi jednoduchý spôsob ako tento bug ošetriť špecificky pre IE6 je použiť CSS hack na došpecifikovanie marginu pre Explorer 6.

CSS hack, ktorý umožňuje štýlovať elementy špecificky pre IE6 je podčiarkovník pred definíciou štýlu.

Teda CSS zápis:

#right {
      margin: 20px 20px 20px 0;
      _margin-right: 10px;
}

znamená, že bežné prehliadače zobrazia okolo objektu margin 20 px zhora, 20 px sprava, 20 px zdola a 0 px zľava. Explorer 6 si však prečíta aj dodatočnú informáciu a margin sprava upraví na 10 px. Teda polovičnú hodnotu od normálne hodnoty pre ostatné prehliadače.

Zdvojenie marginu teda zrazu nevadí - keďže sme ho umelo zmenšili na polovicu, po zdvojení sa zrazu správa presne tak, ako chceme – zobrazí 20 px.

Samozrejme, treba dodržať kaskádovitosť CSSiek – najprv uviesť hodnotu pre všetky prehliadače, až potom dodefinovať špeciálnu hodnotu pre IE6.

Ostatné prehliadače definíciu za podčiarkovníkom ignorujú, vedia totiž, že podčiarkovníkom žiadna CSS vlastnosť nezačína a teda ich tento zvláštnu súbor znakov vo vašom CSSku nezaujme a preskočia ho. :)

Tu práve narážame na jeden z problémov, ktorý pri tejto metóde môže niekomu vadiť – takéto CSS nie je valídne podľa špecifikácie. K žiadnemu skutočnému problému však z tohto ohľadu nedochádza, validita CSS preto v tomto prípade ustúpi korektnému zobrazovanie stránky v IE6.

Ďalší z problémov tejto metódy môžeme ilustrovať priamo na príklade CSSiek:

#right {
      margin: 0 17px 0 0;
      _margin-right: ???;
}

Čo urobíme v prípade, že číslo, o ktoré potrebujeme div odsadiť, nie je deliteľné dvoma? Aj jeden nesediaci pixel nám môže rozbiť dizajn, či už len vizuálne, prerušením rovnej línie, alebo aj prakticky tým, že sa div-y nebudú do seba zmestiť.

Preto radšej použime druhú jednoduchá metódu na odstránenie double-margin chyby – úplne sa jej vyhnime.

Použitie paddingu namiesto marginu

Na odsadenie elementov od okraja  vonkajšieho div-u môžeme použiť niečo úplne iné ako margin. A to padding. Paddingom môžeme div-y odsadiť tak, že ho aplikujeme na ne, alebo ešte menej riskantne tak, že padding aplikujeme na vonkajší div #container, do ktorého sú zabalené.

Naše HTML:

<div id=“container“>
      <div id=“left“>
            menu a bannery
      </div>
      <div id=“right“>
            text
      </div>
</div>

CSSká s využitím paddingu:

#container {
      width: 810px;
      padding: 20px 20px 20px 20px;
}

#left {
      float: left;
      width: 210px;
      margin: 0;
}

#right {
      float: right;
      width: 540px;
      margin: 0;
}

Padding v containeri nastavíme ako potrebujeme. Floatované elementy teraz žiaden margin nemajú a double-margin chyba sa teda nemá kde prejaviť. Napriek jednoduchosti tohto riešenia sa často najmä začínajúci dizajnéri s double-margin chybou dlho moria a skúšajú na ňu rôzne finty.

Toto riešenie samozrejme nie je aplikovateľné univerzálne, keďže niekedy nám množstvo ostatných elementov na stránke zabráni použiť jednoznačne paddingy na vonkajší element.

Záver

Predvídanie double-margin chyby pri kódovaní stránky a implementácia vhodného CSS často šetrí prácu a čas pri následnom debuggovaní a prerábaní nevhodne vyrobených grafických elementov. Už pri rozhodovaní ako nasekať grafiku, je často dôležité túto chybu predvídať a pozadia floatovaných a vonkajších elementov vyrobiť tak, aby sa stránka dala efektívne poskladať bez použitia CSS hackov.

Ak používate nejaké iné metódy na vysporiadanie sa s IE6 double margin chybou, dajte nám vedieť v komentároch. :)

Skôr ako začneme: nahliadnite do spracovania vašich osobných údajov

Súbory cookies používame najmä na anonymnú analýzu návštevnosti a vylepšovanie našich web stránok. Ak si nastavíte blokovanie zápisu cookies do vášho prehliadača, je možné, že web sa spomalí a niektoré jeho časti nemusia fungovať úplne korektne. Viac info k spracúvaniu cookies.