DEV Community

loading...
Cover image for What is the color of a blank page?

What is the color of a blank page?

bcalou profile image Bastien Calou Updated on ・8 min read

Please picture the following HTML page in your head:

<html>
  <body>
    <h1>Hello World</h1>
  </body>
</html>

You open it in the browser. What is the color of the page?

It's a CSS trap!

You could argue that this is a trick question because white is not really a color, but the page is not white anyway: it's transparent. Sure, the browser is white, but the page displayed inside the browser is transparent.

Prove me that the page is not white because it is kind of white I must say

Philosopher mode on :

So what is a page?

Two elements must be considered here:

  • The body element
  • The html element

If we want the page to have a yellow background, we can put a background-color on the body:

body {
  background-color: yellow;
}

From this example, we can assume that the body fills the whole viewport, because everything is yellow now.

That is not true. Let's add a border to the body:

You can see that, actually, the body only uses the space it needs to present the content "Hello World".

So why all the yellow?

Oh, you'll have to ask the w3c:

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas.

Human translation: you put a background on the body. The browser will use that as a background for the canvas.

The canvas, you say?

The document canvas is the infinite surface over which the document is rendered.

So that's pretty big.

The notion of canvas is absent from most CSS courses (including mine, I must admit), although it's a very important part of the browser. As we've seen, based on the body, it provides a background for the whole viewport.

With that new information let's update our mental model of the page, from top to bottom:

  • The body element
  • The html element
  • The canvas

For a long time I thought that the canvas was all yellow because the body was the canvas. Nope: the canvas just uses information from the body, and the canvas can be much bigger than the body itself.

It's interesting to note that even though we set the body to be yellow, it is actually transparent. As the w3c puts it:

The background of the root element becomes the background of the canvas [...] The root element does not paint this background again, i.e., the used value of its background is transparent.

It's useless for the browser to paint the body, which has the same color as the canvas : that's why it's treated as transparent.

In other words: when you set a background color on the body, you are actually styling the canvas (which cannot be styled directly in CSS). The canvas "steals" the value from the body.

Beyond the body

Philosopher mode on :

So what is the body?

According to the w3c, the body is

where the content appears: text, images, colors, graphics, etc.

If the body is the content, it seems safe to say that what is outside of the body is not the content.

Yes, thank you for your input

So surely setting a background-color on the html element won't have any effect, because it's not part of the content?

Stop and think about it: what would our page look like with this CSS?

html {
  background-color: green;
}

body {
  background-color: yellow;
}

What is the color of the page now? Is it yellow, is it green, is it both? Of course it's both.

What can we see?

  • The yellow is now limited to the body.
  • The html element seems to fill the whole viewport.

Wrong! Once again we are fooled.

But it does fill the viewport! The whole page is green!

I know. But let's add borders to the html element to see what happens:

At this point it's worth noting that the browser has no problems applying styles (such as borders) outside of the body. But let's continue.

So actually, the html behaves just like the body : it only takes the space needed to host its content: the body and its 8px margin coming from the browser default styles.

So WHY the green everywhere?

Same answer from the w3c :

The background of the root element becomes the background of the canvas.

We also learn that the root element can be the body or the html :

It is recommended that authors of HTML documents specify the canvas background for the BODY element rather than the HTML element.

Although the w3c recommends that we don't use the html element for that, we just did, and that's where the canvas green color is taken from.

Like in the first example, the html is treated as transparent : its green is "stolen" by the canvas.

We now have the full algorithm that the browser uses to choose the color of the canvas:

if (the html has a background-color) {
  use it to paint the canvas
} 
else if (the body has a background-color) {
  use it to paint the canvas
}
else {
  the canvas stays transparent
}

Well, that's one mystery solved I guess, and that's not that strange. You could say this is quite smart that we don't have to give explicit dimensions to the root element in order to have a background color filling the viewport.

Why does this matter? What about the white VS transparent thing?

Understanding that there is a difference between white and transparent, even if both situations look identical, is key to figure out some CSS mysteries.

Let's have fun with mix-blend-mode. This CSS property allows us to define how an element should blend with its parent. Sometimes referred as "Photoshop in the browser". Exageration or not, the possibilities are amazing.

Mix blend mode examples

From www.visualcinnamon.com

We begin with a simple example: the h1 will be green, and we want to change its appearance with mix-blend-mode: difference.

h1 {
  color: green;
  mix-blend-mode: difference;
}

The difference value means that the color of the text will be the difference between its original color (green) and the color of the background.

The difference between green and white is pink. So hopefully, our title will be pink.

It is not, I repeat, it is not pink.

But it should blend! The background is white!

No, it isn't. It's transparent.

Ah ah!

The difference between green and transparent is green, hence the color of the title, unchanged.

Let's recap:

  • The body is transparent (default value of background-color)
  • The html is transparent (default value of background-color)
  • The canvas is transparent (no value provided by html nor body)

So our poor title has nothing to blend with.

The fix is easy: just put a background-color on the body !

body {
  background-color: white;
}

It now works!

Let's recap again:

  • The body is transparent (white set in the CSS, but "stolen" by the canvas)
  • The html is transparent (default value of background-color)
  • The canvas is white (the value is taken from the body)

And so our green title blends with the canvas and turns pink. This title could of course be an image, a video, anything. The body (or any element containing our target) must have a background (you could also set a background to the html to achieve that, but that's non-standard).

Our journey is coming to an end, but there is one last question…

What is the color of a blank canvas?

Our mental model of the page is this:

  • The body element
  • The html element
  • The canvas

According to what we learned, if the body and the html are transparent, the canvas will be transparent too.

But how can the bottom layer be transparent? If this was the case, we would see the desktop and the other windows through the browser! You're nuts!

Hear me out. What if there is another layer, actually white, below the canvas?

There must be another layer

Once again, the w3c gives the answer:

If the canvas background is not opaque, what shows through is UA-dependent.

Human translation : there is something behind the canvas. You can see it if the canvas is transparent. What you see depends on the browser.

On every browser I can think of, this bottom layer is white. But theoretically, it could also show a picture of a horse eating an pineapple pizza. What a strange web that would be.

Anyway, this led me to think: is there any way to actually see the difference between a white and a transparent canvas? Can we have proof that the default canvas is transparent? Just asking for a weird friend.

The iframe clue

Let's go back to a very simple CSS:

html, body {
  border: 3px dashed black;
}

Our page looks like that:

Let's include that page in another one with an iframe tag:

<iframe src="..." width="100%" height="300px"></iframe>

Here's what we get :

So, the question is : does the iframe have a transparent or white canvas?

We can answer this question by setting a background-color on the parent page.

body {
  background-color: lightblue;
}

As you can see, the iframe is transparent. body, html, and canvas. We can see the parent page through it.

Does it really prove that the canvas is transparent? Maybe iframes just don't have a canvas?

That's a fair question. To answer that, let's put a white background on the iframe's body tag:

body {
  background-color: white;
}

Here's what we get:

If the iframe didn't have a canvas, the area outside its body wouldn't be filled. But thanks to the canvas mechanism, the background color of the body can be used to cover the whole iframe viewport.

And that's how we can see that on any page, the default canvas is not white but transparent.

So what you see when you open a blank page is not a white canvas. It's just the "bottom" of the browser, the background of the software, outside of CSS land, not meant to interact with anything.

That's so deep

Hence our (final?) mental model of what we see:

  • The body element (transparent by default)
  • The html element (transparent by default)
  • The canvas (depends on the html and body, so transparent by default)
  • The inaccessible software foundations (often white)

Oh, and I tried to represent it visually :

It's a small Hello World after all

That was a nice trip. And yes, I'm fun at parties. If you have any input about all of this, please leave a comment!

CSS is a lot about what you see, but also a lot about what you don't.

Discussion

pic
Editor guide
Collapse
sabberworm profile image
Raphael Schweikert

I remember in the ’90s when most browsers’ background color was grey. IE was the only one that has a white browser background by default. Others followed suit.

In fact you can change the browser background color in Firefox in about:config by setting browser.display.background_color. I have set this to grey to check if I haven’t accidentally forgotten to add background:white to a page that should have a white background.

I remember when they wanted to fix the weird special-casing of the body tag (which is NOT the root element but can upwards-„inherit“ its color to the html element, which is root) in XHTML. Still today, pages sent with the correct XHTML mime type (application/xhtml+xml) will not show this behaviour. Setting a background on the body tag there won’t make it magically stretch to the canvas.
Sadly, true XHTML never saw any real adoption…

Collapse
bcalou profile image
Bastien Calou Author

That is super-interesting, thank you so much for this comment.
Would you be ok with me writing a small bonus article and quoting your comment ?
I think more people need to know about this grey background tip.
Very interesting details about xhtml too, thanks!

Collapse
sabberworm profile image
Raphael Schweikert

Sure, by all means, bonus away…

Thread Thread
rubengmurray profile image
Reece Daniels

xhtml... wow, haven't seen a mention of that in a while

Collapse
rhymes profile image
rhymes

Netscape definitely had a grey "blank page":

netscape navigator

Collapse
bcalou profile image
Bastien Calou Author

Indeed, I'm currently writing about this! (not the main subject, but part of it)

Collapse
manishfoodtechs profile image
manish srivastava

It's a small Hello World after all..... nice article

Collapse
peke314 profile image
Victor Janin

Great Article!
so if we leave our html/body without any background, and the browser changes to dark mode, would that change the browser background?

Collapse
bcalou profile image
Bastien Calou Author

Thanks!
The answer seems compicated.
I just tried the #enable-force-dark flag to force dark mode on every site on Chrome.
It looks like it doesn't try to replace black background with white : it considers white to be black ! (see screenshot)
So background-color: white | transparent | black | none has the same effect : you see black. I think that yes, the browser's background changes, but that's really a wild guess.
Maybe something to explore in another article ;)

Collapse
bcalou profile image
Collapse
taylorbeeston profile image
Taylor Beeston

This was a really well-written article! I think we should petition Google and Mozilla to let us customize our default browser backgrounds. I personally would love it to actually be transparent and show me my desktop through the browser window

Collapse
bcalou profile image
Bastien Calou Author

I learned that this is possible in Electron by setting the background color of the body to "transparent" !
But nothing like that in the browser indeed

Collapse
victormagarlamov profile image
Victor Magarlamov

Thank you! It's a very interesting article!

Collapse
mckenney17 profile image
Ogunrinola Kehinde

You're a genius writer with your dev stuff, this made me wonder, are a member of the w3c or you sat down and figured this shit out yourself? You're great man. You've added greatly to my knowledge today

Collapse
bcalou profile image
Bastien Calou Author

Thank you very much, I'm so glad you liked it!
I'm just a front-end teacher ;) One of my student struggled with this mix-blend-mode thing, so I sat down and tried to get to the bottom of this with many tests. Had to read a lot of w3c documentation ^^
Actually I started writing another post on the same subject, because there is too much to say!

Collapse
simevidas profile image
Šime Vidas

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas.

Human translation: you put a background on the body. The browser will use that as a background for the canvas.

Small correction: The “root element” is the <html> element, not the <body> element.

Collapse
bcalou profile image
Bastien Calou Author

Small shortcut, I agree. The <html> is of course the root, but the browser uses the <body> rules as if they were set on the <html>.

"The used values of that BODY element’s background properties are their initial values, and the propagated values are treated as if they were specified on the root element."

Collapse
patarapolw profile image
Pacharapol Withayasakpunt

Iframe has allowtransparency -- stackoverflow.com/questions/374070... so I always know it is transparent.

Collapse
bcalou profile image
Bastien Calou Author

Thanks, I didn't know about that !
But I could not produce an example in which allowtransparency had any impact. The iframe is transparent by default.
Is it for specific browsers/environments ?

Collapse
nanouchkaya profile image
Claudine

Those wonderful thing we can learn about CSS 😍 thank you for sharing!

Collapse
alohci profile image
Nicholas Stimpson

Good stuff. Most of this I knew, but the point about the blend-modes had passed me by. Thanks for the explanation.

Collapse
leob profile image
leob

Man, this is deep! Good stuff.

Collapse
bayuangora profile image
Bayu Angora

Some website use <canvas> on its view-source, especially when it use particle.js background.

Collapse
rpalo profile image
Ryan Palo

These examples are really, really good.

Collapse
omarioabreu profile image
Mário Abreu

Interesting article! 👏

Collapse
rootdown001 profile image
Lance A.

I think this is a great article...solves a lot of mysteries

Collapse
hohonsing profile image
Ho Hon Sing

Great post and salute to your adventurous spirit!

Collapse
peacefulseeker profile image
Alexey Vorobyov

Brilliant presentation of such a tricky material!

Collapse
aligoren profile image
Ali GOREN

Amazing!

Thanks for this great post.

Collapse
sbu_05 profile image
CoolCodekid

I had a good laugh at this 😄😂 . Thanks for that! Keep up the good stuff

Collapse
sergix profile image
Peyton McGinnis

Creative article! A common misconception many of us neglect. Well written!

Collapse
rhymes profile image
rhymes

This post is AMAZING! Thanks Bastien, I learned so much :-D

Human translation : there is something behind the canvas.

AHHAHAHA

Collapse
myleftshoe profile image
myleftshoe

Funny, all the way down to the bottom

Collapse
russellabraham profile image
Russell

Thanks. I suspect this has something to do with toggling a dom node into full screen or off screen without a bg color.