Request comments: :root to body hierarchy

Hello, Merry Christmas, and thanks for looking!
I hope that what I suggest here is correct. I would appreciate verification or being educated where I am wrong. Thank you.
– Fred

<!DOCTYPE html>
  <html lang="en">
      :root { 
        --rb-blue: LightBlue; /* root background */
        --rb-gray: LightGray;
        --rf-blue: blue;      /* root font */
        --rf-green: green;
        --rf-brown: Maroon;
        background-color: var(--rb-blue);
        padding: 25px;
      :root::before {
        content: 'This is the :root selector area. It is the entire <!DOCTYPE>, before the document has been declared as HTML. <br> HTML tage do not work yet. Even the cascading wildcard "*" could not overide this. This text is from :root::before.';
        color: var(--rf-blue);
        font-weight: bold;
        font-size: 20px;
      :root::after {
        content: "This text is from :root::after.";
        color: var(--rf-blue);
        font-weight: bold;
        font-size: 15px;
      * { /* overide the browser's default settings */
        font-size: 16px; 
        margin: 0; 
        padding: 0;
      html { /* html is below the :root */
        background-color: wheat;
     body { /* body is below the html element styles */
        height: 70%;
        background-color: var(--rb-gray);
        padding: 25px;
        font-size: 22px;
        color: var(--rf-brown);
      h1 {
        color: var(--rf-green);
        text-align: center;
    <title>A title is required for validation</title>
    <h1>:root * html and body selectors</h1>
    <p>The CSS <u><b>:root</b></u> pseudo-class element is the top-most element within the &lt;!DOCTYPE>. HTML has not been called yet, so the &lt;br> in the :root (above) did not work.</p>
    <p>I placed my "site global style" colors and backgrounds as variables there. This may be used to place content before the HTML part of the document as shown above.</p>
    <p>It has been suggested (I have not tried) that :root is the place for media queries.</p>
    <h2>* is a wildcard.</h2>
    <p>This means that it will be applied to every CSS element. For example, notice that my " * { font-size: 16px; margin: 0; padding: 0; overrides the browser's default setting on all elements including the headers.</p> 
    <p>In the hierarchy of things, HTML is the top level after &lt;!DOCTYPE html> has told a browser to treat a document as html. I have read that there are may situations where it makes more sense to apply styles to html. The HTML element references the viewport. Height and width values then depend on the user's device. The rem unit is relative to the document root. Background-color on html floods the whole viewport. </p>  
    <p>The body element resides inside the html element. This will be the parent element for all others. If there is not enough information to fill the viewport, a Background-color here will not flood the screen. The solution would be: body { min-height: 100vh; }. </p>

Hi Fred, Merry Christmas to your too

Good question! Not sure about the answer… :thinking:

MDN Web Docs says

The :root CSS pseudo-class matches the root element of a tree representing the document. In HTML, :root represents the <html> element and is identical to the selector html , except that its specificity is higher.

So, for me, everything is HTML but your html code in the content is a string so I won’t work. You can open Dev Tools in your browser, for Chrome all your code is an HTML document. For me too, but I would like more experiencer folks say something.

Keep thinking like that, you will learn more and deeper.

Great job!!

if you define some property in the root, such as background-color, this shouldn’t be changed by adding that property with a different value in ‘html’ element’s selector. The exception will be if you put !important after it. The new value of the background-property will be put into action:

with your existing code:

html { /* html is below the :root */
        background-color: black;

You have got the following:

But if you change this property by adding !important, you will get:

html { /* html is below the :root */
        background-color: black !important;

The html element’s selector will take the priority over the root’s selector.

Thank you, @carlosvisator .
I had read that while trying to understand this.
IF my browser(s) knew that this is a HTML document, they should have displayed a new line at the “

Thank you, @DobarBREND
This project started because of me questioning myself while trying to get media queries to work as I wish.
Yes, the html {background-color: black !important;} fills the viewport. I normally would not define the same property twice.

Do you have an idea of why " * {font-size: 16px !important;} " does not override those set in :root? Even placing this before (on line 5) the :root (line 6) has no apparent affect.

Try placing “border: 1px solid red;” in :root and nothing is seen. Then in * to see all elements.

  • The universal selector * has a specificity of 0-0-0

  • The html element/type selector has a specificity of 0-0-1

  • The :root pseudo-class selector has a specificity of 0-1-0 (pseudo-classes have the same specificity as class selectors).

Thank you, Lasse @lasjorg .
I will try ti understand that link.
Merry Christmas!
– Fred

@lasjorg , even that does not explain what I think I see. From the , remove everything that mentions border ( including box-sizing: border-box; ). Put :

      :root { 
        --bg-blue: LightBlue; /* background colors */
        --bg-gray: LightGray;
        --f-blue:  blue;      /* font colors */
        --f-green: green;
        --f-brown: Maroon;
        background-color: var(--bg-blue);
        padding: 25px;
        border: 1px solid red;

at the top.
Where are the red boxes?

– Fred

* selects all elements.

:root selects the root element, usually the html element (a single element, i.e. one red box).


  • { font-size: 16px; margin: 0; padding: 0; overrides the browser’s default setting on all elements including the headers. Note that this does not have an apparent effect on :root.

Edit: I worded that wrong. The location (cascade) of the styles will not change the selector specificity. Just because a style comes after does not mean the selector will overwrite it.

The reason the * selector can overwrite browser defaults even with a specificity score of 0-0-0 is because of the cascade and the style origin rules (kind of a more advanced topic).

Thank you, Lasse @lasjorg.

The more I learn the less I know! I may have to let this rest for a while.

Where do you place your media queries?

Thanks, and Merry Christmas - Happy New Year!

– Fred

It depends. I sometimes like placing them close to the selector they overwrite the styles for. Mainly when making small changes that are well-targeted and the position is “stable”. By that I mean I am unlikely to make changes that are affected by the position of the media query.

But most often I place them wherever in the cascade they are sure to work correctly, which is often just at the bottom of the file. We do have @layer now, I haven’t really used it much but it does open up some new possibilities for how we group our selectors.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.