Nespolehlivost Validátoru W3C

…aneb na co je i validátor krátký!
16. 3. 2006

Validátor je sice dobrá pomůcka, která může pomoci odhalit chybu v podobě nějakého neuzavřeného tagu, ale v zásadě se na něj úplně spoléhat nedá. Už Pixy kdysi dávno napsal článek o Spolehlivosti validátoru W3C, kde některé chyby zmiňoval. Já zmíním a vysvětlím další. Ale hned na začátku bych chtěl připomenout, že všechny zde zmíněné chyby nejsou chyby validátoru samotného. Jde o to, že DTD, podle kterého validátor validuje, není schopné pojmout všechny možné výmysly a upřesnění, které obsahuje specifikace samotná. Je to pouze orientační výstup, označí-li validátor vaši stránku za validní, stále ještě nemusíte splňovat všechny možné úskalí specifikace.

Nejdříve tedy chyby, které validátor neodhalí v HTML dokumentu.

Asi nejčastější chyby jsou v hodnotách atributů. Pokud totiž může hodnota nějakého atributu nabývat nějakých rozličných hodnot, je v DTD prakticky nemožné toto vyjádřit. Například zápis barev může být v RGB nebo slovní pojmenování (dle specifikace je to těchto šestnáct barev). Toto nelze v DTD zapsat, proto má třeba atribut color konečnou hodnotu CDATA, tedy prakticky normální text. Takže pokud budete mít v dokumentu tento kód, validátor jej označí za validní:

<body bgcolor="pekelně červená">

Správně by tedy hodnota měla být buď v hexadecimálním zápisu – #RRGGBB – nebo tedy jedna z šestnácti definovaných barev. Další atribut, který je postižen stejným nešvarem je již Pixym zmiňovaný width (a samozřejmě tím pádem také height). Správná hodnota tohoto atributu je buď pouze číslo – v tuto chvíli prohlížeč počítá hodnotu v pixelech (pozor – jednotka px se za hodnotu v HTML nedoplňuje, je to chyba). Druhá možnost je číslo a následný znak procenta „%“. Nyní tedy počítá procentuální šířky a výšky. Díky tomuto procentu ovšem opět musí být konečná hodnota definovaná jako CDATA, nemůže být definovaná jako číslo, neboť znak procenta číslo prostě není. Proto tedy projde i tento zápis:

<img src="obr.gif" alt="" height="jako eiffelovka">

Další takový atribut je určitě rel. Často se totiž používá u odkazů s hodnotou nofollow, čímž chceme strejdovi Googlovi říci, aby daný odkaz nesledoval. Ovšem specifikace se o této hodnotě nezmiňuje, povolené jsou zcela jiné hodnoty. Tudíž používáním rel="nofollow" porušujete specifikaci. Validátor na to opět pochopitelně nepřijde, hodnota je definovaná jako CDATA.

Pokračujeme dále ve výčtu a sice mnohými lidmi tolik nenáviděným atributem target. Ten totiž může obsahovat prakticky libovolný název „framu“, ale může začínat pouze písmenem (a-zA-Z). Dále jsou vyčleněny čtyři hodnoty, které mají speciální význam (_blank, _top, _self a _parent). Ostatní jsou dle specifikace nepřípustné. Validátor opět chybu neodhalí:

<a href="#" target="1. rám">odkaz</a>

Podobných atributů bude nejspíše více (třeba takový atribut styleviz příklad), ale ty nejdůležitější jsem snad již vyjmenoval. Přejděme tedy k jiným „zajímavějším“ chybám.

HTML zná dva docela zvláštní elementy – <ins> a <del>. Tyto elementy se od ostatních liší v tom, že mohou obsahovat jak řádkové, tak blokové elementy a zároveň mohou být vnořeny jak do řádkových tak do blokových elementů. To znamená, že můžete stejně tak vyznačit celý odstavec, jako pouze jedno slovo. Specifikace ovšem praví, že pokud se tyto elementy chovají jako řádkové, nesmí již obsahovat prvky blokové. Bohužel, v DTD to opět nijak vyjádřené není, takže přes tyto dva elementy můžete snadno do řádkového prvku propašovat prvek blokový a validátor je v koncích:

<a href="#">
Odkaz a
<ins>vložený <div>oddíl</div> který tu</ins>

nemá co dělat
</a>

S těmito elementy je ovšem další potíž. Jsou totiž povolené v celém obsahu elementu <body> a to tak, že všude. Ať je tedy zanoříte kdekoliv, vždycky to projde. A to i v případech, kdy by to rozhodně projít nemělo. Takže snadno můžete tyto dvě značky vložit přímo do seznamu nebo přímo do tabulky. Asi nějak takto:

<table>
<ins>kde to jsem?</ins>
<tr>
<td>buňka
</table>

co na to validátor? Příklad se seznamem:

<ul>
<del>jak jsem se tady dostal?</del>
<li>odrážka
</ul>

A chudák validátor opět musí předchozí kód označit za validní.

V sekci <head> také může být přítomen element <object>. Ovšem dle specifikace by neměl obsahovat žádný alternativní obsah, protože v obsahu elementu <head> by prostě žádný obsah na vykreslení být neměl (samozřejmě něco jiného je <title>). Ovšem validátor to opět nepozná a tak si do hlavičky můžete klidně strčit i celou tabulku:

<head>
<title>valid!</title>
<object>
<table>
<tr>
<td>zase jsem někde mimo
</table>

</object>
</head>

Prakticky identický příklad již uváděl Chamurappi. Hezké příklady se dají vymyslet při použití NET. Neboli stručně řečeno – v HTML se dá element zapsat dvěma způsoby:

<strong>důležitý text</strong>

<strong/důležitý text/

Oba příklady jsou validní. Element s prázdným obsahem potom můžeme zapsat buď běžným způsobem <br> nebo pomocí NET – <br/. Situace v prohlížečích je taková, že to nefunguje :-). Ale ve specifikaci to je. Problém nastává, pokud třeba udáváte adresu obrázku a vyskytne se vám v cestě lomítko. Tedy nějak takto:

<img alt="" src=images/image.png>

V HTML je povoleno neuzavírat hodnoty atributů do uvozovek, avšak pouze za předpokladu, že se v hodnotě nevyskytují nějaký klikyháky jako třeba „$“ nebo mezera. Stejně tak se tam nesmí vyskytnout lomítko, protože to lomítko ve skutečnosti uzavírá celý element. Tudíž prohlížeč by měl teoreticky vidět něco takového:

<img alt="" src=images>image.ong>

Ukončovací závorka „>“ se entitami zapisovat nemusí, proto validátor nakonec nezahlásí chybu ani na závorku, ani na klikyhák v adrese, ačkoliv tak, jak to nejspíše autor zamýšlel, to je chybný zápis. Že to opravdu takto funguje si můžete vyzkoušet sami, třeba když přemístíte atribut alt až „za“ adresu, tedy takto:

<img src=images/image.png alt="">

Validátor vyhodí chybu na chybějící atribut alt – ve „skutečnosti“ se již totiž vyskytuje až „za“ obrázkem.

Tak to by již mohlo ohledně HTML stačit a můžeme se směle vrhnout na XHTML, kde se také dají nalézt různé skopičinky.

Takže předně chyba zřejmě největší – XHTML nedovoluje zakázat vnořování elementů do všech úrovní, proto se musel definovat dodatek Bé, kde jsou dodatečně některá prapodivná zanoření zakázaná. Ovšem všechny tyto konstrukce validátorem projdou:

<form action="">

<div>
<form action="">
<fieldset>
<label>jméno<span><label>zase jméno</label></span></label>

</fieldset>
</form>
</div>
</form>

Dávejte si pozor na to, že v tom dodatku Bé nejsou zmíněny již zavržené elementy, takže například XHTML tím pádem povoluje zanořit do <pre> element <basefont>, ač to specifikace HTML zakazuje.

Další chyba je taková, že validátor nijak nekontroluje, zda splňujete směrnici kompatibility, ač v dnešní situaci je ve většině případů nutné tuto směrnici dodržovat. Validátor však nepřijde ani na jednu chybu vůči této směrnici. Jinak chyby ohledně povolených hodnot atributů se v XHTML vyskytují také.

To by bylo prozatím všechno, už mě nic nenapadá :-).

Málem bych zapomněl – většinu zde zmiňovaných chyb odhalí Relaxed validátor od Petra Nálevky.

Další chybku ještě dnes zveřejnil Dero.