cssdomcssom

How is the root element of the CSSOM (CSS Object Model) determined


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/

and here https://developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model

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?


Solution

  • 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.