Le differenze sostanziali riguardano soprattutto la sintassi, il modo in cui tag, attributi e valori vengono usati. Le esamineremo ora una per una, proponendo sempre il confronto con HTML. Attenzione: l'uso di queste convenzioni è normativo. XHTML è un'applicazione XML e alla sintassi di questo deve conformarsi. Non rispettare queste regole significa non avere documenti validi e ben formati. La cosa che le accomuna è che queste regole pongono fine ad una serie di procedure che HTML consentiva e che ora sono invece vincolate ad usi ben definiti.
HTML <b><i>un test</b></i>
XHTML <b><i>un test</i></b>
Il primo esempio non è corretto in XHTML. Il tag <i> si sovrappone a <b>. La seconda colonna mostra invece un corretto annidamento degli elementi. La prima pratica è consentita in HTML. Certo, il browser dovrà interpretare qualcosa che è ambiguo, ma alla fine ci restituirà un testo in grassetto-corsivo (ciò che volevamo). In XHTML non possono sorgere ambiguità, tutto segue una regola.
XML è un linguaggio case sensitive. Significa che <table> e <TABLE> sono cose diverse. In XHTML è consentito solo l'uso delle minuscole per i nomi di elementi e attributi. Anche qui regole più vincolanti.
HTML <TABLE><TR><TD>un test</TD></TR></TABLE>
XHTML <table><tr><td>un test</td></tr></table>
HTML
<p>Test1
<p>Test2
XHTML
<p>Test1</p>
<p>Test2</p>
In HTML la pratica esposta è tollerata, in XHTML non lo è. Ogni elemento non vuoto (sono quelli che contengono testo o altri elementi) deve avere dopo il tag di apertura quello di chiusura.
Anche questa pratica è tollerata in HTML. E, soprattutto, è causata da molti editor che la "dimenticano" con molta disinvoltura.
HTML <img src=test.gif>
XHTML <img src="test.gif">
Alcuni attributi di HTML non hanno un valore (si dice che sono standalone). E' il caso dell'attributo selected usato per identificare l'opzione di un menu a tendina selezionata all'apertura del documento. In XHTML anche questi attributi devono essere valorizzati.
HTML <option selected>test</option>
XHTML <option selected="selected">test</option>
Il problema si pone anche nei form. Se ad esso non si assegna un'azione avremo questa situazione:
<form action=""></form>
Si può risolvere assegnando un valore fittizio:
<form action="action"></form>
In XML tutti i tag devono essere chiusi. Ma cosa fare con gli elementi vuoti? Si tratta di quelli che non possono contenere nulla al loro interno ma semplicemente ricevere attributi: <meta>, <br>, <hr>, <img> sono i più comuni. In XHTML tali elementi vengono chiusi terminando la dichiarazione con />.
HTML
<br>
<img src="test.gif">
XHTML
<br/>
<img src="test.gif"/>
Per identificare un elemento si deve usare l'attributo id e non name. Apparantemente la cosa non fa una grinza. In questo modo si ha una perfetta conformità con XML dove id è l'attributo standard per l'identificazione dei frammenti. In realtà qui il cambiamento con HTML è notevole, perchè per elementi come <img> o <a> l'attributo di identificazione è proprio name. Il passaggio a id non pone problemi nei browser più recenti, ma con altri (Netscape 4, per esempio) non funziona. In questo caso e se la compatibilità all'indietro è assolutamente necessaria, la stessa specifica XHTML 1.0 suggerisce di usare entrambi gli attributi, anche se ciò è contro le regole:
HTML
<a name="test>
XHTML
<a id="test">
Per compatibilità:
<a id="test" name="test">
Nelle specifche successive (cosa che è accaduta con XHTML 1.1) l'attributo name è stato abolito completamente.