Implementační chyby v prohlížečích – double margin a peekaboo bug
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
position
na 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.
Mohlo by vás také zajímat
-
10 nejpopulárnějších programovacích jazyků a jejich využití
9. listopadu 2023 -
Užitečné nástroje pro bezpečnost na internetu
17. října 2024 -
Jak vybrat doménu: Co je dobré vědět?
2. září 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024