22

When you style the background of the body element, why does the styling affect the entire screen and not just the body element itself? Let's say I create the following rule:

body {
  width: 700px;
  height:200px;
  border: 5px dotted red;
  background-color: blue;
}

I find that the border shows up as 700px wide as I would expect, but the background color occupies the entire browser viewport. Why?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
yroc
  • 886
  • 1
  • 10
  • 16

7 Answers7

18

Quote from http://www.w3.org/TR/CSS21/colors.html

The background of the root element becomes the background of the canvas and covers the entire canvas, anchored (for 'background-position') at the same point as it would be if it was painted only for the root element itself. The root element does not paint this background again.

The body element is the root-element, and thus, as required by the CSS rules it loses its background style and the background style is applied to the containing canvas (the webpage area in the browser), therefor the entire screen is blue. The other properties stay with the element (e.g. the border).

Dribbel
  • 2,060
  • 2
  • 17
  • 29
  • +1 for actually citing the reason why -- because the W3 said it shall be so! :-) – Sean Vieira Mar 07 '11 at 21:15
  • 11
    `html` is the root element. – melhosseiny Mar 07 '11 at 21:19
  • 1
    Read on in the specs :) If no background is set for the html element, the values for the first body must be used. I did omit that for clarity. Compare http://jsfiddle.net/2aN7D/ and http://jsfiddle.net/7AvqZ/ – Dribbel Mar 07 '11 at 21:26
  • It would be simpler if body and html were simply forced to contain the canvas, or were, in fact, the canvas. I could finally use `width: 100%;` on a child of ``. [sigh] – Hawken Jul 04 '12 at 17:51
  • @Hawken: Unfortunately, it's not that simple. The root element needs to generate a box for all other elements including head (even though it's typically not displayed) and body. And for the root element to generate a box, there needs to be an initial containing block for this box to live in. Having special CSS box generation rules for HTML would actually complicate matters. – BoltClock Apr 10 '15 at 19:29
  • @BoltClock I am not quite sure I understand; I think it would be better if `body` **was** the root element; such that only `body` and its descendants would be passed to the renderer. – Hawken Apr 24 '15 at 11:43
  • @Hawken: I think that would require maintaining two separate DOMs in memory: one with html as the root element and head/body children, and one with body, detached from html, as the root element, for rendering purposes. Not sure what sort of complications that would have, particularly in DOM scripting and selectors - the `:root` pseudo for one would match completely different elements depending on context. – BoltClock Apr 24 '15 at 11:45
  • 1
    "The body element is the root-element" — As melhosseiny points out, it is not, but the paragraph after the one you quoted in the spec explains the special casing that is applied to the body element. – Quentin Sep 27 '18 at 08:48
  • 1
    overflow property of body is also back propagated to the html element. – mustafa kemal tuna May 31 '20 at 10:54
11

From CSS: The Definitive Guide by Eric Meyer

In CSS values are never propagated upward; that is, an element never passes values up to its ancestors. There is an exception to the upward propagation rule in HTML: background styles applied to the body element can be passed to the html element, which is the document's root element and therefore defines its canvas.

So when you add the background-color: blue; declaration to the body element, this value is propagated to the html element (which is also the root element). Add this declartion to see it for yourself.

html {
    background-color: grey;
}
melhosseiny
  • 9,992
  • 6
  • 31
  • 48
  • 1
    Yes, you and Dribbel nailed it. Upward propagation ("inheritance"?) from body to html due to not specifying the html background. Didn't even know you could specify the background of html! Thanks. – yroc Mar 07 '11 at 21:38
1

When you set the background color of <body>, the browser interprets this as the background color for the entire window, even if you've forced the <body> to be smaller with CSS. Otherwise, what color would the outside of the <body> tag be?

Jake
  • 4,829
  • 2
  • 33
  • 44
-1

This is why it's a good idea to use containers. Such as:

<body>
    <div id="container">

    </div>
</body>

Example here: http://jsfiddle.net/Shaz/2FqqV/

Shaz
  • 15,637
  • 3
  • 41
  • 59
-2

You cannot set a width on the <body> element itself, that's why the entire screen appears to be blue versus just a 700px area.

dmackerman
  • 2,938
  • 5
  • 26
  • 43
-2

It must set the entire background, because you cannot define parts of the page that are "not" the body.

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
-2

One of those mysteries of CSS, I guess.

A better idea is to place your content inside of a <div> element and style that instead of trying to style the whole <body> tag.

mellamokb
  • 56,094
  • 12
  • 110
  • 136
  • I wasn't the downvoter, but probably because you didn't answer the question of /why/ the behavior takes place. – Jake Mar 07 '11 at 21:14
  • ya sorry you didn't even remotely address the question of the poster. – jonezy Mar 07 '11 at 21:15
  • Lol. I provided a **solution** instead of an answer. I guess I'm too practical and real-world :s. – mellamokb Mar 07 '11 at 21:16
  • I'm not sure if it is better, just different. http://csswizardry.com/2011/01/using-the-body-element-as-a-wrapper/ – Lime Mar 07 '11 at 21:23
  • @Lime: Well, for one, the CSS posted by OP would work correctly on a container div... – mellamokb Mar 07 '11 at 21:31