Řešení problému s 3px bugem při FLOAT v MSIE - aktualizováno podruhé

<txp:image id=„52“ />

Při přechodu z tabulkového na beztabulkový layout, který je řešený pomocí plovouciho sloupce, se webdesignér začne potýkat se značnými problémy, které souvisí s chybnou implementací kaskádových stylů v prohlížeči Microsoft Internet Explorer.

Obecně se beztabulkový layout (pomocí plovoucího sloupce) řeší následovně:

<style>
 #main {background-color:yellow;width:300px;}
 #left {background-color:blue;width:100px;float:left;}
 #content {background-color:red;margin-left:100px;}
</style>

<div id="main">
 <div id="left">
   navigation<br>
   navigation<br>
 </div>
 <div id="content">
    content content content content content content content
    content content content content content content content
 </div>
</div>

Můžete se podívat na ukázku.

Problém s float v MSIE

Levý sloupec s navigací je plovoucí a má definovanou šířku (v tomto případě 200 pixelů), sloupec s obsahem je o tuto šířku odsazen (jeho pravý okraj má stejnou velikost). Kód funguje ve všech moderních prohlížečích.

ALE je zde problém, že v MSIE se objeví posunutí o velikosti 3px a to pouze tam, kde se nachází levý plovoucí sloupec.

Hledal jsem řešení všude možně a při tom jsem narazil na několik relevantních článků (viz odkazy na kocni článku) ale nejlepší řešení mi dal Martin Snížek ve svém komentáři na Intervalu

Takže řešením je přidat záporný spodní okraj u plovoucího prvku:

#left {background-color:blue;width:100px;float:left;margin-bottom:-500px;}

Podívejte se na opravenou ukázku.

<style>
  #main {background-color:yellow;width:300px;}
  #left {background-color:blue;width:100px;float:left;margin-bottom:-500px;}
  #content {background-color:red;margin-left:100px;}
</style>

<div id="main">
 <div id="left">
   navigation<br>
   navigation<br>
 </div>

 <div id="content">
    content content content content content content content
    content content content content content content content
 </div>
</div>

Chyba lávky!

Ukázka sice funguje skvěle, ale má jeden háček – díky velkému zápornemu spodnímu okraji se šířka levého plovoucího prvku počítá jako NULA, což se projeví v okamžiku, kdy budete chtít přidat patičku – pomocí atributu clear se patička umístí přímo pod konec divu content a to i v případě, že je content kratší než levý sloupec (protože ten má výšku NULA);

Podívejte se na ukázku s patičkou a s delším levým sloupcem.

Patička ignoruje levý sloupec, protože má nulovou velikost

Druhé řešení

Další řešení spočívá v ve vložení pomocného DIVu do contentu a nastavení jeho výšky na jedno procento:

<style>
  #main {background-color:yellow;width:300px;}
  #left {background-color:blue;width:100px;float:left;}
  #content {background-color:red;margin-left:100px;}
  #inner {height:1%;background-color:silver;}
  #footer {background-color:green;clear:both;}
</style>

<div id="main">
  <div id="left">
   navigation<br>
   navigation<br>
   navigation<br>
   navigation<br>
   navigation<br>
  </div>

  <div id="content">
    <div id="inner">
      content content content content content content content
      content content content content content content content
      content content content content content content content
      content content content content content content content
    </div>
  </div>
  <div id="footer">footer</div>
</div>

Ukázka se zdrojovým kódem

Řešení, které není dokonalé

Neptejte se mě proč tomu tak je (je to fígl, na který přišli na webu www.positioni­severything.net. Doporučuji přečíst si jejich článek.

Bohužel stále je tam 3px mezera (akorát nekončí zároveň s levým sloupcem, ale pokračuje až dolů) – prosvítá tam červená barva DIVu content (šedá barva je DIV inner).

Plaváčkovo řešení

Díky Plaváčkovi víme další řešení – popisuje jej v komentáři pod článkem, pro úplnost jsem jej přidal i do článku – včetně obrázku a ukázky:

<style>
  #main {background-color:yellow;width:300px;}
  #left {background-color:blue;width:100px;float:left;}
  #content {background-color:red;margin-left:100px;}
  .fix {width:100%;background-color:silver}
  #footer {clear:both;background-color:brown}
</style>

<div id="main">
  <div id="left">
    navigation<br>
    navigation<br>
  </div>
  <div id="content">
    <div class="fix">
      content content content content content content content
      content content content content content content content
    </div>
  </div>
  <div id="footer">Footer</div>
</div>

Ukázka se zdrojovým kódem

Plaváčkovo řešení

Jeho řešení mi rozhodně přijde čistější – spočívá v použití dalšího pomocného DIVu fix, který má nastavenou stoprocentní šířku – tím se sice zbaví škaredého zubu v místě kde končí levý plovoucí sloupec, ale obsahuje stejný problém, jako předchozí příklad – šířka je zůžena o ony 3 pixely.

Finální řešení? – Nechte všechno plavat!

Asi nejlepší řešení je nechat všechno plavat – tedy ne tento problém, ale oba bloky – levý i obsahový. Vizte ukázku:

<style>
  #main {background-color:yellow;width:300px;}
  #left {background-color:blue;width:100px;float:left;}
  #content {background-color:red;float:right;width:200px;}
  #footer {background-color:brown;clear:both;width:100%;}
</style>

<div id="main">
  <div id="content">
    content content content content content content content
    content content content content content content content
  </div>
  <div id="left">
    navigation<br>
    navigation<br>
  </div>
  <div id="footer">Footer</div>
</div>

Ukázka se zdrojovým kódem

Finální řešení - nechte všechno plavat

Jak vidíte, konečně vše funguje tak jak má, 3px bug prohlížeče MSIE se nekoná a všechny bloky na sebe perfektně – na pixel přesně – navazují. Dokonce to má tu výhodu, že můžete ve zdrojovém kódu uvádět nejdříve blok s obsahem a teprve poté blok s navigací (tedy další plus za přístupnost). Ještě se uvidí, jak se toto řešení osvědčí v praxi.

Pokud víte o jiném, nebo lepším řešením, neváhejte a podělte se, ke zkoušení můžete využít první ukázku.

Odkazy:

Komentáře

1
22 březen 2005, 20:07

Zabírají dvě věci. Za prvé zkusit nastavit bloku, který jeví tendenci obsahovat 3px bug nějakou line-height. Druhé, vždy stoprocentní řešení, je vložení dalšího divu a jemu nastavit šířku width=100%. Sám používám druhé řešení, protože je funkční, bezpečné a většinou se mi i další vnořený blok hodí, protože ho lze využít k definici pozadí a podobně.

 
2
23 březen 2005, 08:16

Myslím, že opravdu přechod na STRICT by prospěl, protože používáte i vyšší styly CSS. Jinak se mrknětě na moji stránku, jak jsem to řešil.

 
3
23 březen 2005, 11:12

Plaváčku díky, tvé řešení funguje, i když jednu mušku má :) – viz aktualizace článku.

Kvetos: Zkoušel jsem, ale vše se chovalo stejně :( Navíc si nejsem jist, zda starší MSIE – verze 5 – podporuje přepínání režimů pomocí DOCTYPE.

 
4
24 březen 2005, 09:29

Starší verze: Právě ten prolog by ti to přepnul do quirk modu, tedy zpět do modu, který podporuje i MSI 5. Proč ale zrovna na to baziruješ. Tento prohlížeč už dnes používá možná 1% uživatelů?

 
5
24 březen 2005, 09:31

Jo, ukázky pod příklady kódů ti nefungují!

 
6
24 březen 2005, 13:16

Kvetos: a já měl pořád nejaké tušení, že jsem na něco zapoměl. Díky za upozornění, už by tam měly být.

A na pětkové verzi bazíruju jednak ze zvyku a jednak ho používá ještě asi 5%, což není až tak málo – viz statistiky:

 
7
nakashi
15 listopad 2005, 20:42

Plaváčku díky, přesně tohle jsem už nějakou dobu hledal, s třípixelovou mezerou budu počítat, hlavně, že tam neni ten zub! :) Jo a přikládám jeden odkaz na problémy box modelu v IE, ale to už stejně všechno znáte, jen tak pro úplnost. :) http://www.digital-web.com/…ompli­ant_ie/

 

Přidej komentář

Pište prosím slušně, s diakritikou a k věci. Dodržujte pravidla a využijte možnosti formátování uvedená pod formulářem.

Email nebude zveřejněn

Pravidla a možnosti formátování

  • Nepoužívejte HTML značky, blog podporuje formátování texy. Nový odstavec získáte 2x odřádkováním, odkaz: "text odkazu":odkaz, **tučně**, *kurzíva*
  • Adresy začínající na http:// budou automaticky převedeny na odkazy
  • Jediné dvě povinné položky formuláře jsou Jméno a zpráva
  • Na předchozí komentáře odkazujte zápisem [2]

 

Sekce