Does <STYLE> have to be in the <HEAD> of an HTML document?

style is supposed to be included only on the head of the document.

Besides the validation point, one caveat that might interest you when using style on the body is the flash of unstyled content. The browser would get elements that would be styled after they are displayed, making them shift on size/shape/font and/or flicker. It is generally a sign of bad craftsmanship. Generally you can get away with putting style anywhere you want, but try to avoid it whenever it is possible.

HTML 5 introduced a scoped attribute that allowed style tags to be included everywhere in the body, but then they removed it again.


Short answer

  • According to the current spec, yes, style elements must always be in the head. There are no exceptions (except a style element inside a template element, if you want to count that).

  • This has not always been the case historically. If you care about the details of the spec and its history, keep reading.

  • No matter what the spec says, using style elements in the body does more-or-less work in all major browsers. However, it is considered a bad practice both because it violates spec and because it can cause undesirable consequences like worse rendering performance or a "flash of unstyled content".


Spec history

style elements didn't exist in HTML 2. They were introduced in HTML 3.0, where they were included in the list of elements that could be included in The Head Element, but not included in the list of elements that could be present in The Body Element. Thus, at the moment the element was first specced, it could only be included in the head.

This remained the case (albeit expressed using different wording) until HTML 5, which introduced the (since removed) scoped attribute for style elements. This attribute, when present, was meant to allow a style element to be placed within an element in the body to style only that element's descendants. However, that feature never made it to any real browser (at least not without needing to be enabled via a developer flag) and was removed from both the W3C and WhatWG specs "due to lack of implementer interest". Thereafter, style elements were only permitted in contexts that allow metadata content, which is only the head. Thus we were back to the same rules as before HTML 5.

However, due to an error made by both spec organisations, a non-normative index of elements included as an appendix in both specs was not properly updated to reflect the removal of scoped, rendering it inconsistent with the normative spec. I pointed this out both to the WhatWG and to the W3C, and in doing so unwittingly set in motion events that caused the two specs to diverge.

WhatWG's solution to the inconsistency between the normative spec and non-normative index was to accept my patch correcting the non-normative index.

The W3C, on the other hand, rejected my equivalent patch in favour of instead updating the normative spec to allow the use of style elements in the body, while caveating this with a note that it can cause problems and should be done "with care". The reasoning behind this change was to make the spec align with real-life browser behaviour.

Thus, from March 2017, it was the case that the official answer to this question depended upon which standards organisation you chose to listen to. If you listed to the (generally more respected) WhatWG spec, then a style element was not allowed in the body. If you listed to the W3C spec, then it was allowed, but not recommended.

This silly state of affairs was ended (perhaps like many other such inconsistencies) with the April 2019 peace treaty between W3C and WhatWG, which agreed that the WhatWG spec would become the one true living HTML standard, with W3C merely releasing snapshots from it as numbered HTML specifications instead of developing a competing spec in parallel. Thus, the change from 2017 to the W3C fork that allowed style elements in the body is no longer part of any current spec; it is merely a curiosity of history.

So, today, we need only look to the WhatWG spec to determine what is officially allowed. It has this to say:

4.2.6. The style element

Categories:

Metadata content.

Contexts in which this element can be used:

Where metadata content is expected.
In a <noscript> element that is a child of a <head> element.

CTRL-Fing through the single-page spec reveals that the only element whose content model includes metadata content is the head element.

The non-normative index of elements I mentioned fixing earlier also confirms that the only permissible parents for a style element are a head or noscript element.