Puede parecer una pregunta tonta, pero tiene más "miga" de la que parece.

code-html-Hace ya unos cuantos años, cuando vio la luz la anterior versión de HTML, "lo más de lo más" por aquel entonces era el lenguaje XML. Estábamos en los tiempos de apogeo de las APIs SOAP, los archivos de configuración basados en XML y hasta las bases de datos basadas en este formato. Teníamos este lenguaje de marcas hasta en la sopa, vamos.

A la versión de HTML gestada en aquella época se le llamó, como no, XHTML (de XML Hyper-Text Markup Language).

Una de los características de XML es que todas las etiquetas sin excepción se deben cerrar. Esto suponía un pequeño problema con algunas etiquetas de HTML que no necesitan contener a otros elementos, como por ejemplo las imágenes (<img>) o los cambios de línea (<br>), por citar dos de los más comunes. Así que para poder cumplir con la sintaxis de XHTML todas estas etiquetas se auto-cerraban poniéndoles una barra antes del cierre, por ejemplo:

<img src="Imgs/foto.jpg"/>
<br/>

Es decir, esa barra al final era lo mismo que poner una etiqueta de cierre, así:

<img src="Imgs/foto.jpg"></img>

que incluso era válido. De hecho, esta sintaxis de auto-cierre se utilizaba muchas veces incluso con elementos que contienen a otros elementos pero que, en el código inicial de la página iban a ir vacíos.

Pero ahora estamos en 2016 y lo que se utiliza es HTML5. ¿Qué dice esta especificación al respecto?

Bueno, pues aunque a muchos pueda sorprenderle, resulta que HTML5 no permite el uso de etiquetas auto-cerradas.

    "Pero ¿qué dices?... Si yo las pongo en mi página HTML5 funcionan sin problemas"

Efectivamente, funcionan sin problemas, pero eso no significa que sean correctas. HTML5 y los diferentes navegadores tienen una gran capacidad para adaptarse a errores de sintaxis en el código, pero eso no significa que sea código válido. Son cuestiones diferentes. Es más, el estándar define la manera de "parsear" el código e incluso cómo reaccionar ante ciertos errores. Pero insisto: que un código se renderice bien no quiere decir que sea válido.

Volviendo al tema de las etiquetas auto-cerradas, en HTML5 se distinguen varios tipos de elementos. Un tipo especial de elementos es lo que el estándar denomina elementos de tipo "void".

Los elementos de tipo void son aquellos que no contienen a otros (incluyendo texto), y que la especificación dice explícitamente que solo tienen una etiqueta de apertura, y que no se debe especificar una etiqueta de cierre:

Void elements only have a start tag; end tags must not be specified for void elements.

Estos elementos de tipo "void" son:

area, base, br, col, embed, hr, img, input, link, menuitem, meta, param, source, track, wbr

Por ello es importante saber que, aunque podemos auto-cerrar todas estas etiquetas, y aunque al navegador no parezca importarle, no pasarán una validación estricta de sintaxis. Si eso es importante para nuestro proyecto (en muchos casos lo es, sobre todo en proyectos para la administración), debemos evitarlo.

Los ejemplos típicos de mala sintaxis son los dos que hemos visto y, sobre todo, las etiquetas <meta> de las cabeceras, que se ven muy a menudo cerradas, cuando no debería ser así.

¡Muchas de las etiquetas de cierre son opcionales!

Antes de terminar, hay otra sorpresa escondida en la sintaxis de HTML5, y es que existen muchísimas etiquetas que no necesitan obligatoriamente etiqueta de cierre, aunque contengan a otros elementos dentro.

Muchas de ellas, además son de lo más común. Por ejemplo los párrafos, las listas, casi todos los elementos de las tablas, y por supuesto las propias etiquetas <html> y <body> que, de hecho, se pueden omitir por completo si queremos.

En la especificación tienes todos los detalles y las normas que rigen la posible omisión de estas etiquetas de cierre.

Por ejemplo, este HTML es perfectamente válido:

<!DOCTYPE HTML>
<title>Hola</title> <p>Hola mundo</p>

a pesar de que omite las etiquetas del cuerpo y del propio HTML, pero es válido según el estándar y es equivalente a este otro:

<!DOCTYPE HTML>
<html>
	<head>
		<title>Hola</title>
	</head>
	<body>
		<p>Hola mundo</p>
	</body>
</html>

Es el navegador el que se encarga de rellenar los elementos que faltan, según indica la propia especificación.

Otro ejemplo sería, por ejemplo, algo tan raro como no cerrar párrafos. Este fragmento es el que usaríamos habitualmente:

<body>
	<p>Hola</p>
	<p>Mundo</p>
</body>

pero en realidad este otro sería perfectamente válido según la especificación:

<body>
	<p>Hola
	<p>Mundo
</body>

(incluso, en realidad, podríamos omitir el <body> pero lo he dejado para dar contexto).

Si abrimos esto en un navegador veremos que mete las etiquetas de cierre que faltan automáticamente (esta captura es de Chrome):

Etiquetas-Cierre-Automaticas

OJO: esto no es que el navegador se adapte a una mala sintaxis e improvise metiendo estos nodos, como pasaba con el auto-cierre que vimos antes. No. Es que esto está explícitamente indicado como válido en la especificación en ciertos casos muy concretos (mira el enlace anterior).

Esto abre la puerta a ciertas optimizaciones en el código que enviamos a los navegadores desde el servidor, sin perder la validez de la sintaxis. Por ejemplo, para compresión al máximo del mismo, de modo que lleve las etiquetas de apertura y cierre estrictamente necesarias, y que sea el navegador en el otro extremo el que se encargue de rellenarlas. En móviles puede ser una buena idea.

No obstante, yo no abusaría de esta capacidad. El código se vuelve más difícil de seguir y de mantener, aunque si existe algún plugin para Grunt, Gulp, Webpack (desconozco si existe algo así) o el post-procesador que utilices habitualmente, puede ser algo muy a tener en cuenta.

En resumen

  • En HTML5 no se permiten las etiquetas auto-cerradas aunque funcionen.
  • Que funcionen no quiere decir que la sintaxis sea correcta.
  • Los elementos de tipo "void" no permiten etiquetas de cierre ni auto-cierre, y no deberíamos hacerlo.
  • Muchas etiquetas de cierre de elementos HTML comunes son opcionales, incluso las de apertura (podemos omitir el elemento entero)
  • Esto abre el camino para optimizar el código para dispositivos móviles o zonas con poca cobertura o "velocidad" de Internet.

¡Espero que te haya parecido interesante!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA