Respuesta corta
Según la especificación actual, sí, los style
elementos siempre deben estar en el head
. No hay excepciones (excepto un style
elemento dentro de un template
elemento , si desea contar eso).
Este no siempre ha sido el caso históricamente. Si te interesan los detalles de la especificación y su historial, sigue leyendo.
No importa lo que diga la especificación, el uso de style
elementos en el body
hace más o menos trabajo en todos los principales navegadores. Sin embargo, se considera una mala práctica tanto porque viola las especificaciones como porque puede causar consecuencias indeseables como un peor rendimiento de representación o un "destello de contenido sin estilo".
Historial de especificaciones
style
los elementos no existían en HTML 2 . Se introdujeron en HTML 3.0, donde se incluyeron en la lista de elementos que podrían incluirse en The Head Element , pero no en la lista de elementos que podrían estar presentes en The Body Element . Por lo tanto, en el momento en que el elemento se especificó por primera vez, solo se podía incluir en head
.
Este siguió siendo el caso (aunque expresado con una redacción diferente) hasta HTML 5, que introdujo el scoped
atributo (ya eliminado) para los style
elementos. Este atributo, cuando estaba presente, estaba destinado a permitir que un style
elemento se coloque dentro de un elemento en el cuerpo para diseñar solo los descendientes de ese elemento. Sin embargo, esa característica nunca llegó a ningún navegador real (al menos no sin necesidad de habilitarse a través de un indicador de desarrollador) y se eliminó de las especificaciones W3C y WhatWG "debido a la falta de interés del implementador" . A partir de entonces, los style
elementos solo se permitieron en contextos que permiten contenido de metadatos, que es solo la cabeza. Por lo tanto, volvimos a las mismas reglas que antes de HTML 5.
Sin embargo, debido a un error cometido por ambas organizaciones de especificaciones, un índice no normativo de elementos incluidos como apéndice en ambas especificaciones no se actualizó correctamente para reflejar la eliminación de scoped
, lo que lo hace inconsistente con la especificación normativa. Señalé esto tanto al WhatWG como al W3C , y al hacerlo, involuntariamente, pusimos en marcha eventos que causaron que las dos especificaciones divergieran.
La solución de WhatWG a la inconsistencia entre la especificación normativa y el índice no normativo fue aceptar mi parche corrigiendo el índice no normativo.
El W3C, por otro lado, rechazó mi parche equivalente a favor de actualizar las especificaciones normativas para permitir el uso de style
elementos en el body
, al tiempo que advierte que puede causar problemas y debe hacerse "con cuidado". El razonamiento detrás de este cambio fue hacer que la especificación se alineara con el comportamiento real del navegador.
Por lo tanto, a partir de marzo de 2017, la respuesta oficial a esta pregunta dependió de la organización de estándares que eligió escuchar. Si enumeró la especificación WhatWG (generalmente más respetada), entonces style
no se permitió un elemento en el body
. Si enumeraste la especificación W3C, entonces estaba permitido, pero no recomendado.
Esta situación tonta se terminó (tal vez como muchas otras inconsistencias) con el tratado de paz de abril de 2019 entre el W3C y WhatWG , que acordó que la especificación WhatWG se convertiría en el único estándar HTML vivo real, con W3C simplemente lanzando instantáneas de él como numeradas Especificaciones HTML en lugar de desarrollar una especificación competitiva en paralelo. Por lo tanto, el cambio de 2017 a la bifurcación W3C que permitió style
elementos en elbody
ya no es parte de ninguna especificación actual; Es simplemente una curiosidad de la historia.
Entonces, hoy, solo necesitamos mirar la especificación WhatWG para determinar lo que está oficialmente permitido. Tiene esto que decir:
4.2.6. losstyle
elemento
Contenido de metadatos .
Donde se espera contenido de metadatos .
En un <noscript>
elemento que es hijo de un <head>
elemento.
CTRL-Fing a través de la especificación de una sola página revela que el único elemento cuyo modelo de contenido incluye contenido de metadatos es elhead
elemento.
El índice no normativo de elementos que mencioné arreglar anteriormente también confirma que los únicos padres permisibles para un style
elemento son un elemento head
o noscript
.