HTML5 elementen in Internet Explorer zonder Javascript
geschreven op 23 November 2010
Wanneer je HTML5 voor je website gebruikt, heb je snel door dat Internet Explorer weigert om die geinige nieuwe HTML5 elementen te erkennen en dus ook te stijlen. Ze vallen simpelweg in elkaar, alsof ze nooit bestaan hebben. Dit kan al snel betekenen dat je prachtige website er in Internet Explorer uitziet als een compleet wrak.
Huh? Section element? Wat voor section element? Ik zie geen section element. Geen idee waar je het over hebt. Wat? Nee, ik geloof er niet in. Ga toch fietsen. Ik meen het, vriend. Krijg toch de quirks mode.
John Resig kwam met een slimme oplossing dat een piepklein stukje Javascript gebruikt om Internet Explorer te forceren de nieuwe elementen te accepteren:
javascript:
var a = ['section', 'article', 'nav', 'header', 'footer', ...];
for (var i = 0, j = a.length; i < j; i++) {
document.createElement(a[i]);
}
Helaas is het compleet nutteloos wanneer Javascript uit staat.
En je zult net zien; pas nadat een nieuwe website live staat, belt de klant op die doodleuk zegt dat een van hun "slimme" systeem-beheerders zojuist Javascript permanent uit heeft gezet op alle bedrijfscomputers, en dat 'ie weigert om het weer terug aan te zetten.
Dat betekent dat een alternatieve oplossing nodig is. Die zijn wel te vinden, maar echt prettig of zinvol zijn ze niet. De WhatWG group adviseert het volgende: (vrij vertaald)
- Weet hoe de DOM eruit ziet en richt je op andere elementen dan de nieuwe voor de stijlen.
- Gebruik de universele selector (*) om op het juiste element te richten.
- Gebruik het noscript element.
Mja, geweldige opties. Nou, nee. Dat zijn ze niet.
Allereerst, het richten op andere elementen is niet echt mogelijk. Als het zo simpel was, hadden we dat allang gedaan. Om de stijlen op een parent of child element te richten, hebben we iets er boven of onder nodig dat vrij is van de stijlen die we willen toepassen. Dat betekent dat we ze allemaal in <div> elementen moeten omwikkelen, sinds de originele elementen in elkaar klappen. Grappig, sinds het vermijden van een semantisch betekenisloze onoverzichtelijke spaghetti-boel van <div> elementen, juist een van de redenen is waarom men HTML5 zal gebruiken. Afgezien van de nieuwe mogelijkheden, dan.
Daarnaast is het gebruik van de universele selector niet alleen ontzettend inefficiënt, maar het heeft het potentiëel om een rotzooi van je CSS te maken; je zou goed moeten opletten en de stijlen die het ongedaan maakt op elementen die dezelfde patronen volgen weer ongedaan maken. Binnen de kortste keren is je CSS een rotzooi, helemaal als je probeert teveel classnames of id's te vermijden:
css:
body > footer > p {
font-style: italic;
}
body > * > p {
font-style: italic;
} /* voor IE */
body > ... > p {
font-style normal;
} /* het bovenstaande ongedaan maken voor niet-footer elementen */
Het noscript element is compleet nutteloos in dit geval. We weten al dat de gebruiker Javascript uit heeft staan als de elementen niet goed worden weergegeven. Je kunt de stijlen omhullen in een noscript element, maar Internet Explorer zal de stijlen nog steeds niet toepassen op de elementen die het bewust blijft negeren. Het beste wat je ervan kunt maken, is te proberen niet te veel een troep ervan te maken wanneer je de parent of child elementen probeer te pakken, maar dan kun je het beter gewoon helemaal permanent maken. Een stuk makkelijker onderhouden, zo.
Iemand die Fakedarren heet heeft een andere oplossing in elkaar geknutseld, welke een creatief, doch rommelig gebruik van zgn. "conditional comment tags" laat zien:
html:
<!--[if lt IE 9]><div class="article"><![endif]-->
<!--[if IE 9]><article class="article"><![endif]-->
<!--[if !IE]><!--><article class="article"><!--<![endif]-->
...
<!--[if lt IE 9]></div><![endif]-->
<!--[if IE 9]></article><![endif]-->
<!--[if !IE]><!--></article><!--<![endif]-->
En dat werkt ook. Maar, wees eerlijk, zou je niet liever in je onderbroek naar het werk gaan, voordat je iets als dit gaat gebruiken voor elk HTML5 element dat in je website zit? Het zou van je nette opmaak een gigantische rommel maken.
Gelukkig, je mag je broek aanhouden. Er is een oplossing en is in de praktijk niet zo lastig als het klinkt.
De oplossing
De oplossing is eigenlijk best eenvoudig; zet de nieuwe HTML5 elementen in hun eigen naamruimte. Hierdoor zal Internet Explorer het nalopen (en in elkaar klappen) van de nieuwe elementen achterwege laten en worden ze prima weergegeven. Het is dezelfde manier als gebruikt wordt voor het stijlen van een XML document met CSS en Internet Explorer geeft dat ook prima weer.
html:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:html5="http://www.w3.org/1999/xhtml">
<body>
<html5:section>...</html5:section>
</body>
</html>
Je kunt zowel de namespace als een simpele id of class gebruiken om op te richten:
css:
html5\:section, #element-id, .element-class {
...
}
Let op: Je moet de HTML5 naamruimte globaal instellen. Je kunt deze niet lokaal instellen op bijvoorbeeld een <article> element.
Daarnaast, voor zover ik weet, werkt deze oplossing ook prima voor IE print stijlen, terwijl de javascript methode dat niet doet.
Het voorbeeld
The following sections should all be green:
Standalone XHTML5 example (validates)
Standalone HTML5 example (works, but doesn't validate)
Standalone XHTML5 voorbeeld (valideert wel)
Standalone HTML5 voorbeeld (valideert niet, werkt wel)
Doordat het laatste element in z'n eigen naamruimte zit, past Internet Explorer de CSS toe zoals het hoort. Zie de voorbeelden voor een simpele testcase en blader een beetje in de broncode, als je geïnterreseerd bent.
Hou wel in het achterhoofd dat je de dubbelepunt moet escapen door middel van een backslash \ om een botsing met bijvoorbeeld :hover te voorkomen. Maar, afgezien van het instellen van display: block heb je de namespace methode niet nodig -- id's en classes werken ook prima.
Ook ondersteunt HTML5 dat op deze manier gebruikt wordt officieel geen naamruimtes. Realiseer je hierbij wel, dat de validator je weldegelijk om de oren zal slaan wanneer je probeert om je website te valideren. Er is wat voor te zeggen dat validatie niet uitmaakt, alleen resultaten, maar dat zul je zelf moeten beslissen.
Als je toch echt de validatie wilt doorstaan, dan is dat ook geen probleem. Gebruik gewoon XHTML5 in plaats van HTML5. Nooit van gehoord? Dat is niet erg. Volgens Anne van Kesteren realiseren een hoop mensen zich niet dat HTML5 ook XHTML 1.0 uitbreid; het is simpel een kwestie van je HTML5 uitschrijven op een manier die met XML conformeert.
XHTML5 gebruiken
Voor de duidelijkheid, het is niet verplicht de XHTML5 syntax te gebruiken voor deze methode. Wel is het zo dat het gebruik in HTML5 markup niet valideert, terwijl XHTML5 markup dat wel doet. Het is aan jou om te kiezen welke markup je prefereert; beiden hebben voor en nadelen.
Het gebruiken van XHTML5 betekent dat je nog steeds de nieuwe semantische schoonheid dat HTML5 is hebt, de nieuwe mogelijkheden zoals <video> & <audio> elementen en geolocatie inbegrepen, maar dat je ook van het voordeel (of nadeel, afhankelijk van je perspectief) van streng parsen kunt genieten. Hoe dan ook, de XHTML5 specificatie heeft naamruimtes inbegrepen en dat betekent dat het prima zal valideren.
Om XHTML5 te gebruiken zul je zorg moeten dragen over enkele dingen. Op de server zul je dezelfde stappen moeten volgen als voor XHTML 1.0:
- Configureer de server om application/xhtml+xml te sturen naar moderne browsers en text/html naar Internet Explorer, ook al zijn sommigen van mening dat zoiets schadelijk is. Internet Explorer laat anders niet je pagina zien, maar een bestands-venster.
- Gebruik de XML declaratie:
<?xml version="1.0" encoding="utf-8"?>en zorg dat het gestuurd wordt naar alle browser, opnieuw behalve Internet Explorer. Anders kan dit quirks mode aan zetten in IE6. Behalve, wanneer je klant zich geen zorgen maakt om IE6. Wat hij ook niet zou moeten doen, aangezien het programma meer dan negen jaar oud is.
En in het document is het een beetje anders:
- Gebruik de DOCTYPE; het eerste woord moet in kapitalen geschreven zijn en het moet na de XML declaratie komen:
<!DOCTYPE html> - Definieer de XHTML naamruimte en de XHTML5 naamruimte in je html element:
xmlns="http://www.w3.org/1999/xhtml" xmlns:html5="http://www.w3.org/1999/xhtml"En ja, ze zijn hetzelfde. De browser hoeft alleen te geloven dat de naamruimtes verschillende inhoud bevatten. - Gebruik de HTML5 voorvoegsel met HTML5 elementen:
<html5:section>...</html5:section> - Gebruik de HTML5 voorvoegsel in de CSS voor je HTML5 elementen:
html5\:section { ... }Let erop dat je de dubbelepunten in je CSS escaped met een backslash! - Let erop dat er geen onvolkomenheden in je XHTML zitten, of je zult helemaal geen website zien.
Wanneer je daarmee klaat bent, zal het prima valideren, zoals je kunt zien door deze pagina te valideren in de W3C validator of de .nu validator.
Veel plezier met (X)HTML5.
