Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and how do browsers render <style> tag in <body>?

Tags:

html

css

I noticed that if I place <style> inside <body> the css would be applied to all elements after and before <style> tag.

So it looks to me that the css is processed when the page is loaded, similar behavior to javascript document ready event. Am I right? And if that is the case in which order would multiple <style> tags be processed?

like image 216
tolkinski Avatar asked Jun 05 '17 14:06

tolkinski


2 Answers

TL;DR:

In short, the answer to your question is: once a <style> tag is met inside <body> everything stops and the CSSOM is being rebuilt and re-applied to all existing rendered (painted) content.

Placing <style> tags inside <body> is considered bad practice because it can create FOUC. But if your <style> tag only contains rules for elements placed after it in DOM, placing it in body is perfectly fine, as no FOUC can happen.


The render process of a page is quite complex. But, overly-simplified, here's what happens

  1. <head> is read and CSSOM is built. All CSS is render blocking, unless explicitly specified otherwise by use of @media queries. The non-blocking CSS is still loaded, it's not entirely skipped.
  2. DOM building and CSSOM building are ran in paralel, but all <script> execution is deferred until CSSOM has been built (on </head> tag met), at which point all loaded <script>s are ran, blocking DOM building. JS can make changes to CSSOM at this point. *
  3. Placing <style> tags inside <body> interrupts everything (JS execution and DOM building), CSSOM is being updated and applied to the already rendered content, if any. Everything is resumed after.

* On further testing it appears <head> parsing is single threaded. CSSOM building does block javascript execution but it's done is stages, as each <link /> and <style> tags are met (a <script> placed after a <link> will only execute after the <link /> was resolved and applied to CSSOM). <script> tags placed in between CSS resources are not deferred until all CSS resources in <head> are parsed, as I initially thought.
And, of course js can make changes to CSSOM at run time. See this question I asked for more on how js execution is blocked by CSSOM building.


All the above apply to the normal loading, without considering async, which adds a whole new layer of complexity to it.

If you're interested in more details, I recommend going through the Performance chapter of Web Fundamentals, provided by Google.

like image 81
tao Avatar answered Nov 17 '22 11:11

tao


Scope of CSS

A style element applies to the whole document, regardless of its position. It is applied as soon as it's loaded.

Reason for putting style tags in <body>

Since every browser has a limited number of threads for downloading a page's files (like JS, CSS, images and asynchronously loaded HTML, JSON or XML), people tend to include CSS files at the end of the body element instead of the classic approach of including them in the head element. This way the rest of the page can be loaded and rendered, and the styling is applied last. You would go this way if your CSS is purely for the looks (i.e. no required element hiding) in order to improve the user experience.

CSS files vs style rules in HTML

Including an external CSS file or putting the same rules in a style element have equivalent results regarding layout and styling. The external file has the downside of a little HTTP overhead, but the benefit of being cached for any further request. If your site consists of more than one page, you usually want to have one or more CSS files that are downloaded only once and re-used for most pages. In addition you can have page-specific rules in another file or within the HTML page.

like image 3
Hubert Grzeskowiak Avatar answered Nov 17 '22 10:11

Hubert Grzeskowiak