Resposta curta
De acordo com a especificação atual, sim, os style
elementos devem sempre estar no head
. Não há exceções (exceto um style
elemento dentro de um template
elemento , se você quiser contar isso).
Esse nem sempre foi o caso historicamente. Se você se preocupa com os detalhes das especificações e seu histórico, continue lendo.
Não importa o que a especificação diz, usando style
elementos no body
faz mais ou menos trabalho em todos os principais navegadores. No entanto, é considerada uma má prática, tanto por violar especificações quanto por causar conseqüências indesejáveis, como pior desempenho de renderização ou um "flash de conteúdo não estilizado".
Histórico de especificações
style
elementos não existiam no HTML 2 . Eles foram introduzidos no HTML 3.0, onde foram incluídos na lista de elementos que poderiam ser incluídos no The Head Element , mas não incluídos na lista de elementos que poderiam estar presentes no The Body Element . Assim, no momento em que o elemento foi especificado pela primeira vez, ele só pôde ser incluído no head
.
Este permaneceu o caso (embora expresso usando palavras diferentes) até o HTML 5, que introduziu o scoped
atributo (desde que removido) para os style
elementos. Esse atributo, quando presente, tinha como objetivo permitir que um style
elemento fosse colocado dentro de um elemento no corpo para estilizar apenas os descendentes desse elemento. No entanto, esse recurso nunca chegou a nenhum navegador real (pelo menos não sem a necessidade de ser ativado por um sinalizador de desenvolvedor) e foi removido das especificações do W3C e do WhatWG "devido à falta de interesse do implementador" . Depois disso,style
elementos foram permitidos apenas em contextos que permitem conteúdo de metadados, que é apenas o cabeçalho. Assim, voltamos às mesmas regras de antes do HTML 5.
No entanto, devido a um erro cometido pelas duas organizações de especificações, um índice não normativo de elementos incluídos como apêndice nas duas especificações não foi atualizado adequadamente para refletir a remoção de scoped
, tornando-o inconsistente com a especificação normativa. Eu apontei isso para o WhatWG e para o W3C e, ao fazê-lo, involuntariamente desencadeou eventos que fizeram com que as duas especificações divergissem.
A solução da WhatWG para a inconsistência entre a especificação normativa e o índice não normativo foi aceitar meu patch corrigindo o índice não normativo.
O W3C, por outro lado, rejeitou meu patch equivalente em vez de atualizar a especificação normativa para permitir o uso de style
elementos no body
, enquanto ressalta isso com uma nota de que ele pode causar problemas e deve ser feito "com cuidado". O raciocínio por trás dessa mudança foi alinhar as especificações com o comportamento do navegador da vida real.
Portanto, a partir de março de 2017, a resposta oficial a essa pergunta dependia de qual organização de padrões você escolheu ouvir. Se você listou as especificações WhatWG (geralmente mais respeitadas), um style
elemento não era permitido na body
. Se você listou as especificações do W3C, isso foi permitido, mas não recomendado.
Esse estado de coisas tolo foi encerrado (talvez como muitas outras inconsistências) com o tratado de paz de abril de 2019 entre o W3C e o WhatWG , que concordou que as especificações do WhatWG se tornariam o único verdadeiro padrão HTML vivo, com o W3C apenas liberando instantâneos como numerados Especificações HTML em vez de desenvolver uma especificação concorrente em paralelo. Assim, a mudança de 2017 para o fork do W3C que permitiu style
elementos nobody
não faz mais parte de nenhuma especificação atual; é apenas uma curiosidade da história.
Então, hoje, precisamos apenas olhar para a especificação WhatWG para determinar o que é oficialmente permitido. Tem o seguinte a dizer:
4.2.6 O style
elemento
Conteúdo de metadados .
Onde o conteúdo de metadados é esperado.
Em um <noscript>
elemento que é filho de um <head>
elemento.
CTRL-Fing através da especificação de página única revela que o único elemento cujo modelo de conteúdo inclui conteúdo de metadados é o head
elemento.
O índice não normativo dos elementos que mencionei anteriormente, também confirma que os únicos pais permitidos para um style
elemento são a head
ou noscript
elemento.