Internet Explorer 7 og webstandarderne

Ideen med denne artikel er at opridse forskellene mellem Internet Explorer 7 og tidligere versioner, specifikt IE5/Win og IE6/Win.

Formålet er at nå frem til nogle ideer til, hvorledes vi som websidekonstruktører tackler det faktum, at IE 7 på væsentlige områder opfylder CSS-standarden betydeligt bedre end begge de tidligere versioner.

Hvilken indflydelse har dette på de stylesheet hacks, en del af os har anvendt igennem måske adskillige år?

I beskrivelsen af disse forhold kan jeg ikke undgå at skelne mellem websider, der er forsynet med en standardsættende dokumenttypeerklæring og websider, der er forsynet med en ikke-standardsættende dokumenttypererklæring.

Hvis du ikke ved hvad det er, vil jeg anbefale Martin Hintzmanns artikel DOCTYPE.

Hvis du overhovedet ikke har nogen dokumenttypeerklæring på dine websider, behøver du ikke læse videre. Jeg tvivler på du kan finde brugbare råd i denne artikel.

Det er et kedeligt faktum, at mange af de stylesheet hacks, jeg og andre tidligere har anbefalet, ikke duer længere. Det gælder i særlig grad de hacks, der er baseret på den mangelfulde – i betydningen ikke-eksisterende – fortolkning af kontekstuelle selektorer i IE5 og IE6.

Parent>child selektoren

Eksempel 1 (med standardsættende dokumenttypeerklæring).
Eksempel 1a (med ikke-standardsættende dokumenttypeerklæring).

Som et indledende eksempel vil jeg bruge forældre-barn-selektoren:

#box {
  width:200px;height:100px;
  border:10px solid maroon;
  padding:10px;background-color:#ffcc66;}
                /* #ffcc66 er lys orange (gul) */
                
html>body div#box {
  width:160px;height:60px;
  background-color:#66ccff;} /* #66ccff er lys blå */

Stylesheet'et beskriver en kasse, hvis synlige bredde skal være 200 pixel, nemlig summen af width, padding og border. Den første formdeklaration vil tegne en sådan boks i IE5 og IE6 i quirks modus, men tegne en boks der er 40 pixel for stor på begge ledder i IE6 og IE7 i standard modus. Derfor den anden formregel, hvis hensigt er at passere de korrekte mål til andre browsere, der læser html>body div#box som en ganske normal kontekstuel selektor. Det fungerer fint i IE5, der ikke forstår denne selektor, og derfor ikke læser formdeklarationen. Men her går det allerede galt i IE6, der med en standardsættende dokumenttypedeklaration læser forældre-barn-selektoren.

Jeg kender faktisk websidekonstruktører, der kun kender det ene stylesheet hack, og derfor vedblivende sætter deres websider i quirks modus. Yuck!

Tantek Çelik

Eksempel 2 med standardsættende dokumenttypeerklæring og
Eksempel 2a med ikke-standardsættende dokumenttypeerklæring.

Dette er et såkaldt "High-Pass” filter, der passerer forkerte værdier – ligesom parent>child filteret – til alle browsere, og de rigtige værdier til alle andre browsere end IE5. Det kendes derfor også som IE5 filter.

div#box {
  width:200px;
  height:100px;
  border:10px solid maroon;
  padding:10px;background-color:#ffcc66;
                  /* #ffcc66 er lys orange (gul) */
    voice-family: "\"}\""; 
    voice-family:inherit;
    width:160px;height:60px;
    background-color:#66ccff;/* #66ccff er lys blå */
}

Her kan du se at de sidste fire linier, udover at de ser noget usædvanlige ud, indeholder de samme rigtige formregler, efter at vi først har lavet stylesheet til benefice for IE5.

Det, der sker her, er, at vi anvender en meget sjældent brugt egenskab, nemlig voice-family, med en værdi, der er højst aparte, nemlig strengen "\"}\"";

En fejl i Internet Explorer 5 får netop denne browser – og kun denne – til at standse læsningen af stylesheet'et ved denne streng. Alle andre browsere læser ufortrødent videre og får dermed oplyst nye værdier for de kritiske egenskaber, nemlig width og height.

Det gør Internet Explorer 6 og 7 også – hvis disse browsere vel at mærke har en standardsættende dokumenttypeerklæring. Eksempel 2 vil derfor i Internet Explorer 6 vise en blå boks, der er for lille.

Det er en ualmindelige grim løsning, men den virker fortrinligt. Til denne løsnings fordel taler, at den retter sig specifikt imod Internet Explorer 5, mens Internet Explorer 6 og formodentlig også denne browsers efterfølgere – jf. Microsofts egen redegørelse (http://msdn.microsoft.com/library/) – læser hele stylesheet'et og dermed viser korrekte CSS-kasser.

Alligevel bryder jeg mig ikke meget om metoden. Jeg synes det er lidt unaturligt at lave et stylesheet, der bevidst er forkert, for derefter med nogle tricks at passere rigtige værdier til flertallet af browsere. Det burde være omvendt, hvorfor jeg meget anbefale at man bruger Microofts betingede kommentarer i stedet for:

<!--[if lt IE 6]>
<style type="text/css" media="screen">  
[ IE5-specifikke formdeklarationer ]
}
</style>
<![endif]-->

Tantek Çelik's hack opnåede en vis berømmelse under browserkrigene lige før og omkring årtusindskiftet som en metode til at opnå ensartede skriftstørrelser i Internet Explorer 5 og andre browsere. Metoden, der har fået navn efter dens ophavsmand, Todd Fahrner, passerer font-size:small til IE5/Win, og font-size:medium til alle andre browsere. Årsagen er, er Internet Explorer 5's standard skriftstørrelse er større end andre browseres standard skriftstørrelse.

body, p, th,td, li, dd {
font-size:    small;   /* Forkert værdi 
                          til IE5/Win */   
voice-family: "\"}\""; /* Fortæl IE5/Win 
                          at reglen slutter */  
voice-family: inherit; /* Nulstil egenskaben */  
font-size:    medium; /*  Ønsket værdi til 
                          andre browsere */ }
html>body, html>body div, html>body p, html>body th, 
html>body td, html>body li, html>body dd    {
font-size:    medium; /* Vær rar mod Opera */ }

Ganske som med parent-child hack'et er tiden løbet fra denne metode, og den bør erstattes af

<!--[if IE 5]>
<style type="text/css" media="screen">  
  body, p, th,td, li, dd {
    font-size: small;}
</style>
<![endif]-->

Tantek Çelik forsimplet

Eksempel 3 med en standardsættende dokumenttypeerklæring og
Eksempel 3a med en ikke-standardsættende dokumenttypeerklæring

Tantek's opdagelse af, at kryptiske tegn i css-kodens tekststrenge kan forårsage nogle browsere til at springe visse formregler over, førte til en betydelig kreativitet blandt alverdens websidekonstruktører, og det varede ikke længere før en simplere udgave så dagens lys:

div#box {
  width:160px;
  height:60px;
  background:#66ccff;
  border: 10px solid maroon;
  padding:10px;
  margin-bottom:10px;
  }

div#box {
  \width: 200px; 
  \height:100px;
  \background-color:#ffcc66;
  w\idth: 160px;
  he\ight:60px;
}
  1. Den første formregelblok beskriver, hvorledes det pågældende element skal formateres i browsere, der fortolker CSS-standarden korrekt.
  2. Den anden formregelblok indeholder to gentagelser af de to egenskaber, der bekymrer mig. Den baglæns skråstreg kaldes Escape-tegnet og er det tegn, der sædvanligvis bruges i f.eks. JavaScripts til at indsætte metada i tekststrenge.
  3. Internet Explorer 5 og 5.5 læser de første to linier, der begynder med \-tegnet, men læser ikke de to følgende linier, der har \-tegnet inde i egenskabens navn. Disse linier læses imidlertid af Internet Explorer 6 og alle andre moderne browsere.
  4. Dermed har vi nået, hvad vi ønskede: At præsentere de nødvendige “forkerte” oplysninger til Internet Explorer 5.

Der er nogle få og simple regler at holde sig for øje ved brugen af dette trick:

  1. Der må ingen steder være mellemrum mellem bogstaverne i egenskabens navn og \-tegnet.
  2. \-tegnet må ikke stå foran bogstaverne a, b, c, d, e, f i de to sidste linier, idet en browser så vil fortolke det som en hex-kode. Det er derfor \-tegnet forekommer før i'et i den sidste formregel.

Og igen, brug hellere:

<!--[if lt IE 6]>
<style type="text/css" media="screen">  
div#box {
  width: 200px; 
  height:100px;
  background-color:#ffcc66;}
</style>
<![endif]-->

Underscore-hack

Eksempel 4 med en standardsættende dokumenttypeerklæring og
Eksempel 4a med en ikke-standardsættende dokumenttypeerklæring

De ovenfor nævnte stylesheet hacks har alle at gøre med forskellene på forskellige versioner af Internet Explorer. Hvis du undlader at bruge disse hacks, og i stedet, som jeg anbefaler, bruge Microsofts betingede kommentarer, får du ingen problemer hverken nu eller i fremtiden.

Det forholder sig lidt anderledes med nogle af hacks, der fuldstændigt skiller fårene fra bukkene, det vil sige – passere nogle formregler kun til IE/Win og ikke til andre browsere.

Et godt eksempel på et sådant hack er underscore-hacket. Underscore er det engelske ord for understregning, så en formdeklaration som

p {
  color:green;
  _color:red;
}

– vil kolorere tekstasfnit grønne i standardkompatible browsere, men røde i Internet Explorer 5 og 6. Men altså ikke i Internet Explorer 7.

_color:red er en lovlig formregel i hehold til CSS2.1 specifikationen. Der er bare indtil videre ingen egenskaber med navne, der starter med denne understregning. Der er i hvert fald ingen egenskab, der hedder _color, så formreglen _color:green ignoreres af standardkompatible browsere – samt af Internet Explorer 7.

Og så må vi igen ty til teknikken med de betingede kommentarer:

<!--[if lt IE 7]>
<style type="text/css" media="screen">  
p { color:red; }
</style>
<![endif]-->

Star-hack

Eksempel 5

Stjerne-hacket, der hyppigst antager formen

div#box {
  background:#66ccff;}/* #66ccff = blå */
* html div#box {  background:#ffcc66;} 
	/* #ffcc66 = orange*/

– vil kolorere elementet #box blåt i alle andre browsere end IE. IE 5 og 6 vil imidlertid vise en gul kasse, idet disse browsere læser den nederste formdeklaration som om der stod html div#box.

Hvis man skal forklare den nederste formdeklaration i ord, står der det, at html-elementet er efterkommer af et andet element, repræsenteret ved stjernen. Det er ikke muligt i et dokument, der er formateret i henhold til CSS-standarden. I et sådant dokument skal html-elementet være rod-elementet. I en browser, der overholder standarden, har denne formdeklaration derfor ingen virkning. Det gælder også Internet Explorer 7.. Derimod vil IE5 og IE6 håndtere formdeklarationen som en udvælgelse af div#box-elementet og give denne kasse en gul bagrundsfarve.

For mig og en hel del andre har netop stjernehacket haft stor betydning i forbindelse med stylesheet hacks rettet mod specifikke IE/Win CSS tolkningsfejl. Jeg har derfor nogen tid før denne artikel skrevet en separat artikel om dette emne: Stjerne-hacket.

Man kan forestille sig, at vi kan fortsætte med at bruge stjerne-hacket som et mid-pass filter til at passere formdeklarationer til IE5 og I6, som er anderledes end de formdeklarationer, der skal passeres til IE7. Det gælder i øvrigt også underscore filteret, som jeg beskriver ovenfor.

Så vidt jeg lige kan gennemskue vil dette behov kun eksistere for dem, der laver websider med en ikke-standardsættende dokumenttypeerklæring med den hensigt at sætte IE i quirks modus – der også kan benævnes IE5 modus.

Og så kan det være lidt lige meget, for sådanne sider kan på ingen måde laves så vi udnytter det faktum, at en række selektorer og egenskaber i IE7 tolkes i overensstemmelse med CSS-standarden.

Links til andre sider

Internet Explorer 7 har nu i mange måneder været tilgængelig i beta-versioner og mens jeg skriver dette i en Release Candidate 1 version. Mange websidekonstruktører har derfor i nogen tid beskæftiget sig med disse og lignende problemer, også mere grundigt end undertegnede. Her er nogle links:

Download IE7RC1
Microsofts weblog om CSS understøttelsen i IE7
Opskrift på at have flere samtidige versioner af IE.
Opskrift på IE7RC1 som standalone (ved siden af IE6).

Denne side er senest opdateret: 10. November, 2006