Короткий ответ
Согласно текущей спецификации, да, style
элементы всегда должны быть в head
. Нет никаких исключений (кроме style
элемента внутри template
элемента , если вы хотите это посчитать).
Это не всегда имело место исторически. Если вы заботитесь о деталях спецификации и ее истории, продолжайте читать.
Независимо от того , что говорит спецификация, используя style
элементы в body
делает более-менее работу во всех основных браузерах. Однако это считается плохой практикой как из-за того, что оно нарушает спецификацию, так и из-за того, что может привести к нежелательным последствиям, таким как ухудшение производительности рендеринга или «вспышка нестандартного содержимого».
Спек история
style
элементы не существовали в HTML 2 . Они были введены в HTML 3.0, где они были включены в список элементов, которые могут быть включены в элемент Head , но не включены в список элементов, которые могут присутствовать в элементе Body . Таким образом, в тот момент, когда элемент был впервые обнаружен, он мог быть включен только в head
.
Это сохранялось (хотя и выражалось в разных формулировках) до HTML 5, в котором scoped
для style
элементов был введен атрибут (поскольку он был удален) . Этот атрибут, когда он присутствует, предназначался для того, чтобы позволить style
элементу быть размещенным внутри элемента в теле, чтобы стилизовать только потомков этого элемента. Однако эта функция никогда не была доступна ни одному реальному браузеру (по крайней мере, без необходимости включения через флаг разработчика) и была удалена из спецификаций W3C и WhatWG «из-за отсутствия интереса со стороны разработчика» . После этого style
элементы были разрешены только в тех контекстах, которые допускают содержание метаданных, то есть только заголовок. Таким образом, мы вернулись к тем же правилам, что и до HTML 5.
Однако из-за ошибки, допущенной обеими организациями спецификаций, ненормативный индекс элементов, включенный в качестве приложения в обе спецификации, не был должным образом обновлен для отражения удаления scoped
, что делает его несовместимым с нормативной спецификацией. Я указал на это как на WhatWG, так и на W3C , и при этом невольно включил события движения, которые вызвали расхождение двух спецификаций.
Решение WhatWG для несоответствия между нормативной спецификацией и ненормативным индексом состояло в том, чтобы принять мой патч, исправляющий ненормативный индекс.
W3C, с другой стороны, отклонил мой эквивалентный патч в пользу того, чтобы вместо этого обновить нормативную спецификацию, чтобы разрешить использование style
элементов в body
, при этом отметив это примечанием, что это может вызвать проблемы и должно быть сделано "с осторожностью". Причиной этого изменения было приведение спецификации в соответствие с реальным поведением браузера.
Таким образом, начиная с марта 2017 года, официальный ответ на этот вопрос зависел от того, какую организацию по стандартам вы выбрали для прослушивания. Если вы указали в спецификации WhatWG (как правило, более уважаемой), то style
элемент не был разрешен в body
. Если вы указали в спецификации W3C, то это было разрешено, но не рекомендуется.
Это глупое положение вещей было положено конец (возможно, как и многие другие подобные несоответствия) мирному договору от W3C и WhatWG , заключенному в апреле 2019 года , который согласился с тем, что спецификация WhatWG станет единственно верным живым стандартом HTML, а W3C просто выпустит снимки из него в виде номера. HTML-спецификации вместо параллельной разработки конкурирующей спецификации. Таким образом, переход с 2017 года на форк W3C, который позволял style
элементам в, body
больше не является частью текущей спецификации; это просто любопытство истории.
Итак, сегодня нам нужно только обратиться к спецификации WhatWG, чтобы определить, что официально разрешено. Он имеет это сказать:
4.2.6. style
элемент
Содержание метаданных .
Где ожидается содержание метаданных .
В <noscript>
элементе, который является дочерним <head>
элементом элемента.
CTRL-Fing в одностраничной спецификации показывает, что единственным элементом, модель содержимого которого включает в себя содержимое метаданных, является head
элемент.
Ненормативный индекс элементов, о которых я упоминал ранее, также подтверждает, что единственными допустимыми родителями для style
элемента являются a head
или noscript
element.