Acerca de este problema HTML
En un documento HTML válido, todo el contenido debe residir dentro del elemento <html>, y específicamente dentro de <head> o <body>. El analizador HTML espera una estructura bien definida: <!DOCTYPE html>, luego <html>, conteniendo <head> y <body>. Cuando una etiqueta <script> aparece fuera de esta jerarquía — por ejemplo, después de la etiqueta de cierre </html> — el validador la reporta como una “etiqueta de apertura perdida” porque no tiene un padre válido en el árbol del documento.
Este es un problema común que surge de varias maneras. A veces los desarrolladores colocan accidentalmente un script después de </body> o </html>, pensando que aún se ejecutará. Otras veces, los sistemas de plantillas o plataformas CMS inyectan scripts al final de la salida sin asegurar que estén dentro de <body>. Aunque los navegadores son tolerantes y típicamente ejecutarán el script de todas formas, depender de este comportamiento de recuperación de errores lleva a un marcado no estándar y colocación impredecible en el DOM.
Por qué esto importa
-
Cumplimiento de estándares: La especificación HTML requiere que todos los elementos estén correctamente anidados dentro de la estructura del documento. Un
<script>fuera de<html>viola este requisito. -
DOM predecible: Cuando un navegador encuentra un
<script>perdido, debe usar recuperación de errores para determinar dónde colocarlo en el DOM. Diferentes navegadores pueden manejar esto de manera diferente, llevando a inconsistencias. - Mantenibilidad: El marcado inválido puede causar escenarios de depuración confusos, especialmente cuando JavaScript depende de la estructura o el orden del DOM.
Cómo solucionarlo
Mueve el elemento <script> dentro de <head> o <body>:
-
Colócalo en
<head>si el script necesita cargarse antes de que el contenido de la página se renderice (configuración, configuración de analytics, etc.). Considera usar el atributodeferoasyncpara scripts externos para evitar bloquear el renderizado. -
Colócalo al final de
<body>(justo antes de</body>) si el script interactúa con elementos DOM, que es un patrón común y recomendado.
Ejemplos
Incorrecto: script después de la etiqueta de cierre </html>
Esto desencadena el error “Etiqueta de apertura script perdida” porque el <script> está completamente fuera de la estructura del documento.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
<script>
console.log("This is stray!");
</script>
Incorrecto: script entre </head> y <body>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<script>
console.log("Misplaced script");
</script>
<body>
<p>Hello world</p>
</body>
</html>
Correcto: script en el <head>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<script>
console.log("Hello from the head");
</script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Correcto: script al final del <body>
Esta es la colocación más común y recomendada para scripts que interactúan con la página.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
<script>
console.log("Hello from the body");
</script>
</body>
</html>
Correcto: script externo con defer en <head>
Usar defer te permite colocar el script en <head> mientras aseguras que se ejecute después de que el DOM esté completamente analizado, dándote lo mejor de ambos mundos.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<script src="app.js" defer></script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Encuentra problemas como este automáticamente
Rocket Validator escanea miles de páginas en segundos, detectando problemas de HTML en todo tu sitio web.
Más información: