Problemy z przeglądarką IE nie kończą się na zagadnieniach opisanych w poprzednim punkcie. Znacznie poważniejszym problemem jest wspomniany błąd w interpretacji szerokości pudełka. Opis tego problemu znajdziesz pod adresem http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug.
W skrócie, Internet Explorer 5 wyznacza szerokość elementu wyłącznie na podstawie atrybutu width. Prawidłowo: powinien do atrybutu width dodać marginesy, padding oraz obramowanie. Jeśli na przykład w kodzie HTML pojawi się element div:
<div id="tekst"> Lorem ipsum... </div>
opatrzony stylami:
#tekst {
width : 200px;
padding : 50px;
}
to IE5 ustali jego szerokość na 200 pikseli, podczas gdy prawidłowa wartość wynosi 300 pikseli (tj. 200 + lewy padding 50 + prawy padding 50 = 300).
Problem ten dotyczy Internet Explorera 5 (przeglądarka ta ma tylko jeden tryb pracy: quirks mode; nie posiada ona trybu strict mode) oraz Internet Explorera 6 w trybie quirks mode (Internet Explorer 6 w trybie strict mode poprawnie interpretuje szerokość pudełka).
Jakie są konsekwencje tego błędu? Wbrew pozorom dość poważne. Jeśli bowiem zechcesz pracować w trybie strict mode i tworzyć witryny zgodne ze standardami to na przeszkodzie stanie przeglądarka IE5 (wykorzystywana — wg danych z http://ranking.pl — przez 2,7% polskich internautów).
Witryna zgodna ze standardami będzie poprawnie interpretowana przez IE6 zaś błędnie przez IE5. Jak zatem przygotować arkusze stylów, które będą inne dla przeglądarki IE6 (i wszystkich przeglądarek pracujących w trybie strict mode) a inne dla IE5? Czy da się przygotować rozwiązanie powyższego problemu bez stosowania technik po stronie serwera (np. PHP i wartości $_SERVER['HTTP_USER_AGENT'])?
Pierwsze z rozwiązań wykorzystuje skrypt JS. Skrypt zawiera jedną funkcję o nazwie przestyluj(). Funkcja ta jest wywoływana po pobraniu dokumentu, przed wyświetleniem. Dzieje się to dzięki wykorzystaniu zdarzenia onload elementu body:
... <body onload="przestyluj();"> ..
Wewnątrz funkcji odbywa się sprawdzenie. Czy przeglądarka to Internet Explorer:
if (navigator.userAgent.indexOf("MSIE") != -1) {
...
}
Jeśli tak, to dalej sprawdzamy, czy przeglądarka potrafi pracować w trybie strict mode. Fakt ten stwierdzamy porównując document.compatMode z wartością CSS1Compat. Jeśli tak, to podajemy poprawną wartość width wynoszącą 200. W przeciwnym razie (czyli dla przeglądarki IE5) podajemy błędną wartość width równą 300:
if (document.compatMode == 'CSS1Compat') {
//style dla IE w trybie strict (np. IE 6)
var tmp = document.getElementById("tekst");
tmp.style.width = 200;
} else {
//style dla IE w trybie quirks (np. IE 5)
var tmp = document.getElementById("tekst");
tmp.style.width = 300;
}
Oczywiście rozwiązanie takie zadziała offline (nie wymaga ono PHP), pod warunkiem, że włączona jest interpretacja skryptów JavaScript.
Kompletny kod funkcji przestyluj() jest przedstawiony na listingu 1.
function przestyluj()
{
if (navigator.userAgent.indexOf("MSIE") != -1) {
if (document.compatMode == 'CSS1Compat') {
//style dla IE w trybie strict (np. IE 6)
var tmp = document.getElementById("tekst");
tmp.style.width = 200;
} else {
//style dla IE w trybie quirks (np. IE 5)
var tmp = document.getElementById("tekst");
tmp.style.width = 300;
}
}
}
Listing 1. Funkcja przestyluj()
padding-left margin-right border-topDo atrybutów takich możesz odwoływać się w JavaScript pisząc:
tmp.style.padding_left = 8; tmp.style.margin_right = 8; tmp.style.border_top = 8;
Zwróć uwagę, że znak - (dywiz) został zastąpiony przez podkreślenie _. Jest to konieczne, gdyż znak - nie może być — w języku JavaScript — fragmentem identyfikatora. Pełny opis właściwości CSS znajdziesz w dokumencie pt. Document Object Model (DOM) Level 2 Style Specification pod adresem http://www.w3.org/TR/DOM-Level-2-Style.
Notacją alternatywną jest:
tmp.style.border = "1px solid black"; tmp.style.padding = "0px 10px 20px 30px";
Drugim, lepszym, sposobem dostarczenia odmiennych stylów dla IE5 oraz IE6 jest wykorzystanie specjalnych komentarzy HTML interpretowanych wyłącznie przez przeglądarki IE. Komentarz taki przyjmuje postać:
<!--[if gte IE 6]> ... ...zawartość przeznaczona dla ...IE w wersji od 6 wzwyż ... <![endif]-->
lub
<!--[if lt IE 6]> ... ...zawartość przeznaczona dla ...IE w wersji poniżej 6 ... <![endif]-->
Każda inna przeglądarka powinna oba powyższe wpisy potraktować jako komentarze HTML (zwróć uwagę, że są one umieszczone pomiędzy <!-- oraz -->). Natomiast IE (bez względu na wersję) potraktuje je jako instrukcje if. Warunki instrukcji zawierając operatory gte oraz lt. Są to skróty od angielskich terminów greater than or equal (ang. większe lub równe niż) oraz less than (ang. mniejsze niż).
Jeśli więc w dokumencie HTML umieścisz wpisy:
<!--[if gte IE 6]>
<style type="text/css">
#tekst {
width : 200px;
}
</style>
<![endif]-->
<!--[if lt IE 6]>
<style type="text/css">
#tekst {
width : 300px;
}
</style>
<![endif]-->
to przeglądarka IE6 otrzyma poprawną wartość 200, zaś przeglądarka IE5 wartość 300, uwzględniającą błąd wyznaczania szerokości pudełka.