The topic of CSS in the body is rather controversial, as it somewhat defeats the idea of separating content from styling. But, it can significantly improve the user experience if done right.
When CSS is included in the body, either in <style> or via <link>, the browser may pause rendering of the page until the CSS is loaded. Obviously, this does not matter for content outside the viewport (aka "below the fold"), and so it is not hard to see how this will improve the UX of a site. The exact behavior depends on the browser, but it is generally reliable.
This is known as progressive rendering, and it has been used since before HTML5 / Living Standard. One way this could be used, is via AJAX, where content is loaded as-needed rather than all-at-once.
However, one should not simply go and place all CSS in the body without knowing the consequences.
Progressive Rendering and CSS
I am sure we have all tried adding CSS to the body, finding it worked in the browser, while the HTML validator would complain. Now, standards seem to line up more with this reality, allowing CSS included in the body – for good and bad.
Browsers still behave a bit differently when they encounter CSS in the body, but it is generally working quite well.
One situation where this is useful, is if you have CSS that adds colors for Syntax Highlighting to a web page. Loading this via a <link rel="stylesheet"> right before the article/section where it is used will improve UX by giving the impression your page loads faster. The reason is, these files tend to be quite big, and hence delay rendering of everything else until they are downloaded, which can sometimes be avoided by including them in the body instead.
For example, if your footer content is outside the viewport, then there is no reason to have your footer content block rendering of your header and main content. Placing styles related to the footer in the body, might therefor speed up rendering of other content. See below example:
<-- Other content --> <link rel="stylesheet" href="/footer.css"> <footer> <-- Footer content --> </footer>
It is important to keep in mind, in many situations, especially for small pages loaded over HTTP/1.x and no CDN, this will not actually speed up your page load time. It will make it slower because of extra HTTP requests.
For large pages, it will improve the UX by creating the illusion that your page loads faster. But, this is also what we are looking for!
Individual components will still have to be loaded, you just load them later, after critical parts of the page has finished rendering, or while the user is busy looking at something else on the page.
Both small and large is relative to the internet bandwidth of your users, so those with high speed internet will not benefit much from progressive rendering. Keep in mind, many users still have slow mobile connections.
Another thing to keep in mind, is that the result will depend on the browser. Today, Firefox, Chrome, and Edge are all good examples, since they simply pause the rendering of the page until the encountered StyleSheet/CSS is loaded, and then resume rendering the rest of the page. Safari will show a blank page until all CSS is loaded. It is almost like Safari is becoming the new IE6... Sigh!
In my case, here on Beamtic, the sh syntax highlighter code is quite big, so I will likely experiment with moving this at some point, when I get the time. Or, maybe choose another highlighter script.
Do not place all your CSS in the body. Keeping at least one StyleSheet in the head will prevent a Flash Of Unstyled Content. The file in the head should contain critical styles, including any CSS reset, and basic layout of your pages, while styles for individual components can be loaded as needed in the body via <link rel="stylesheet"> elements.