2

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?

Carl
  • 457
  • 5
  • 23
  • Note that the CSSOM applies to all DOM documents, XML as well as HTML. While the root node in HTML is always initially the `` element (JavaScript can change it) the root node in an XML document could be anything. – Alohci Jan 16 '20 at 21:35

1 Answers1

2

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.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • I guess the part that's got me confused is this part where they say verbatim- "If there’s a single selector, it will be attached to the root node of the tree." If we take an ID e.g. #box- we need to know what exactly "root" is- to know where we should insert a node for #box. In context- it would make sense for the #box node to be attached to the body node. Is that basically what's going on? – Carl Jan 16 '20 at 20:50
  • @Carl - That tree diagram from the logrocket document, the accompanying CSS and the paragraph that follows makes no sense. It doesn't describe the CSSOM, isn't self-consistent, and right-to-left reading has nothing to do with "guarantee[ing[ that they end up underneath the correct nodes". It's purely a performance technique. I suggest you disregard that, and find a better source of information. – Alohci Jan 16 '20 at 21:44
  • I've been looking for better sources- but they are very hard to come by. Reading the W3 specification is not particularly helpful- and most of the sources that are geared towards learning are either wrong or ultra simplified. Do you have any suggestions on where/how I can learn about this? – Carl Jan 16 '20 at 22:02
  • @Carl, sadly no. If you look at the CSSOM spec, you'll see that it's an API for manipulating the stylesheets. It's not about trees at all. If the browser constructs a tree from the styles at all, and I have my doubts, then (a) the root would not map to any DOM node at all, and (b) the sub-tree depicted could not be constructed from the given CSS, since the CSS provides no information about a connection between body and p elements (for example). – Alohci Jan 16 '20 at 22:19
  • The DOM tree, and the render tree are real though, but how the CSS is applied to the DOM tree to create the render tree is an implementation detail. I would maybe concentrate on grasping the render tree instead. – Alohci Jan 16 '20 at 22:19
  • Thanks for the information. I just wanted to know for sure that I wasn't skipping over something important by not know how this worked. The only concrete information I was able to find in regards to this was the very API that you speak of- which is documented very well. If what you say is correct and the details of the CSSOM are browser specific, then I guess there's more of less no point in learning about it. – Carl Jan 16 '20 at 22:34