Etiquetas autocerradas y tipo de contenido en XHTML y HTML5
Publicado 2011-08-27 23:15:00 en HTML5
Al escribir XHTML, ¿alguna vez se preguntaron porqué existen etiquetas que pueden autocerrarse mientras que otras no? Me explico:
<!--Una imagen se autocierra--> <img src="foto.png" /> <!--Un div necesita otra etiqueta de cierre--> <div></div>
La explicación es que se suele utilizar el autocerrado en las etiquetas que no admiten contenido. Algunas de ellas son: <br />, <meta />, <img />, <link />, <hr />, <input />.
Sin embargo, en XHTML, técnicamente cualquier tipo de elemento puede autocerrarse y ser válido:
<!--En XHTML podría autocerrar: --> <div /> <p />
A pesar de esto, miren este ejemplo. Notaran que los divs autocerrados aparecen anidados:
¿Raro no? Además, si ven el código fuente, verán que el doctype es XHTML pero aparecen marcas de errores en los divs:

Aclarando el asunto
La realidad es que los navegadores modernos se guían por la cabecera Content-Type que envía el servidor. Si miran nuevamente el ejemplo, pero esta vez revisando sus cabeceras (con Firebug por ejemplo) verán que el tipo es text/html.

Es decir, por mas que se especifique un determinado doctype, lo que predomina es el valor de Content-Type: En el ejemplo, se esta usando la sintaxis válida de XHTML, pero la página es servida como HTML (text/html), entonces el navegador entiende que posee etiquetas inválidas (y por eso mismo se muestran anidados los divs y aparecen las marcas rojas).
Si realmente se quiere utilizar XHTML, lo que se debe hacer es enviar en el Content-Type el valor application/xhtml+xml (o application/xml).
Pero cuidado, hacerlo puede ocasionar dos potenciales problemas:
- IE 6/7/8 no entiende el significado de
application/xhtml+xmly tratará a la página como un archivo descargable, sin mostrar nada. - En caso de existir un error de sintaxis (por ejemplo, una etiqueta mal cerrada) el navegador directamente mostrará el error ya que lo debe tratar al documento como si fuera un XML:

Por las razones anteriores, la mayoría de las páginas son servidas como text/html aún usando sintaxis XHTML.
¿Qué sucede en HTML5 con las etiquetas autocerradas y el tipo de contenido?
La especificación de HTML5 es un poco más flexible, ya que esta pensada para que no existan muchas dificultades en la migración de documentos. Por lo tanto admite muchas reglas de sintaxis de XHTML y HTML.
En el caso de los elementos que no admiten contenido, son válidos estando autocerrados o no:
<!--En HTM5 las dos formas son válidas--> <br> <br />
Con los elementos normales, la especificación dicta una serie de reglas para determinar si los tags de cierre (o de apertura!) pueden omitirse, siendo estas reglas opcionales. Por ejemplo:
A li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element.
Con respecto al Content-Type, para que los navegadores entiendan como deben renderizar el documento, la especificación define que:
- Los documentos escritos con la sintaxis HTML deben ser servidos como
text/html; - Los documentos escritos con la sintaxis XHTML deben ser servidos con
application/xhtml+xmloapplication/xml(y siempre teniendo en cuenta los posibles inconvenientes comentados); - Y también es posible servir los documentos con sintaxis HTML con el tipo de contenido
text/html-sandboxeden el caso que dicho documento contenga contenidos que no son de confianza (como losiframe). Sin embargo los navegadores modernos aún entienden de que trata este tipo de contenido.
¿Qué tipo de sintaxis utilizar en HTML5?
Lo ideal es escribir correctamente HTML/XHTML y servir la página con el tipo de contenido correcto. Tomar una decisión depende de varios factores y de que tan estrictos/cómodos nos sintamos. HTML5 es flexible.
Yendo un poco más en profundidad con otros asuntos de sintaxis en HTML5, particularmente me gusta mucho el estilo descripto en el artículo My Preferred Syntax Style for HTML5 Markup (el cual resumo muy brevemente):
Utilizar lowecase para todo el marcado;
<p class="parrafo"> Un breve <a href="#">ejemplo</a> </p>Siempre utilizar comillas para los valores de los atributos;
<label for="ejemplo">Otro ejemplo</label>
No autocerrar las etiquetas que no admiten contenido;
<input value="Buscar.." name="buscar">
Siempre cerrar las etiquetas que poseen contenido;
<div> <p>Otro breve ejemplo</p> </div>No repetir el valor en los atributos booleanos.
<input type="checkbox" name="ejemplo" disabled checked>
Pero como decía, esta es una preferencia personal, cada uno es libre de seguir sus predilecciones ;)
