Error Más de una etiqueta html, head o body

Por qué una segunda etiqueta <html>, <head> o <body> suelta en el código fuente es inválida, aunque los navegadores la fusionen en silencio.

El validador marca markup de origen crudo que contiene más de una etiqueta de apertura <html>, <head> o <body>.

Ejemplo

<!-- Incorrecto: un segundo <body> que quedó de una fusión -->
</body>
<body class="tema-oscuro">
  ...
</body>
</html>

<!-- Correcto: fusionar el atributo en la única etiqueta body -->
<body class="tema-oscuro">
  ...
</body>

Por qué importa

Un documento HTML válido tiene exactamente un <html>, un <head> y un <body>. Los navegadores manejan con elegancia una copia extra que se coló — según el algoritmo de parseo de HTML5, una segunda etiqueta de apertura de cualquiera de estos tres elementos no se convierte en un nuevo nodo del DOM; en cambio, cualquier atributo nuevo que traiga se fusiona con el que ya está abierto, y la etiqueta misma se descarta. Esa resiliencia es exactamente por qué es fácil pasarlo por alto: la página renderizada normalmente se ve completamente normal. Casi siempre señala un error real en cómo se ensambló el documento — dos plantillas concatenadas, un copiar y pegar que incluyó el markup contenedor dos veces, o un paso de build que duplicó un parcial de layout.

Frequently asked questions

Si los navegadores manejan bien esto, ¿de verdad hace falta arreglarlo?

El renderizado suele verse bien, que es exactamente el problema — oculta un error real en cómo se ensambla la página. La etiqueta suelta es un síntoma de salida de plantilla duplicada o mal combinada, y una duplicación similar en otra parte del mismo paso de generación (estilos, scripts, etiquetas meta) es fácil de pasar por alto si esta etiqueta en particular se ve inofensiva.

¿Por qué esto no se puede detectar inspeccionando la página parseada en un navegador?

Porque el parser del navegador ya descarta el duplicado antes de que pudieras verlo en el DOM o en las herramientas de desarrollador — para cuando la página está parseada, solo existe un <body> (con los atributos fusionados). Esta revisión tiene que mirar el texto fuente HTML crudo en su lugar, antes de que un navegador lo procese.