I've been researching browser rendering and I've just now come to the part in the render process where the browser constructs the CSSOM from raw CSS.
In all of the tutorials I've seen the authors seem to make the assumption/assertion that the body
element is the root, and that all styles applied to the body will tacitly be applied to the rest of the DOM unless explicitly overridden by another selector. An example of this is here https://blog.logrocket.com/how-css-works-parsing-painting-css-in-the-critical-rendering-path-b3ee290762d3/
In both of these explanations- the body
tag is assumed to be the root, even though the html
tag seems like it should be the root. Whats more is the fact that the HTML specification doesn't seem to require EITHER of these tags in markup (maybe I'm misunderstanding this though).
To me this seems like an incredibly important piece of information when applying styles to elements in the render tree. If one does not know which element is the root, then one does not know how the styles should cascade onto one another.
So my question is essentially, do browsers always assume that the body element is the root, or is there a method for determining which element should be the root in the browser's CSS Tree?
There are several issues here you're conflating, so it's difficult to close this one as a duplicate, even though each of the questions you raise by themselves have been asked, and answered before. So I hope this helps!
How is the root element of the CSSOM (CSS Object Model) determined
The root is simply the root element of the document, or html
, let there be no misunderstanding about that.
authors seem to make the assumption that the body element is the root (..) An example of this is here https://blog.logrocket.com/how-css-works-parsing-painting-css-in-the-critical-rendering-path-b3ee290762d3/
Ehm, no. The example on that page uses "root" as the top of the particular subtree it is talking about, which just happens to be <body>
there, but that is a coincidence; the example could well have been for a table, and then <table>
would have been the "root".
Whats more is the fact that the HTML specification doesn't seem to require EITHER of these tags in markup (maybe I'm misunderstanding this though).
The start tags for both <html>
and <body>
are optional, so yes, they can be omitted from a HTML document. Same for <head>
. But the elements themselves are still there! All the content is inside the html
element, start tag or not. You can test this for yourself by loading a HTML document, say
<title>title</title>
<div>Hello world</div>
into the browser and inspecting it, you'll see that the div is now packed inside a body
element, while the title is in a head
element. There is no way around that.
Now the confusing part is that some (but not all) CSS styles applied to body
are applied to html
instead by the browser. background-color
for example; if you assign that to the body, the whole browser window gets coloured rather than just the body area.
This is a leftover behaviour from a time, long ago, when the html
element was not considered to be a drawing canvas; it was not styleable, and only the body had styling attributes (BGCOLOR, TEXT, LINK etc). Although this is no longer the case, browsers still behave as if it is, for compatibility purposes.