Implementační chyby v prohlížečích - double margin a peekaboo bug
25. 02. 2004 | Jan Bien | Webové standardy | Komentáře: 0
V druhém článku ze série o implementačních chybách v prohlížečích poodhalíme dvě nejčastěji řešené chyby, vznikající v Internet Exploreru při použití plovoucích boxů. Jedná se o takzvaný "Peekaboo bug" a problém dvojnásobného okraje (double margin).
Plovoucím boxem rozumíme box, který má nastavenou vlastnost float. Podle specifikace CSS je plovoucí box odsunut k levému nebo pravému okraji výplně obsahujícího boxu. Plovoucí box je vyjmut z toku dokumentu a ostatní bloky se proto formátují stejně, jako by v dokumentu vůbec neexistoval. Jen řádky jsou podle plovoucího boxu patřičně zúženy a říkáme, že jej obtékají.
Peekaboo
Peekaboo je velmi nepříjemná ale řešitelná chyba, jejíž název je složeninou anglického "Peek a boo". Zajímavé na ní je, že se týká jen Internet Exploreru verze 6 ve standardním i kompatibilním režimu, u starších verzí IE se chyba nevyskytuje.
Chybu je možné popsat takto: Jestliže v dokumentu existuje plovoucí box obtékáný odstavcovým textem, a zároveň dolní krana okraje zmíněného plovoucího boxu je níže, než dolní hrana okraje odstavcového textu, pak není odstavcový text vykreslen. Demonstrujme si chybu příkladem:
<html>
<head>
<title>Peekaboo</title>
<style type="text/css">
#sample {
padding : 10px;
color : white;
background-color : black; /* Podmínka vzniku chyby */
}
#floated {
width : 70px;
height : 70px;
float : left; /* Podmínka vzniku chyby */
background-color : #dadada;
}
#p2 {
clear : left;
background-color : gray;
}
</style>
</head>
<body>
<div id="sample">
<div id="floated">
</div>
<div id="p1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam augue. Maecenas pharetra ultrices tellus.
</div>
<div id="p2">
Nunc pretium, odio quis vestibulum pretium, augue mauris iaculis lectus, a placerat nibh ipsum at est. Donec venenatis mi.
</div>
</div>
</body>
</html>
Pohleďme, jak by měl být prohlížečem příklad vykreslen a jak jej vykresluje Internet Explorer 6:
Správné vykreslení příkladu
Vykreslení příkladu v IE6
Na první pohled to vypadá, jako by jeden odstavec v dokumentu chyběl. Pravdou však je, že Internet Explorer v tomto případě chybně vykresluje pozadí nadřazeného bloku později než text, který tím pádem není vidět. O jeho přítomnosti se lze ale snadno přesvědčit pomocí myši tím, že se pokusíme v předpokládaném místě text vybrat:
Výběr textu myší
Zúžíme-li okno prohlížeče tak, aby dolní hrana okraje problematického odstavce byla ve svislém směru textem odsunuta až pod úroveň dolního okraje plovoucího boxu, pak je problematický odstavec v celé své délce vykreslen řádně:
Delší odstavec je vykreslen
Kde je problém
Aby chyba vznikla, musí být splněno souběžně několik podmínek:
- Existuje box (v příkladu pojmenovaný "sample") s deklarovaným pozadím (rodina vlastností
background). Tento box nemá explicitně zadanou šířku (vlastnostwidth) ani výšku (vlastnostheight). - Box "sample" obsahuje plovoucí box (v příkladu pojmenovaný "floated").
- Plovoucí box "floated" je obtékán odstavcovým textem (v příkladu pojmenovaný "p1"), přičemž odstavců může být libovolné množství, nejméně však jeden. Celková výška odstavce či odstavců (včetně okrajů, rámečku a výplně) je menší, než celková výška plovoucího boxu.
- Odstavcový text "p1" je následován elementem s definovanou vlastností
clear. - V hierarchii elementů dokumentu neexistuje mezi elementem generujícím obsahujícím box "sample" a elementem generujícím plovoucí box "floated" další element, který by měl explicitně nastavenou výšku nebo šířku.
Řešení
Známe příčiny i důsledky chyby, takže se můžeme pokusit náš příklad opravit tak, aby k chybě nedocházelo. Možností je více, vybírám jen ty použitelné:
- Přidejme obsahujícímu boxu "sample" deklaraci
width, neboheight. V našem případě přidejme ke stylovému zápisu deklaraci:#sample { width : 100%; }. - Deklarujme u obsahujícího boxu "sample" vlastnost
line-height. V našem případě přidejme ke stylovému zápisu deklaraci:#sample { line-height : 1.2; }. - U odstavcového textu "p1" nastavme vlastnost
positionna hodnoturelative. V našem případě přidejme ke stylovému zápisu deklaraci:#p1 { position : relative; }.
Dvojnásobný okraj
Dvojnásobný okraj, v angličtině "double margin", je chyba Internet Exploreru verzí 5, 5.5 a 6, a to ve standardním i kompatibilním režimu. Chybu lze popsat velmi jednoduše - vlevo plovoucí box má 2x větší levý okraj oproti deklaraci. Analogicky i plovoucí box vpravo má dvojnásobně větší pravý okraj proti deklaraci. Opět bude nejlépe použít příkladu:
<html>
<head>
<title>Double margin</title>
<style type="text/css">
#sample {
background-color : #aeaeae;
border : 2px solid black;
}
#p1, #p2 {
margin-left : 35px;
width : 150px;
border : 2px solid black;
background-color : #dadada;
}
#p1 { float : left; }
#p2 { clear : left; }
</style>
</head>
<body>
<div id="sample">
<div id="p1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</div>
<div> </div>
<div id="p2">
Vestibulum congue convallis ante. Fusce facilisis volutpat nibh.
</div>
</div>
</body>
</html>
Správné vykreslení příkladu
Plovoucí box má v IE dvojnásobný okraj
Řešení
V předchozím článku jsem se zmiňoval o matrjošce, kterou můžeme stejně dobře použít i k ošetření dvojnásobného okraje. U plovoucího boxu nastavíme levý okraj na nulu, v HTML kódu do elementu generujícího plovoucí box vnoříme další blokový element a kýžený okraj nastavíme u něj. Vezměme náš příklad a opravme jej matrjoškou:
<html>
<head>
<title>Double margin - matrjoska hack</title>
<style type="text/css">
#sample {
background-color : #aeaeae;
border : 2px solid black;
}
#p1 div, #p2 {
margin-left : 35px;
border : 2px solid black;
background-color : #dadada;
}
#p1 {
float : left;
width : 185px;
}
#p2 {
clear : left;
width : 150px;
}
</style>
</head>
<body>
<div id="sample">
<div id="p1">
<div>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</div>
</div>
<div> </div>
<div id="p2">
Vestibulum congue convallis ante. Fusce facilisis volutpat nibh.
</div>
</div>
</body>
</html>
Bohužel, matrjoška bývá někdy poměrně těžkopádná (například u obtékaných obrázků). Naštěstí má IE další, v tomto případě velmi příjemnou, vlastnost - deklarujeme-li u plovoucího boxu vlastnost display: inline;, IE u tohoto boxu okraj nezdvojí, a vykreslí jej řádně. Ptáte se, co na to specifikace? V CSS 2.1 je definováno, že až na hodnotu none je vlastnost display u plovoucích boxů ignorována. Jde tedy o čisté řešení bez vedlejších účinků. Náš příklad ošetříme přidáním následující deklarace ke stylovému zápisu: #p1 { display : inline; }.
Myslím, že na jeden článek jsou tyto dvě implementační chyby více než dostačující. Budu však rád, když v komentářích zveřejníte vlastní nápady nebo další známé triky na jejich řešení.
Odkazy, zdroje
- Vlastnost Float - Marek Prokop
- Jak funguje "float" a "clear" - Petr Staníček
- Float - Dušan Janovský (Jak psát web)
- IE6 Peekaboo Bug - Holly 'n John (Position Is Everything)
- Floats, Margins and IE - Steve Clason (Position Is Everything)
- The IE Doubled Float-Margin Bug - Holly 'n John (Position Is Everything)
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Další aktuální články na interval.cz
- Mylné představy o responzivním designu
- WordPress.com – přes 66 milionů blogů ve 120 jazycích
- Redakční systém WordPress: 10 let mezi námi
- Kam se posunula česká e-commerce za posledních 10 let?
- Jak nejrychleji zabezpečit webové stránky
Tematicky související články
- Implementační chyby v prohlížečích - plovoucí prvky a obtékající text
- Implementační chyby v prohlížečích - chybné rozměry boxů
- Časté chyby při vývoji pro mobilní zařízení
- Podpora CSS 3 a HTML 5 v prohlížečích: přehledná tabulka
- Práce s barvami v HTML pro začátečníky
Dejte vědět i ostatním o článku
Diskuse (počet komentářů: 0)
Buďte prvním návštěvníkem, který přidá nový komentář.

