1   2   3   4   5   6   7   8 

Quirks mode, strict mode — dwa tryby pracy przeglądarek internetowych

Współczesne przeglądarki internetowe posiadają dwa tryby pracy: quirks mode (ang. tryb wstecznej zgodności, tryb dziwactw) oraz strict mode (ang. tryb standardów). Myśląc o tworzeniu witryn zgodnych ze standardami powinieneś uwzględniać tryb pracy przeglądarki.

01/01/07

1. Tryby pracy przeglądarek

Przeglądarki internetowe posiadają dwa tryby pracy: tryb quirks mode oraz tryb strict mode. Terminy te są tłumaczone w interfejsie przeglądarki Firefox jako tryb standardów oraz tryb wstecznej zgodności. Można powiedzieć, że tryb quirks mode jest przeznaczony do interpretacji starych witryn niezgodnych ze standardami, zaś tryb strict mode — do interpretacji witryn przestrzegających standardów W3C. Różnice interpretacji witryn WWW w obu trybach dotyczą wyłącznie arkuszy stylów CSS.

Oba tryby są konieczne i występują we wszystkich przeglądarkach. Obecność trybu quirks mode jest wymuszona przez ogromną ilość stron WWW, które były przygotowane w czasach, gdy standardy sieciowe dopiero powstawały. Witryny takie:

Dla przeglądarki nie pozwalającej na odwiedzanie witryn niezgodnych ze standardami niedostępna byłaby większa część internetu. Takie oprogramowanie byłoby bezużyteczne.

Z drugiej strony tryb strict mode przeglądarek jest odbiciem powolnej ewolucji sieci WWW w kierunku przestrzegania standardów. Wykonanie witryny zgodnej ze standardami i całkowite przystosowanie jej do trybu quirks mode zupełnie mijałoby się z celem.

Najprawdopodobniej liczba witryn zgodnych ze standardami będzie w ciągu najbliższych lat rosła. Czy jednak w przyszłości nastąpi całkowite przejście na tryb strict mode (do tego stopnia, że tryb quirks mode zniknie z przeglądarek)? Z racji na ilość witryn, jakie należy poddać aktualizacji, raczej nie jest to perspektywa najbliższych kilku lat. Chociaż należy zauważyć, że główny czynnik wstrzymujący przejście na tryb strict mode przestaje mieć znaczenie. Czynnikiem tym jest procent przeglądarek wymagających przystosowania witryn do quirks mode. Według najnowszych badań dostępnych na witrynie http://www.ranking.pl przeglądarki wspierające strict mode stanowią 92,1% (MSIE 6.x, Firefox 1.x, Opera 9.x).

Dodam jeszcze, że w obydwu tych trybach przeglądarka ignoruje wszelkie błędy HTML oraz CSS. Praca w trybie strict mode nie oznacza, że przeglądarka informuje o błędach. Różnica pracy w obu trybach polega na tym, że w trybie strict mode interpretacja CSS będzie (lub być powinna) zgodna z ustaleniami zawartymi w specyfikacjach dostępnych na stronie W3C. Natomiast w trybie quirks mode wystąpi wiele różnic, których istnienie ma podłoże historyczne.

2. Przykładowe różnice w interpretacji CSS w trybach quirks mode oraz strict mode

Przykładowe różnice w interpretacji stylów CSS to:

Pierwszy problem polega na tym, że wpis:

div {
    width  : 100px;
    margin : 20px;
}

będzie błędnie interpretowany przez IE5 oraz IE6 (ale tylko w trybie quirks mode). IE5 ustali faktyczną szerokość elementu na 100, podczas gdy prawidłowa wartość powinna wynosić 140 (100 + lewy margines 20 + prawy margines 20).

Drugi problem polega na tym, że wyśrodkowanie elementu blokowego wykonywane prawidłowo:

margin : 0 auto;

nie zadziała w IE5. W przeglądarce tej należy użyć atrybutu:

text-align : center;

Wreszcie trzeci problem, wyświetlanie obrazków, dotyczy wielu przeglądarek, nie tylko IE. Element img, który pierwotnie był elementem blokowym, po wprowadzeniu stylów CSS został przemianowany na element tekstowy. Pod obrazkami pojawiła się kilkupikselowa pozioma przerwa. Wynika to z tego, że wysokość elementów tekstowych jest tak dobrana, by w linii zmieściły się litery takie jak j, p, czy g sięgające poniżej linii centralnej tekstu. Problem ten rozwiążemy zmieniając typ elementu img:

img {
    display : block;
}

lub wysokość linii elementu blokowego, w którym obraz został umieszczony:

line-height : 0;

3. Problemy z trybami pracy

Głównym zmartwieniem jest to, że ta sama witryna może wyglądać inaczej w tej samej przeglądarce. Nie mówię tutaj o zmianie wersji przeglądarki. O tym wiemy wszyscy, że przy przejściu z numeru IE5 do IE6 należy spodziewać się różnic. Mówię o tym, że ta sama witryna może inaczej wyglądać wyświetlana w trybie strict mode w IE6 oraz w trybie quirks mode w IE6.

Czyli do całego galimatiasu przeglądarkowego należy doliczyć jeszcze jeden czynnik: tryb pracy. Czynnikami, które mogą wpływać na wygląd witryny są więc:

Czy zdarzyło Ci się kiedyś deja-vu: strona, która przed sekundą wyglądała poprawnie, bez wprowadzania jakichkolwiek zmian w stylach czy w kodzie HTML nagle się rozjechała? Ja z tym problemem spotkałem się już kilkukrotnie, za każdym razem kosztowało mnie to wiele dodatkowej pracy. Plik CSS — bez zmian. Plik HTML — prawie bez zmian. A układ rozjeżdża się.

Winny był właśnie tryb pracy przeglądarki. Witryna, która poprawnie wygląda w trybie strict mode może rozjeżdżać się w trybie quirks mode. I na odwrót. Zatem badając wygląd witryny, trzeba mieć na uwadze tryb pracy przeglądarki.

4. Jak stwierdzić tryb pracy przeglądarki?

Tryb pracy przeglądarki możemy stwierdzić wykorzystując skrypt JavaScript. Jeśli w dokumencie HTML umieścisz kod:

<script type="text/javascript">
    alert(document.compatMode);
</script>

to ujrzysz komunikat informujący o trybie pracy przeglądarki podczas interpretacji tego konkretnego dokumentu. Komunikat CSS1Compat oznacza, że dokument jest interpretowany w trybie standardów (strict mode). Natomiast komunikat BackCompat oznacza, że przeglądarka działa w trybie wstecznej zgodności (quirks mode).

Rozwiązanie takie zadziała w przeglądarkach:

natomiast nie zadziała w IE5.

Dodatkowo, korzystając z Firefoxa możesz posłużyć się oknem dialogowym Narzędzia → Informacje o stronie. Rysunek 1 przedstawia informacje o witrynie interpretowanej w trybie strict mode (Tryb standardów). Natomiast rysunek 2 przedstawia informacje o witrynie interpretowanej w trybie quirks mode (Tryb wstecznej zgodności).

Rysunek 1. Informacje o stronie interpretowanej przez Firefoxa w trybie strict mode (Tryb standardów)

Rysunek 2. Informacje o stronie interpretowanej przez Firefoxa w trybie quirks mode (Tryb wstecznej zgodności)

Zaletą tego rozwiązania jest fakt, że nie musisz wprowadzać jakichkolwiek zmian w kodzie HTML. Dzięki temu, możesz zbadać tryb wyświetlania dowolnej witryny w internecie (a nie tylko stron tworzonych przez Ciebie).

5. W jaki sposób przeglądarka wybiera tryb pracy?

Do tego służy element DOCTYPE. Technika taka jest nazywana w terminologii anglojęzycznej doctype switching lub doctype sniffing. Brak elementu DOCTYPE wymusza tryb quirks mode. Jeśli zatem przyzwyczaiłeś się do pomijania DOCTYPE, to pora zmienić nawyki. Pomijając DOCTYPE tworzysz witryny, które są interpretowane w trybie quirks mode, a co za tym idzie wszelkie rozwiązania HTML/CSS będziesz musiał ponownie zweryfikować w trybie standardów.

W zależności od stosowanego elementu DOCTYPE różne przeglądarki mogą pracować w różnych trybach. Najprostszą regułą jest:

Oto pełna postać elementu DOCTYPE języka XHTML 1.0 strict:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Bardziej skomplikowane reguły przełączania trybów różnych przeglądarek znajdziesz pod adresem http://hsivonen.iki.fi/doctype/. Co ciekawe, nowe, nieznane elementy DOCTYPE włączają tryb zgodności ze standardami.

Pamiętaj, że wybór trybu pracy przeglądarki dotyczy wyłącznie dokumentów opatrzonych nagłówkiem Content-Type: text/html. Dokumenty o nagłówku Content-Type: application/xhtml+xml są zawsze interpretowane w trybie standardów.

6. Problemy z IE

Przeglądarka Internet Explorer wymaga, by element DOCTYPE był pierwszym elementem na stronie WWW. Jeśli przed DOCTYPE umieścisz jakikolwiek komentarz HTML:

<!--  opis strony  -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
...

lub znacznik XML:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
...

to Internet Explorer będzie pracował w trybie quirks mode. Musisz zatem pilnować, by przed DOCTYPE nie umieszczać żadnych wpisów (przynajmniej w wersji wysyłanej do IE).

7. Problemy z różnicami IE5/IE6

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'])?

7.1 Rozwiązanie pierwsze: zmiana atrybutów CSS w JavaScript

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()

Niektóre atrybuty CSS posiadają dwuczłonowe nazwy. Separatorem członów jest dywiz (czyli znak -), np.
padding-left
margin-right
border-top
Do 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";

7.2 Rozwiązanie drugie: komentarze HTML będące instrukcjami dla IE

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.

Przeglądarka IE5 uruchamiana na komputerze, na którym zainstalowana jest również wersja IE6, przedstawia się jako IE6. Rozwiązanie stosujące komentarze <!--[if ...]> oraz <![endif]--> będzie sprawiało wrażenie błędnego. W celu oceny faktycznego zachowania opisanej sztuczki należy ją przeanalizować na komputerze, na którym jedyną zainstalowaną przeglądarką IE jest wersja IE5.

8. Podsumowanie

Jeśli myślisz o tworzeniu witryn zgodnych ze standardami, to powinieneś zwrócić uwagę na tryb pracy przeglądarki. Myślą przyszłościowo rozsądnym rozwiązaniem wydaje mi się przygotowywanie witryn, które będą interpretowane (przez wszystkie nowe przeglądarki) w trybie standardów (strict mode).

Jeśli duży procent odwiedzin odbywa się przy użyciu przeglądarki IE5, to problem z wyznaczaniem szerokości pudełka rozwiążesz stosując specjalny skrypt JS lub komentarze będące instrukcjami if dla IE.

Pamiętaj, że jeśli wykonywane przez Ciebie witryny są interpretowane w trybie quirks mode, to nie zbliżasz się do standardów. Przekształcenie witryny poprawnie wyglądającej w trybie quirks mode, tak by była ona interpretowana w trybie strict mode może wymagać (szczególnie w odniesieniu do IE) wiele pracy.

lp. Przykład
1. Wszystkie przykłady

Tabela 1. Przykłady do pobrania

lp. Adres
1. quirksmode — strona Petera-Paula Kocha
2. Quirks mode and strict mode
3. Strona domowa Henri Sivonena
4. Activating the Right Layout Mode Using the Doctype Declaration
oraz
Browser comparison chart
5. BoxModelHack
6. Internet Explorer Box Model Bug
7. Mozilla's Quirks Mode
8. Mozilla Quirks Mode Behavior
9. Mozilla: quirks.css
10. Przeglądarki: porównanie
11. Silniki przeglądarek
12. Przeglądarki
13. Strona domowa Tanteka Celika
14. MSDN: Measuring Element Dimension and Location
15. MSDN: CSS Enhancements in Internet Explorer 6
16. MSDN: !DOCTYPE
17. MSDN: Building ASP.NET 2.0 Web Sites Using Web Standards
18. W3C: dokumentacja DOM (padding_left)

Tabela 2. Adresy

 1   2   3   4   5   6   7   8